RIFF file format
RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构。RIFF文件所包含的数据类型由该文件的扩展名来标识,能以RIFF格式存储的数据有:
音频视频交错格式数据 .AVI波形格式数据 .WAV位图数据格式 .RDIMIDI格式数据 .RMI调色板格式 .PAL多媒体电影 .RMN动画光标 .ANI其他的RIFF文件 .BNDCHUNK
chunk是RIFF文件的基本单元,其基本结构如下:
struct chunk{uint32_t id; // 块标志uint32_t size; // 块大小uint8_t data[size]; // 块数据};id 4字节,用以标识块中所包含的数据。如:RIFF,LIST,fmt,data,WAV,AVI等,由于这种文件结构 最初是由Microsoft和IBM为PC机所定义,RIFF文件是按照小端 little-endian字节顺序写入的。size 块大小 存储在data域中的数据长度,不包含id和size的大小data 包含数据,数据以字为单位存放,如果数据长度为奇数(字节为单位),则最后添加一个空字节。chunk是可以嵌套的,但是只有块标志为RIFF或者LIST的chunk才能包含其他的chunk。
RIFF chunk
标志为RIFF的chunk是比较特殊的,每一个RIFF文件首先存放的必须是一个RIFF chunk,并且只能有这一个标志为RIFF的chunk。RIFF的数据域的起始位置是一个4字节码(FOURCC),用于标识其数据域中chunk的数据类型;紧接着数据域的内容则是包含的subchunk,如下图
align
数据块对齐单位,一次采样的大小,值为声道数 * 量化位数 / 8,在播放时需要一次处理多个该值大小的字节数据。
bits_per_sample
音频sample的量化位数,有16位,24位和32位等。
cbSize
扩展区的长度
扩展块内容
22字节,具体介绍,后面补充。
FOURCC 值为'd' 'a' 't' 'a'
size数据域的长度
data具体的音频数据存放在这里
采用压缩编码的WAV文件,必须要有Fact chunk,该块中只有一个数据,为每个声道的采样总数。
Format chunk 中的编码方式
在Format chunk中,除了有音频的数据的采样率、声道等音频的属性外,另一个比较主要的字段就是format_tag,该字段表示音频数据是以何种方式编码存放的。其具体的取值可以为以下:
0x0001WAVE_FORMAT_PCM,采用PCM格式
0x0003WAVE_FORMAT_IEEE_FLOAT,存放的值为IEEE float,范围为[-1.0f,1.0f]
0x0006WAVE_FORMAT_ALAW , 8bit ITU-T G.711 A-law
0x0007WAVE_FORMAT_MULAW,8bit ITU-T G.711 μ-law
0XFFFEWAVE_FORMAT_EXTENSIBLE,具体的编码方式有扩展区的 sub_format字段决定
关于扩展格式块
当WAV文件使用的不是PCM编码方式是,就需要扩展格式块,它是在基本的Format chunk又添加一段数据。该数据的前两个字节,表示的扩展块的长度。紧接其后的是扩展的数据区,含有扩展的格式信息,其具体的长度取决于压缩编码的类型。当某种编码方式(如 ITU G.711 a-law)使扩展区的长度为0,扩展区的长度字段还必须保留,只是其值设置为0。
扩展区的各个字节的含义如下:
size 2字节
扩展区的数据长度 ,可以为0或22
有效的采样位数,最大值为采样字节数 * 8。可以使用更灵活的量化位数,通常音频sample的量化位数为8的倍数,但是使用了WAVE_FORMAT_EXTENSIBLE时,量化的位数有扩展区中的valid bits per sample来描述,可以小于Format chunk中制定的bits per sample。
channle mask 4字节声道掩码
sub format 16字节GUID,include the data format code,数据格式码。
在Format chunk中的format_tag设置为0xFFFE时,表示使用扩展区中的sub_format来决定音频的数据的编码方式。在以下几种情况下必须要使用WAVE_FORMAT_EXTENSIBLE
PCM数据的量化位数大于16音频的采样声道大于2实际的量化位数不是8的倍数存储顺序和播放顺序不一致,需要指定从声道顺序到声卡播放顺序的映射情况。Data chunk
Data块中存放的是音频的采样数据。每个sample按照采样的时间顺序写入,对于使用多个字节的sample,使用小端模式存放(低位字节存放在低地址,高位字节存放在高地址)。对于多声道的sample采用交叉存放的方式。例如:立体双声道的sample存储顺序为:声道1的第一个sample,声道2的第一个sample;声道1的第二个sample,声道2的第二个sample;依次类推....。对于PCM数据,有以下两种的存储方式:
单声道,量化位数为8,使用偏移二进制码除上面之外的,使用补码方式存储。总结
本文主要介绍了RIFF文件的格式和WAV音频文件格式,为后面实现对WAVE文件的读写打一个理论基础。后面打算使用C++标准库,实现对WAV文件的读写。










