阡陌 发表于 2023-12-25 23:56:02

WAV 文件格式简介



WAV 为微软公司(Microsoft)开发的一种音频文件格式,它符合 RIFF(Resource Interchange File Format)文件规范,用于保存 Windows 平台的音频信息资源,被 Windows 平台及其应用程序所广泛支持,该格式也支持 MSADPCM,CCITT A LAW 等多种压缩运算法,支持多种音频数字,取样频率和声道,标准格式化的 WAV 文件和 CD 格式一样,也是 44.1K 的取样频率,16 位量化数字,因此在声音文件质量和 CD 相差无几。WAV 格式的音乐通常使用三个参数来表示声音,量化位数,取样频率和声道数。

WAV 文件采用的是 RIFF 格式结构。至少是由 3 个块构成,分别是 RIFF、fmt 和 data。所有基于压缩编码的 WAV 文件必须含有 fact 块。此外所有其它块都是可选的。块 fmt、Data 及 fact 均为 RIFF 块的子块。WAV 文件的文件格式类型标识符为 `WAVE`。

构成 RIFF 文件的基本单位称之为块(chunk)。每个 RIFF 文档是由若干个块构成。每个块(chunk)由块标识、块长度及数据等三部分所组成。块标识保存的是由 4 个 ASCII 码字符组成的块名字。如不满 4 个字符则在右边以空格充填。块长度字段占 4 个字节,保存的是当前块数据的长度,不包括块标识和块长度字段。所以一个块的实际长度为块长度字段内的数值加 8。RIFF 格式规定,只有 RIFF 及 LIST 块可以含有子块,其它的块不允许包含子块。一个 RIFF 格式文档本身就是一个块。其前 4 个字节为文档标识 `RIFF`,同时也是 RIFF 的块标识,标明该文档是一个有效的 RIFF 文档;第二部分为文件的数据长度,占 4 个字节,其数值为文件长度 `-8`;第三部分为 RIFF 块数据,前 4 个字节为文件格式类型标识,如:`WAVE`、`AVI` 等,后面其它部分为 RIFF 块的子块。


!(https://file.mculoop.com/images/2022/12/09/202212091052111.jpg)



```c
//WAV的数值均为小端模式
typedef struct WavRiff {
    char id;                     //"RIFF"
    uint32_t size;                  //块长度,从下一个字段(format)首地址开始到文件末尾的总字节数,该字段的数值加 8 为文件的总长度
    char format;               //文件格式类型:"WAVE"
} wav_riff_t;


typedef struct WavFmt {
    char id;                     //格式子块标识"fmt "
    uint32_t size;                  //格式子块长度,其数值不确定,取决于编码格式,可以是 16、 18 、20、40 等,从下个字段到格式子块结束的字节数
    uint16_t format;                //编码格式代码,常见的 WAV 文件使用 PCM 脉冲编码调制格式,PCM = 1
    uint16_t channels;            //通道数,单声道为1,双声道为2
    uint32_t sample_rate;         //采样频率,单位Hz
    uint32_t data_rate;             //数据传输率 声道数×采样频率×每样本的数据位数/8,播放软件利用此值可以估计缓冲区的大小
    uint16_t block_align;         //块对齐字节数 = 声道数×位数/8,播放软件需要一次处理多个该值大小的字节数据,用该数值调整缓冲区
    uint16_t bps;                   //bits per sample采样位数,存储每个采样值所用的二进制数位数。常见的位数有 4、8、12、16、24、32
} wav_fmt_t;


typedef struct WavData {
    char id;   //"data"
    uint32_t size; //data size,从下个字段到格式子块结束的字节数
} wav_data_t;


typedef struct WavHeader {
   wav_riff_t riff;
   wav_fmt_t fmt;
   wav_data_t data;
} wav_header_t;

```



常见的压缩编码格式:

| 格式代码       | 格式名称               | fmt 块长度 | fact 块 |
| -------------- | ---------------------- | ---------- | ------- |
| 1(0x0001)      | PCM/非压缩格式         | 16         |         |
| 2(0x0002       | Microsoft ADPCM      | 18         | √       |
| 3(0x0003)      | IEEE float             | 18         | √       |
| 6(0x0006)      | ITU G.711 a-law      | 18         | √       |
| 7(0x0007)      | ITU G.711 μ-law      | 18         | √       |
| 49(0x0031)   | GSM 6.10               | 20         | √       |
| 64(0x0040)   | ITU G.721 ADPCM      |            | √       |
| 65,534(0xFFFE) | 见子格式块中的编码格式 | 40         |         |

当 WAV 文件采用非 PCM 编码时,使用的是扩展格式块,它是在基本格式块 fmt 之后扩充了一个的数据结构。该结构的前两字节为长度字段,指出后面区域的长度。紧接其后的区域称之为扩展区,含有扩充的格式信息,其长度取决于压缩编码类型。当某种编码格式(如 ITU G.711 a-law)使扩展区的长度为 0 时,长度字段还必须保留,只是长度字段的数值为 0。因此,扩展格式块长度的最小值为基本格式块的长度 16 加 2。




页: [1]
查看完整版本: WAV 文件格式简介