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 块的子块。
//WAV的数值均为小端模式
typedef struct WavRiff {
char id[4]; //"RIFF"
uint32_t size; //块长度,从下一个字段(format)首地址开始到文件末尾的总字节数,该字段的数值加 8 为文件的总长度
char format[4]; //文件格式类型:"WAVE"
} wav_riff_t;
typedef struct WavFmt {
char id[4]; //格式子块标识"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[4]; //"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。
|