wav音频文件一般为PCM音频原始数据(很少有其他编码格式加wav头组成,如G711)加一个大小为44字节的wav文件头组成。
wav头具体组成见测试代码的wavhead_s结构体,在wav_head_parsing函数中解析并说明了44个字节代表的含义。
测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define WAV_HEAD_LEN 44
struct wavhead_s
{
char RIFF_BUF[4];
int wavFileLen;
char WAVEfmt_BUF[8];
int fmtLen;
short code;
short channels;
int sampleRate;
int bytePerSecond;
short doubleBitsPerSample;
short singleBitsPerSample;
char DATA_BUF[4];
int audioDataLen;
};
void wav_head_parsing(char *wav_head,struct wavhead_s *a)
{
if(NULL == wav_head || NULL == a)
{
printf("%s %d parameter NULL\n",__FUNCTION__,__LINE__);
return;
}
//wav文件头四个字节为固定格式:RIFF 表示这是一个WAVE文件头
a->RIFF_BUF[0] = wav_head[0];//'R'
a->RIFF_BUF[1] = wav_head[1];//'I'
a->RIFF_BUF[2] = wav_head[2];//'F'
a->RIFF_BUF[3] = wav_head[3];//'F'
printf("RIFF_BUF = %c%c%c%c \n",a->RIFF_BUF[0],a->RIFF_BUF[1],a->RIFF_BUF[2],a->RIFF_BUF[3]);
//wav文件总长度 不包含RIFF和自身 wavFileLen = 文件总长度 - 8
a->wavFileLen |= ((wav_head[4] & 0xFF) << 0);
a->wavFileLen |= ((wav_head[5] & 0xFF) << 8);
a->wavFileLen |= ((wav_head[6] & 0xFF) << 16);
a->wavFileLen |= ((wav_head[7] & 0xFF) << 24);
printf("wavFileLen = %d\n",a->wavFileLen);
//固定格式:WAVEfmt 表示后面开始是音频格式
a->WAVEfmt_BUF[0] = wav_head[8];//'W'
a->WAVEfmt_BUF[1] = wav_head[9];//'A'
a->WAVEfmt_BUF[2] = wav_head[10];//'V'
a->WAVEfmt_BUF[3] = wav_head[11];//'E'
a->WAVEfmt_BUF[4] = wav_head[12];//'f'
a->WAVEfmt_BUF[5] = wav_head[13];//'m'
a->WAVEfmt_BUF[6] = wav_head[14];//'t'
a->WAVEfmt_BUF[7] = wav_head[15];//''
printf("WAVEfmt_BUF = %c%c%c%c%c%c%c%c \n",a->WAVEfmt_BUF[0],a->WAVEfmt_BUF[1],a->WAVEfmt_BUF[2],a->WAVEfmt_BUF[3],a->WAVEfmt_BUF[4],a->WAVEfmt_BUF[5],a->WAVEfmt_BUF[6],a->WAVEfmt_BUF[7]);
//wav文件fmt格式块长度
//一般为16 表示是PCM数据 不需要解码
//G711A G711U为18
a->fmtLen |= ((wav_head[16] & 0xFF) << 0);
a->fmtLen |= ((wav_head[17] & 0xFF) << 8);
a->fmtLen |= ((wav_head[18] & 0xFF) << 16);
a->fmtLen |= ((wav_head[19] & 0xFF) << 24);
printf("fmtLen = %d\n",a->fmtLen);
//wav文件音频数据的编码格式
//1:PCM 6:G711A 7:G711U 一般为1
a->code |= ((wav_head[20] & 0xFF) << 0);
a->code |= ((wav_head[21] & 0xFF) << 8);
printf("code = %d\n",a->code);
//声道数 1:单声道 2:双声道
a->channels |= ((wav_head[22] & 0xFF) << 0);
a->channels |= ((wav_head[23] & 0xFF) << 8);
printf("channels = %d\n",a->channels);
//采样率 例如:8000 16000 44100
a->sampleRate |= ((wav_head[24] & 0xFF) << 0);
a->sampleRate |= ((wav_head[25] & 0xFF) << 8);
a->sampleRate |= ((wav_head[26] & 0xFF) << 16);
a->sampleRate |= ((wav_head[27] & 0xFF) << 24);
printf("sampleRate = %d\n",a->sampleRate);
//音频每秒钟的数据量=采样率*声道数*采样位数/8
a->bytePerSecond |= ((wav_head[28] & 0xFF) << 0);
a->bytePerSecond |= ((wav_head[29] & 0xFF) << 8);
a->bytePerSecond |= ((wav_head[30] & 0xFF) << 16);
a->bytePerSecond |= ((wav_head[31] & 0xFF) << 24);
printf("bytePerSecond = %d\n",a->bytePerSecond);
//每次采样的大小=采样位数*声道数/8
//播放器根据此值一次处理最小单位 单位为字节
a->doubleBitsPerSample |= ((wav_head[32] & 0xFF) << 0);
a->doubleBitsPerSample |= ((wav_head[33] & 0xFF) << 8);
printf("doubleBitsPerSample = %d\n",a->doubleBitsPerSample);
//单个声道每次采样的大小=采样位数
//播放器根据此值一次处理最小单位 单位为位
a->singleBitsPerSample |= ((wav_head[34] & 0xFF) << 0);
a->singleBitsPerSample |= ((wav_head[35] & 0xFF) << 8);
printf("singleBitsPerSample = %d\n",a->singleBitsPerSample);
//固定字段 data
a->DATA_BUF[0] = wav_head[36];//'d'
a->DATA_BUF[1] = wav_head[37];//'a'
a->DATA_BUF[2] = wav_head[38];//'t'
a->DATA_BUF[3] = wav_head[39];//'a'
printf("DATA_BUF = %c%c%c%c \n",a->DATA_BUF[0],a->DATA_BUF[1],a->DATA_BUF[2],a->DATA_BUF[3]);
//音频数据的长度=文件总长度 - 44(wav头长度)
a->audioDataLen |= ((wav_head[40] & 0xFF) << 0);
a->audioDataLen |= ((wav_head[41] & 0xFF) << 8);
a->audioDataLen |= ((wav_head[42] & 0xFF) << 16);
a->audioDataLen |= ((wav_head[43] & 0xFF) << 24);
printf("audioDataLen = %d\n",a->audioDataLen);
}
int main(int argc,char **argv)
{
char wav_head[WAV_HEAD_LEN] = {0};
struct wavhead_s wav_test;
FILE *wavfp = fopen(argv[1],"r");
if(NULL == wavfp)
{
printf("fopen %s fail! err!!!\n",argv[1]);
return -1;
}
fread(wav_head,sizeof(wav_head),1,wavfp);
wav_head_parsing(wav_head,&wav_test);
fclose(wavfp);
return 0;
}
随便找了一个wav文件的测试结果: