WAVE文件结构之疑问及对策

时间:2021-10-10 02:11:41

《Windows程序设计》及网络上其他资料都定义WAVE格式类似如下:
WAVE文件结构之疑问及对策

但实际打开.wav文件如下:
WAVE文件结构之疑问及对策

第一,0010处定义的格式块的大小,按照说明值应为16,即0x10,但实际上我打开好几个文件都是0x12。
第二,wf.wBitsPerSample在各资料中都定义为2字节,但实际文件中其后还跟了2个字节的空白,推断是把该字段定义为了4字节。
(更新:后来我发现以上两条猜测不正确。暂时没有研究这个问题了,有空再更正,读者请自行查证,仅保证下文的对策能够生效。)

对策:
按照实际文件定义struct。

    #pragma pack(2)
struct WaveFileHead
{
char type[4];//4
DWORD filesize;//4
char WAVEfmt[8];//8
DWORD formatsize;//4
WORD wFormatTag;//2
WORD nChannels;//2
DWORD nSamplesPerSec;//4
DWORD nAvgBytesPerSec;//4
WORD nBlockAlign;//2
DWORD wBitsPerSample;//4
char data[4];//4
DWORD size;//4
} wavefilehead;//46

void FillWaveFileHead()
{
strcpy(wavefilehead.type,"RIFF");
wavefilehead.filesize=46-sizeof(DWORD)+out_buffer_size*precision/8;
strcpy(wavefilehead.WAVEfmt,"WAVEfmt ");
wavefilehead.formatsize=0x12;
wavefilehead.wFormatTag=WAVE_FORMAT_PCM;
wavefilehead.nChannels=channel;
wavefilehead.nSamplesPerSec=rate;
wavefilehead.nAvgBytesPerSec=channel*rate*precision/8;
wavefilehead.nBlockAlign=channel*precision/8;
wavefilehead.wBitsPerSample=channel*precision;
strcpy(wavefilehead.data,"data");
wavefilehead.size=out_buffer_size*precision/8;
}

实践中发现该struct在内存中对齐为4字节,本该总size为46字节,但实际上有48字节。所以用#pragma pack(2)强制2字节对齐。

head后跟一段正弦数据,写入文件后,结果如下:
WAVE文件结构之疑问及对策

参考文献
1. c/c++ struct内存对齐 http://duanple.blog.163.com/blog/static/70971767200962512238583/
2. WAVE 文件格式分析http://www.cnblogs.com/liyiwen/archive/2010/04/19/1715715.html