wav 文件头解析

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>

//wave文件头  
typedef struct WaveHeader  
{  
    unsigned char riff[4];             //资源交换文件标志  
    unsigned long size;               //从下个地址开始到文件结尾的字节数  
    unsigned char wave_flag[4];        //wave文件标识  
    unsigned char fmt[4];              //波形格式标识  
    unsigned long fmt_len;            //过滤字节(一般为00000010H)  
    unsigned short tag;                //格式种类,值为1时,表示PCM线性编码  
    unsigned short channels;           //通道数,单声道为1,双声道为2  
    unsigned long samp_freq;          //采样频率  
    unsigned long byte_rate;          //数据传输率 (每秒字节=采样频率×每个样本字节数)  
    unsigned short block_align;        //块对齐字节数 = channles * bit_samp / 8  
    unsigned short bit_samp;           //bits per sample (又称量化位数)  
} wave_header_t;  
  
typedef struct WaveStruct  
{  
    wave_header_t header;      //header  
    unsigned char data_flag[4];        //数据标识符  
    unsigned long length;             //采样数据总数  
    unsigned long *pData;             //data  
} wave_t;

void WaveOpen(FILE* fp, wave_t* wave)  
{  
    int read_bytes = 0;  
  
    /* read heade information */  
	read_bytes = fread(wave->header.riff, 1, sizeof(wave->header.riff), fp);
	assert(read_bytes == sizeof(wave->header.riff));
	
	read_bytes = fread(&wave->header.size, 1, sizeof(wave->header.size), fp);
	assert(read_bytes == sizeof(wave->header.size));
	
	read_bytes = fread(wave->header.wave_flag, 1, sizeof(wave->header.wave_flag), fp);
	assert(read_bytes == sizeof(wave->header.wave_flag));
	
	read_bytes = fread(wave->header.fmt, 1, sizeof(wave->header.fmt), fp);
	assert(read_bytes == sizeof(wave->header.fmt));
	
	read_bytes = fread(&wave->header.fmt_len, 1, sizeof(wave->header.fmt_len), fp);
	assert(read_bytes == sizeof(wave->header.fmt_len));	
	
	read_bytes = fread(&wave->header.tag, 1, sizeof(wave->header.tag), fp);
	assert(read_bytes == sizeof(wave->header.tag));

	read_bytes = fread(&wave->header.channels, 1, sizeof(wave->header.channels), fp);
	assert(read_bytes == sizeof(wave->header.channels));	
	
	read_bytes = fread(&wave->header.samp_freq, 1, sizeof(wave->header.samp_freq), fp);
	assert(read_bytes == sizeof(wave->header.samp_freq));	
	
	read_bytes = fread(&wave->header.byte_rate, 1, sizeof(wave->header.byte_rate), fp);
	assert(read_bytes == sizeof(wave->header.byte_rate));	

	read_bytes = fread(&wave->header.block_align, 1, sizeof(wave->header.block_align), fp);
	assert(read_bytes == sizeof(wave->header.block_align));	
	
	read_bytes = fread(&wave->header.bit_samp, 1, sizeof(wave->header.bit_samp), fp);
	assert(read_bytes == sizeof(wave->header.bit_samp));
	
	/* jump to "data" for reading data */ 
	unsigned char temp = 0;  	
    do  
    {  
		read_bytes = fread(&temp, 1, sizeof(temp), fp);
		assert(read_bytes == sizeof(temp));
    }  
    while('d' != temp); 
	
    wave->data_flag[0] = temp;  
	read_bytes = fread(&wave->data_flag[1], 1, sizeof(wave->data_flag)-1, fp);
	assert(read_bytes == (sizeof(wave->data_flag)-1));
	
	read_bytes = fread(&wave->length, 1, sizeof(wave->length), fp);
	assert(read_bytes == sizeof(wave->length));	
  
    /* jduge data chunk flag */  
    if(strncmp((const char*)wave->data_flag, "data", 4))  
    {  
        printf("error : cannot read data!\n");  
        return;  
    }  
	
	const char *channel_mappings[] = {NULL,"mono","stereo"};   
    unsigned long total_time = wave->length / wave->header.byte_rate;  
    unsigned char hour = (unsigned char)(total_time / 3600);  
    unsigned char minute = (unsigned char)((total_time / 60) % 60);  
    unsigned char second = (unsigned char)(total_time % 60);
	
    /* printf file header information */  
    printf("%s %ldHz %dbit, DataLen: %ld, Rate: %ld, Length: %02d:%02d:%02d\n",  
           channel_mappings[wave->header.channels],             //声道  
           wave->header.samp_freq,                              //采样频率  
           wave->header.bit_samp,                               //每个采样点的量化位数  
           wave->length,  
           wave->header.byte_rate,  
           hour, minute, second);  
  
}  

int write_head(FILE* fp, wave_t* wav)
{
	int bytes = fwrite(&wav->header, 1, sizeof(wav->header), fp);
	assert(bytes == sizeof(wav->header));
	
	bytes = fwrite(wav->data_flag, 1, sizeof(wav->data_flag), fp);
	assert(bytes == sizeof(wav->data_flag));
	
	bytes = fwrite(&wav->length, 1, sizeof(wav->length), fp);
	assert(bytes == sizeof(wav->length));
	
	return 0;
} 

 
int main(int argc, char** argv)
{	
	if (argc != 3)
	{
		printf("Usage: \n");
		return 0;
	}
	
	int i = 1;
	FILE* src = fopen(argv[i], "rb");
	if (!src)
	{
		printf("failed to open[%s]: %s\n", argv[i], strerror(errno));
		return -1;
	}
	i++;
	
	FILE* dst = fopen(argv[i], "w+");
	if (!dst)
	{
		printf("failed to open[%s]: %s\n", argv[i], strerror(errno));
		return -1;
	}
	
	wave_t wave;
	memset(&wave, 0, sizeof(wave));
	
	WaveOpen(src, &wave);
	write_head(dst, &wave);
	
	char buf[1024];
	while(!feof(src))
	{
		memset(buf, 0, sizeof(buf));
		int n = fread(buf, 1, sizeof(buf), src);
		if (n > 0)
		{
			int bytes = fwrite(buf, 1, n, dst);
			assert(n == bytes);
		}
	}
	
	fclose(src);
	fclose(dst);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值