本文从定义、格式、特点等三个方面对WAV文件进行了简单地描述。
WAV的定义
波形音频文件格式(WAVE,通常被称为WAV),是Microsoft和IBM(International Business Machines Corporation,国际商业机器公司) 的一种音频文件格式标准,用于在PC上存储音频比特流。它是资源交换文件格式(RIFF)的实例应用,很接近Amiga和Macintosh计算机上使用的8SVX和AIFF格式。它是Windows系统上用于原始和典型的未压缩音频的主要格式。通常使用的比特流编码是线性脉码调制(LPCM)格式。 —— [ 维基百科 ]
WAV用三个参数来表示声音,即量化位数、取样频率和声道数。其中,采样频率一般有11025Hz(11kHz)、22050Hz(22kHz)和44100Hz(44kHz)三种,而其WAV文件所占容量=(采样频率×采样位数×声道)×时间/8(1字节=8bit)。
了解WAV文件的基本构成,首先要明确LPCM和RIFF的定义和特点。
LPCM
PCM(Pulse-code modulation,脉冲编码调制),就是把一个时间连续、取值连续的模拟信号通过取样、量化、编码,变换成时间离散、取值离散的数字信号,然后在信道中传输。PCM中的声音数据没有被压缩,如果是单声道的文件,采样数据按时间的先后顺序依次存入。
LPCM(Linear pulse-code modulation,线性脉冲编码调制),是一种非压缩音频数字化技术。与PCM原理相同,但二者的采样频率和量化精度不同,LPCM码率和体积较大。
RIFF
RIFF(Resource Interchange File Format,资源交换文件格式),是一种通用的文件容器格式(container format),在标记中将数据存储在“块”(chunks)中。微软的AVI、ANI和WAV等容器格式的实现,都是以RIFF为基础。 —— [ 维基百科 ]
RIFF文件由“块”组成,所有块都具有以下格式:
-
chunks
- 4字节:由4个ASCII字符组成,用以识别块中所包含的数据,即块标识符。如:’RIFF’,’LIST’等。
- 4字节:无符号的小端32位整数,定义存储在data域中数据的长度,即块大小。(除此字段本身和块标识符以外)
- 可变大小的字段:存放块内容。所包含的数据是以字(WORD)为单位排列的,如果该数据结构长度是奇数,则在最后添加一个空(NULL)字节。
- 一个pad字节:如果块长度不均匀时使用。 lists:一个chunk的子集
- 4字节:由4个ASCII字符组成,包含关键字“LIST”。
- 4字节:无符号的小端32位整数,表示该LIST的大小。
- 可变大小的字段:存放数据。
WAV的格式
①WAV文件的高级定义是:
<WAVE-form> → RIFF('WAVE' //ID
<fmt-ck> // Format
[<fact-ck>] // Fact chunk
[<cue-ck>] // Cue points
[<playlist-ck>] // Playlist
[<assoc-data-list>] // Associated data list
<wave-data> ) // Wave data
该定义显示了在RIFF格式下WAV的表示方式:
项目 | 具体内容 |
---|---|
格式辨识码ID | ‘WAVE’ |
格式块Format | 包含样本编码、每个通道的位数、通道数、采样率等信息 |
事实块Fact chunk | 可选字段,表示一些压缩编码方案的样本数 |
提示点Cue points | 识别波形文件中的一些重要样本号 |
播放列表Playlist | 允许样本按顺序播放或重复播放 |
相关数据列表Associated data list | 允许将标签和注释附加到提示点 |
强制性波形数据Wave data | 包含实际的样本(以指定的格式) |
②WAV文件主要分为文件头和数据块,由若干个Chunk组成的。按照在文件中的出现位置包括:RIFF WAVE Chunk, Format Chunk, Fact Chunk(可选), Data Chunk。具体如下图:
-------------------------------------------
| RIFF WAVE Chunk |
| ID = "RIFF" |
| RiffType = "WAVE" |
-------------------------------------------
| Format Chunk |
| ID = "fmt " |
-------------------------------------------
| Fact Chunk(optional) |
| ID = "fact" |
-------------------------------------------
| Data Chunk |
| ID = "data" |
-------------------------------------------
③WAV的基本结构 WAVEFORMATEX 定义如下:
typedef struct
{
WORD wFormatag; //编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
WORD nChannls; //声道数,单声道为1,双声道为2;
DWORD nSamplesPerSec; //采样频率;
DWORD nAvgBytesperSec; //每秒的数据量;
WORD nBlockAlign; //块对齐;
WORD wBitsPerSample; //WAVE文件的采样大小;
WORD cbSize; // The count in bytes of the size of extra
// information(after cbSize). PCM中忽略此值
} WAVEFORMATEX;
在非PCM格式的文件中,一般会在WAVEFORMAT结构后面加入一个 “fact” chunk, 结构如下:
typedef struct{
char[4]; //“fact”字符串
DWORD chunksize;
DWORD datafactsize; // 音频数据转换为PCM格式后的大小。
} factchunk;
④“data” chunk存储真正的声音数据,从第9个字节开始存储(前八个字节存储的是标志符 “data” 和后接数据大小size(DWORD)。Data Chunk头结构定义如下:
struct DATA_BLOCK
{
char szDataID[4]; // 'd','a','t','a'
DWORD dwDataSize;
};
Data Chunk中数据存放的形式如下图所示,根据声道数不同及取样位数的不同,得到不同的编码结果。
如果是单声道的文件,采样数据按时间的先后顺序依次存入。
如果是双声道的文件,采样数据按时间先后顺序交叉地存入。
由此可知,8bit和16bit样值的二进制编码表示不一样。
注意:编程时若要放入无声数据,首先需要判断声音格式是8位还是16位。无声是由中间数值来决定,Windows中将8位值的范围定为[0,255],16位值的范围定为[-32768,32767],即8位的时候为128为无声,l6位时0才是无声。
WAV的特点
①WAV音频格式的优点包括:简单的编/解码(几乎直接存储来自模/数转换器(ADC)的信号)、普遍的认同/支持以及无损耗存储。
②主要缺点是需要音频存储空间;另一个缺陷是在32位系统中被限制为2GB。WAV文件格式被限制小于4GiB,因为其使用32位无符号整数来记录文件头。
③由于WAV文件的采样率在1Hz至4.3GHz之间,并且通道数高达65535,所以还可用于非音频数据。
④现有的*.WAV”格式支持MSADPCM、CCITT A LAW等多种压缩算法,支持多种音频位数、采样频率和声道。
参考资料:
[1]https://en.wikipedia.org/wiki/WAV
[2]https://en.wikipedia.org/wiki/Resource_Interchange_File_Format
[3]http://www.cnblogs.com/cheney23reg/archive/2010/08/08/1795067.html
[4]http://blog.sina.com.cn/s/blog_4b8802730100nevs.html
[5]http://www.2cto.com/os/201312/267541.html