作者:slyzhang
多媒体技术近年来发展很快,较好品质的声卡可以提供16位的立体声及44KHZ的播放录制能力,它不仅可以提供原音逼真的取样,其合成的音质也十分理想,有的声卡还加入了数字信号处理器,可编程控制的DSP具有强大的运算能力,它可以用来作声音信息的压缩和一些特殊效果的处理。具有此功能的声卡提供的WAV文件提供的语音信息可以满足语音特征识别的要求。
1.1 RIFF文件和WAV文件格式
在Windows环境下,大部分的多媒体文件都依循着一种结构来存放信息,这种结构称为""资源互换文件格式""(Resources lnterchange File Format),简称RIFF。例如声音的WAV文件、视频的AV1文件等等均是由此结构衍生出来的。RIFF可以看做是一种树状结构,其基本构成单位为chunk,犹如树状结构中的节点,每个chunk由""辨别码""、""数据大小""及""数据""所组成。
辨别码由4个ASCII码所构成,数据大小则标示出紧跟其后数据的长度(单位为Byte),而数据大小本身也用掉4个Byte,所以事实上一个chunk的长度为数据大小加8。一般而言,chunk本身并不允许内部再包含chunk,但有两种例外,分别为以""RIFF""及""L1ST""为辨别码的chunk。而针对此两种chunk,RIFF又从原先的""数据""中切出4个Byte。 此4个Byte称为""格式辨别码"",然而RIFF又规定文件中仅能有一个以""RIFF""为辨别码的chunk。
只要依循此一结构的文件,我们均称之为RIFF档。此种结构提供了一种系统化的分类。如果和MS一DOS文件系统作比较,""RIFF""chunk就好比是一台硬盘的根目录,其格式辨别码便是此硬盘的逻辑代码(C:或D:),而""L1ST""chunk即为其下的子目录,其他的chunk则为一般的文件。至于在RIFF文件的处理方面,微软提供了相关的函数。视窗下的各种多媒体文件格式就如同在磁盘机下规定仅能放怎样的目录,而在该目录下仅能放何种数据。
WAV为WAVEFORM(波形)的缩写。声音文件的结构如图1所示,""RIFF""的格式辨别码为""WAVE""。整个文件由两个chunk所组成:辨别码""fmt""(注意,最后一个是空白字符!)及""data""。
在""fmt""的chunk下包含了一个PCMWAVEFORMAT数据结构,其定义如下:
typedef struct pcmwaveformat - tag {
WAVEFORMAT wf ;
WORD wBitsPerSample;
} PCMWAVEFORMAT;
typedef struct waveformat - tag {
WORD wFormatTag ;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesperSec;
WORD nBlockAlign;
} WAVEFORMAT;
其意义分别为:
wFormatTag:记录着此声音的格式代号,例如WAVE_FORMAT_PCM,WAVE_F0RAM_ADPCM等等。
nChannels:记录声音的频道数。
nSamp1esPerSec:记录每秒取样数。
nAvgBytesPerSec:记录每秒的数据量。
nBlockA1ign:记录区块的对齐单位。
>
> wBitsPerSample:记录每个取样所需的位元数。
>
> ""data""Chunk包含真正的声音数据。Window目前仅提供WAVE_FORMAT_PCM一种数据格式,所代表的意义是脉派编码调变(Pu1se Code Modulation)。针对此格式,Windows定义了在""data""的chunk中数据的存放情形,图2中列出了四种不同频道数及取样所需的位元数以及位元位置的安排。
>
> ""RIFF"" 频道0 频道0 频道0 频道0
>
> xxxx nChannels=1,wBitsPerSample=8
>
> ""WAVE"" 频0(左) 频道1(右) 频道0(左) 频道1 (右)
>
> ""fmt ""
>
> nChannels=2,wBitsPerSample=8
>
> sizeof(PCMWAVEFORMAT)
>
> struct of PCMWAVEFORMAT 频道0(低位) 频道0(高位) 频道0(低位)频道0(高位)
>
> ""data"" nChannels=1,wBitsPerSample=16
>
> xxxx 频道0(低位) 频道0(高位) 频道0(低位)频道0(高位)
>
> (低位) (高位) (低位) (高位)
>
> wave form data
>
> nChannels=2,wBitsPerSample=16
>
> 图1 WAV文件结构 图2 PCM文件中位元安排方式
>
> 第一排表示单声道8位元,第二排表示双声道8位元,第三排表示单声道16位元,第四排表示双声道16位元。8位元代表音量大小由8个位元所表示,16位元则代表音量大小由16个位元所表示。理论上8位元可以表示0~255,16位元可表示0~65536,不过windows却定16位元其值的范围从-32168~32167。此外尚有一点要注意的是,0并不一定代表无声,而是由中间的数值来决定,也就是在8位元时为128,16位元时为0才是无声。所以,若程序设计时需放入无声的数据,糯特别注意声音格式是16或是8位元,以放入适当的值。
>
> 1.2 WAV文件信息的具体应用
>
> WAV文件中包括了对原始声音的高速率采样,并且以WAVE_PCM_FORMAT脉派编码调变格式,我们可以在VISUAL C++程序中实现,在读出WAVEHDR文件头之后,下面就是原始声音的高速率采样信息,我们可以对它作多方面的信息处理。
>
> 1.2.1 波形显示。
>
> 我们可以以时域-幅度的方式显示出原始声音的波形,这是最简单同时也是最直接的信息处理方式。在时域范围内,我们可以观察该信号波形是否连续,中间是否有跳变等。
>
> 1.2.2频谱显示
>
> 我们可以以频域-幅度的方式显示出原始声音的频谱,在对原始信号经过FFT变换之后,可以得到该信号的频谱,进而得到该信号的能量集中带,分布特征,谱对称系数等等。
>
> 1.2.3 用于语音信号识别
>
> 讲话者的个体识别是语音信号处理的一个重要内容,但它的一个前提条件是必须提供语音信号的数字波形,通常的方法是将原始的语音信号进行放大、抗混叠滤波、A/D采样、数值编码,最终得到语音信号的数字波形,通常多采用硬件处理,费时费力,如果我们借助非常成熟的声卡技术,将WAV文件打开,就非常方便地得到语音信号的数字波形,为下一步进行语音信号识别提供良好的前端预处理。