WAV文件格式研究笔记
WAV文件格式是(WAV From format)的简写。WAV是指文件格式,而数据编码格式是多样的,目前微软提供的数据格式只有一种PCM -脉派编码调变(Pulse Code Modulation也就是最常见的无压缩WAV)。其他的数据格式有G.723.1、ACELP、CCITT A-Law、CCITT u-Law、TrueSpeed(TM)、GSM 6.10等,这些格式大多数是为电话或调制解调器等低速语音为主的设备而使用,它们一般采用比较窄的采样范围来产生比较大的压缩比,并没有统一标准。不在本文讨论范围。
·RIFF文件和WAV文件格式
在Windows环境下,大部分的多媒体文件都依循着一种结构来存放信息,这种结构称为"资源互换文件格式"(Resources lnterchange File Format),简称RIFF。例如声音的WAV文件、视频的AV1文件等等均是由此结构衍生出来的。RIFF可以看做是一种树状结构,其基本构成单位为chunk,犹如树状结构中的节点,每个chunk由"辨别码"、"数据大小"及"数据"所组成。
辨别码(ID)由4个ASCII码所构成,数据大小则标示出紧跟其后数据的长度(单位为Byte),而数据大小本身也用掉4个Byte,所以事实上一个chunk的长度为数据大小加8。一般而言,chunk本身并不允许内部再包含chunk,但有两种例外,分别为以"RIFF"及"LIST"为辨别码的chunk。而针对此两种chunk,RIFF又从原先的"数据"中切出4个Byte。 此4个Byte称为"格式辨别码",然而RIFF又规定文件中仅能有一个以"RIFF"为辨别码的chunk。
在Windows环境下,大部分的多媒体文件都依循着一种结构来存放信息,这种结构称为"资源互换文件格式"(Resources lnterchange File Format),简称RIFF。例如声音的WAV文件、视频的AV1文件等等均是由此结构衍生出来的。RIFF可以看做是一种树状结构,其基本构成单位为chunk,犹如树状结构中的节点,每个chunk由"辨别码"、"数据大小"及"数据"所组成。
辨别码(ID)由4个ASCII码所构成,数据大小则标示出紧跟其后数据的长度(单位为Byte),而数据大小本身也用掉4个Byte,所以事实上一个chunk的长度为数据大小加8。一般而言,chunk本身并不允许内部再包含chunk,但有两种例外,分别为以"RIFF"及"LIST"为辨别码的chunk。而针对此两种chunk,RIFF又从原先的"数据"中切出4个Byte。 此4个Byte称为"格式辨别码",然而RIFF又规定文件中仅能有一个以"RIFF"为辨别码的chunk。
·文件结构
WAV文件是chunk的集合,其中有两个chunk是不可缺少的,分别是“fmt”(format)和“data”chunk,fmt装载的是wav文件的各项参数,如采样率。data chunk装载的是音频数据。其他的chunk则是可选的。
所有音频应用程序必须能读取这两个主要的chunk,所有音频复制程序必须能复制所有chunk。
chunk在文件中的顺序是不受限制的,除了一条规则:fmt chunk必须在data chunk前面。
绝大部分人写程序的时候都以为fmt chunk必须放在文件的开头,紧跟riff标识。实际上这并不是必须的,因为微软白皮书没要求如此。但这样搞也没错。
下图显示一个简单的WAV文件结构
__________________________
| riff wave chunk |
| groupid = 'riff' |
| rifftype = 'wave' |
| __________________ |
| | format chunk | |
| | ckid = 'fmt ' | |
| |__________________| |
| __________________ |
| | sound data chunk | |
| | ckid = 'data' | |
| |__________________| |
|__________________________|
所有音频应用程序必须能读取这两个主要的chunk,所有音频复制程序必须能复制所有chunk。
chunk在文件中的顺序是不受限制的,除了一条规则:fmt chunk必须在data chunk前面。
绝大部分人写程序的时候都以为fmt chunk必须放在文件的开头,紧跟riff标识。实际上这并不是必须的,因为微软白皮书没要求如此。但这样搞也没错。
下图显示一个简单的WAV文件结构
__________________________
| riff wave chunk |
| groupid = 'riff' |
| rifftype = 'wave' |
| __________________ |
| | format chunk | |
| | ckid = 'fmt ' | |
| |__________________| |
| __________________ |
| | sound data chunk | |
| | ckid = 'data' | |
| |__________________| |
|__________________________|
·数据类型
所有数据存储在8bit字节中,按照intel 80x86 (ie, little endian)方式排列,多字节排列顺序如下。
7 6 5 4 3 2 1 0
+-----------------------+
char: | lsb msb |
+-----------------------+
+-----------------------+
char: | lsb msb |
+-----------------------+
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8
+-----------------------+-----------------------+
short: | lsb byte 0 | byte 1 msb |
+-----------------------+--
+-----------------------+-----------------------+
short: | lsb byte 0 | byte 1 msb |
+-----------------------+--