WAVE文件结构之疑问及对策

《Windows程序设计》及网络上其他资料都定义WAVE格式类似如下:
这里写图片描述

但实际打开.wav文件如下:
这里写图片描述

第一,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后跟一段正弦数据,写入文件后,结果如下:
这里写图片描述

参考文献
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

猜你喜欢

转载自blog.csdn.net/tomwillow/article/details/51866138