WAV格式符合RIFF文件规范,与AVI格式类似,不同之处在于,WAV格式要简单得很多,它只有一个WAVE结构体头需要填充,data项直接填充采样数据就可以了,不需要与AVI一样视频添加dc标签,音频添加wb标签。至于AVI和RIFF数据格式,可以查看我之前的博客。WAV数据分布如下图:
下面直接上代码main.cpp
#include "wave.h"
#define INPUT_NAME "2Channel_44100_16bit.pcm"
#define OUTPUT_NAME "output.wav"
FILE *Input_fp = NULL;
FILE *Output_fp = NULL;
int Wav_Init(void)
{
WAVPARA_S l_stWavPara;
l_stWavPara.bAenc = false;
l_stWavPara.u32Format = 1;
l_stWavPara.u32Channels = 2;
l_stWavPara.u32Rate = 44100;
l_stWavPara.u32Bits = 16;
l_stWavPara.u32Mp3rate = 0;
HstInitWavWriteStruct(l_stWavPara);
Input_fp = fopen(INPUT_NAME,"r+");
if(NULL==Input_fp)
{
printf("%s %d file open error \n",__FILE__,__LINE__);
return -1;
}
Output_fp = fopen(OUTPUT_NAME,"w+");
if(NULL==Output_fp)
{
printf("%s %d file open error \n",__FILE__,__LINE__);
return -1;
}
fseek(Output_fp,WAV_HEAD_SIZE,SEEK_SET);
return 0;
}
int Wav_ReadData(void)
{
unsigned int l_u32Ret = 0;
unsigned int l_u32Datalen = 0;
unsigned char *l_strTemp = NULL;
l_strTemp = (unsigned char *)malloc(1024);
if(NULL==l_strTemp)
{
printf("%s %d malloc error\n",__FILE__,__LINE__);
return -1;
}
while(0==feof(Input_fp))
{
l_u32Ret = fread(l_strTemp,1,1024,Input_fp);
if(0!=l_u32Ret)
{
l_u32Ret = fwrite(l_strTemp,1,l_u32Ret,Output_fp);
if(0!=l_u32Ret)
{
l_u32Datalen += l_u32Ret;
}
}
}
l_u32Ret = HstWavHeaderWrite(Output_fp, l_u32Datalen);
return 0;
}
int Wav_close(void)
{
if(NULL!=Input_fp)
{
fclose(Input_fp);
Input_fp = NULL;
}
if(NULL!=Output_fp)
{
fclose(Output_fp);
Output_fp = NULL;
}
return 0;
}
int main(void)
{
int res = 0;
res = Wav_Init();
if(0 == res)
{
Wav_ReadData();
}
Wav_close();
return 0;
}
代码的主要功能是将一个直接采样的pcm数据文件封装成WAV格式,工程全部代码如下:
biao@ubuntu:~/test/Wave_file$ tree
.
├── 2Channel_44100_16bit.pcm
├── main.cpp
├── Makefile
├── output.wav
├── wave.cpp
└── wave.h
0 directories, 6 files
biao@ubuntu:~/test/Wave_file$
完整的代码可以在这里下载:C语言WAV音频数据封装实例。