WAV文件格式分析详解.doc_第1页
WAV文件格式分析详解.doc_第2页
WAV文件格式分析详解.doc_第3页
WAV文件格式分析详解.doc_第4页
WAV文件格式分析详解.doc_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

WAV文件格式分析详解一、综述WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是“RIFF”。 WAVE文件是由若干个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 |- 图1 Wav格式包含Chunk示例 其中除了Fact Chunk外,其他三个Chunk是必须的。每个Chunk有各自的ID,位于Chunk最开始位置,作为标示,而且均为4个字节。并且紧跟在ID后面的是Chunk大小(去除ID和Size所占的字节数后剩下的其他字节数目),4个字节表示,低字节表示数值低位,高字节表示数值高位。下面具体介绍各个Chunk内容。PS: 所有数值表示均为低字节表示低位,高字节表示高位。二、具体介绍RIFF WAVE Chunk = | |所占字节数| 具体内容 | = | ID | 4 Bytes | RIFF | - | Size | 4 Bytes | | - | Type | 4 Bytes | WAVE | - 图2 RIFF WAVE Chunk 以FIFF作为标示,然后紧跟着为size字段,该size是整个wav文件大小减去ID和Size所占用的字节数,即FileLen - 8 = Size。然后是Type字段,为WAVE,表示是wav文件。 结构定义如下:struct RIFF_HEADER char szRiffID4; / R,I,F,F DWORD dwRiffSize; char szRiffFormat4; / W,A,V,E;Format Chunk = | | 字节数 | 具体内容 | = | ID | 4 Bytes | fmt | - | Size | 4 Bytes | 数值为16或18,18则最后又附加信息 | - - | FormatTag | 2 Bytes | 编码方式,一般为0x0001 | | - | | Channels | 2 Bytes | 声道数目,1-单声道;2-双声道 | | - | | SamplesPerSec | 4 Bytes | 采样频率 | | - | | AvgBytesPerSec| 4 Bytes | 每秒所需字节数 | |= WAVE_FORMAT - | | BlockAlign | 2 Bytes | 数据块对齐单位(每个采样需要的字节数) | | - | | BitsPerSample | 2 Bytes | 每个采样需要的bit数 | | - | | | 2 Bytes | 附加信息(可选,通过Size来判断有无) | | - - 图3 Format Chunk 以fmt 作为标示。一般情况下Size为16,此时最后附加信息没有;如果为18则最后多了2个字节的附加信息。主要由一些软件制成的wav格式中含有该2个字节的附加信息。 结构定义如下:struct WAVE_FORMAT WORD wFormatTag; WORD wChannels; DWORD dwSamplesPerSec; DWORD dwAvgBytesPerSec; WORD wBlockAlign; WORD wBitsPerSample;struct FMT_BLOCK char szFmtID4; / f,m,t, DWORD dwFmtSize; WAVE_FORMAT wavFormat;Fact Chunk = | |所占字节数| 具体内容 | = | ID | 4 Bytes | fact | - | Size | 4 Bytes | 数值为4 | - | data | 4 Bytes | | - 图4 Fact Chunk Fact Chunk是可选字段,一般当wav文件由某些软件转化而成,则包含该Chunk。 结构定义如下:struct FACT_BLOCK char szFactID4; / f,a,c,t DWORD dwFactSize;Data Chunk = | |所占字节数| 具体内容 | = | ID | 4 Bytes | data | - | Size | 4 Bytes | | - | data | | | - 图5 Data Chunk Data Chunk是真正保存wav数据的地方,以data作为该Chunk的标示。然后是数据的大小。紧接着就是wav数据。根据Format Chunk中的声道数以及采样bit数,wav数据的bit位置可以分成以下几种形式: - | 单声道 | 取样1 | 取样2 | 取样3 | 取样4 | | |- | 8bit量化 | 声道0 | 声道0 | 声道0 | 声道0 | - | 双声道 | 取样1 | 取样2 | | |- | 8bit量化 | 声道0(左) | 声道1(右) | 声道0(左) | 声道1(右) | - | | 取样1 | 取样2 | | 单声道 |- | 16bit量化 | 声道0 | 声道0 | 声道0 | 声道0 | | | (低位字节) | (高位字节) | (低位字节) | (高位字节) | - | | 取样1 | | 双声道 |- | 16bit量化 | 声道0(左) | 声道0(左) | 声道1(右) | 声道1(右) | | | (低位字节) | (高位字节) | (低位字节) | (高位字节) | - 图6 wav数据bit位置安排方式 Data Chunk头结构定义如下: struct DATA_BLOCK char szDataID4; / d,a,t,a DWORD dwDataSize;三、小结 因此,根据上述结构定义以及格式介绍,很容易编写相应的wav格式解析代码。这里具体的代码就不给出了。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。 文件结构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 | | |_| |_| 数据类型所有数据存储在8bit字节中,按照intel 80x86 (ie, little endian)方式排列,多字节排列顺序如下。 7 6 5 4 3 2 1 0 +-+ 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 | +-+-+ 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 +-+-+-+-+ long: | lsb byte 0 | byte 1 | byte 2 | byte 3 msb | +-+-+-+-+ 采样频率,采样精度,声道数量采样频率(sample rate):1秒钟采样的次数。采样次数越多,越能细分声音的频率。音质越好。采样精度(bit resolution):(采样精度、采样位数、采样值或取样值,随便你怎么叫)用来描述每次采样结果的空间大小。也就是用多大的取值范围去描述一个采样点的值(振幅)。精度越高,对声音的分辨力越强。声道数量(channels):那就是声道数量. 采样点和采样帧(sample point and sample frame)采样点是描述某个时刻的声音样本。采样精度就是这个时间上声音的振幅可以用多大的取值空间描述。16bit的采样精度取值范围是-32768 (0x8000)到32767 (0x7fff)。中点,也就是静音点是0。但对于8bit的采样精度来说,范围却是从0-255,静音点在128。(为何有这样的差异?问比盖去。他的人弄的)因为cpu读数据都是用8bit的byte做单位。所以如果你用的是9-16bit的精度,每个采样点用2byte。17-24bit用3byte,25-32bit就用4byte双word。按左对齐,空出的bit补0(pad部分)。具体排列方式按下图。 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _| | | | | | | | | | | | | | | | | 1 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0 |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| 12bit 采样点按照左对齐方式先排满左边 右面4bit补0(pad) 注意,根据intel little endian存储顺序,按byte为单位从左到右从小到大,因此存到介质上面应该是下面这个顺序: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _| | | | | | | | | | | | | | | | | | 0 1 1 1 0 0 0 0 | | 1 0 1 0 0 0 0 1 |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| bits 0 to 3 4 pad bits bits 4 to 11如果当前的WAV文件是多声道的怎么办?假如是2声道的,先放左边声道的采样点,然后放右面声道的。接着是下一个时刻的左声道采样点。这样用两个采样点分别表示左右声道,在播放的时候同一时间播放出来。那么一个时刻上的采样点的集合就成为采样帧。单声道文件每个采样帧包括1个采样点,两声道的采样帧就有2个采样点。如此类推。 sample sample sample frame 0 frame 1 frame n _ _ _ _ _ _| ch1 | ch2 | ch1 | ch2 | . . . | ch1 | ch2 |_|_|_|_| |_|_| _| | = one sample point|_|下面是大于两声道的情况下的排列标准。 channels 1 2 _ _ | left | right | stereo | | | |_|_| 1 2 3 _ _ _ | left | right | center | 3 channel | | | | |_|_|_| 1 2 3 4 _ _ _ _ | front | front | rear | rear | quad | left | right | left | right | |_|_|_|_| 1 2 3 4 _ _ _ _ | left | center | right | surround| 4 channel | | | | | |_|_|_|_| 1 2 3 4 5 6 _ _ _ _ _ _ | left | left | center | right | right |surround | 6 channel | center | | | center | | | |_|_|_|_|_|_|note:以上为无压缩WAVE格式排列方式。显然这样的方式可压缩空间很大(否则也不会跑出ape这类无损压缩格式了)。如果是有压缩格式,则不一定适用上述规则。 the format chunkformat(fmt)chunk 描述了WAVEFROM数据的基本参数,例如采样频率,精度,声道数量等等。#define formatid fmt /* chunkid for format chunk. note: 因为ID是4字节,所以fmt后面有个空格!切记 */typedef struct . id chunkid; long chunksize; short wformattag; unsigned short wchannels; unsigned long dwsamplespersec; unsigned long dwavgbytespersec; unsigned short wblockalign; unsigned short wbitspersample;/*/* note: there may be additional fields here, depending upon wformattag. */ formatchunk;chunkid:永远是fmt chunksize:大小,不包括chunkid和chunksize占用的8个字节,单位是bytewformattag:如果data chunk里面的数据是无压缩的话,那么每个采样帧和每个采样点的长度应该是固定并且符合上面的采样点规定的,但如果是有压缩的话,这就不一定了。wformattag就是用来标识是否有压缩的。在无压缩的情况下,wformattag的值是1,并且没有fmt chunk没有附加fields(further fields)。wformattag不等于1的其他情况下的处理方式要看微软网站。wchannels:就是声道数量。1、2、3、4、6.dwsamplespersec:采样频率、每秒采样次数。单位赫兹。标准的取值如 11025, 22050, and 44100。dwavgbytespersec:每秒采样数据的空间大小,也就是正常播放的话,每秒要读多少数据。用来方便程序评估留多大缓冲区。dwavgbytespersec的值必须根据下列公式。 dwavgbytespersec = round(dwsamplespersec * wblockalign)wblockalign:块对齐位,值从以下公式得出。 wblockalign = round(wchannels * (wbitspersample % 8)基本上说,wblockalign就等于采样帧大小。wbitspersample就是采样率。每个合法的WAV文件都必须有唯一的一个fmt chunk。 data chunk放声音数据的地方了。#define dataid data /* chunk id for data chunk */typedef struct . id chunkid; long chunksize; unsigned char waveformdata; datachunk;chunkid:永远是datachunksize:不包括chunkid,和chunksize占用的8个字节。waveformdata:这个数组里面每个元素就是一个采样帧,大小看wblockalign每个合法的WAV文件都必须有唯一的一个data chunk。运用多媒体WAV文件格式二三例多媒体技术近年来发展很快,较好品质的声卡可以提供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文件系统作比较,RIFFchunk就好比是一台硬盘的根目录,其格式辨别码便是此硬盘的逻辑代码(C:或D:),而L1STchunk即为其下的子目录,其他的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:记录每个取样所需的位元数。 dataChunk包含真正的声音数据。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位元可以表示0255,16位元可表示065536,不过windows却定16位元其值的范围从-3216832167。此外尚有一点要注意的是,0并不一定代表无声,而是由中间的数值来决定,也就是在8位元时为128,16位元时为0才是无声。所以,若程序设计时需放入无声的数据,糯特别注意声音格式是16或是8位元,以放入适当的值。 1.2 WAV文件信息的具体应用 WAV文件中包括了对原始声音的高速率采样,并且以WAVE_PCM_FORMAT脉派编码调变格式,我们可以在VISUALC+程序中实现,在读出WAVEHDR文件头之后,下面就是原始声音的高速率采样信息,我们可以对它作多方面的信息处理。 1.2.1 波形显示。 我们可以以时域-幅度的方式显示出原始声音的波形,这是最简单同时也是最直接的信息处理方式。在时域范围内,我们可以观察该信号波形是否连续,中间是否有跳变等。 1.2.2频谱显示 我们可以以频域-幅度的方式显示出原始声音的频谱,在对原始信号经过FFT变换之后,可以得到该信号的频谱,进而得到该信号的能量集中带,分布特征,谱对称系数等等。 1.2.3 用于语音信号识别 讲话者的个体识别是语音信号处理的一个重要内容,但它的一个前提条件是必须提供语音信号的数字波形,通常的方法是将原始的语音信号进行放大、抗混叠滤波、A/D采样、数值编码,最终得到语音信号的数字波形,通常多采用硬件处理,费时费力,如果我们借助非常成熟的声卡技术,将WAV文件打开,就非常方便地得到语音信号的数字波形,为下一步进行语音信号识别提供良好的前端预处理。基于VisuaC+6.0的声音文件操作声音是人类传递信息的重要途径,如果应用程序中包含声音信息,就可以大大增强它的亲合力;另外在科研开发过程中,声音信号的处理也是一个很重要的科学研究领域。Visual C+作为一个强大的开发工具,当然是声音处理的首选工具,但是在当前Visual C+相关的编程资料中,无论是大部头的参考书,还是一些计算机杂志,对声音文件的处理都是泛泛的涉及一下,许多编程爱好者都感到对该部分的内容了解不是很透彻,笔者结合自己的学习和开发过程中积累的一些经验,在本实例中来和广大编程爱好者们探讨一下声音文件的处理,当然本实例也不可能包括声音处理内容的方方面面,只是希望它能够对刚刚涉及到声音处理领域的朋友们起到一个引路的作用,帮助他们尽快进入声音处理的更深奥空间。当前计算机系统处理声音文件有两种办法:一是使用现成的软件,如微软的录音机、SoundForge、CoolEdit等软件可以实现对声音信号进行录音、编辑、播放的处理,但它们的功能是有限的,为了更灵活,更大限度地处理声音数据,就不得不使用另外一种方法,既利用微软提供的多媒体服务,在Windows环境下自己编写程序来进行声音处理来实现一些特定的功能。下面就开始介绍声音文件的格式和在Windows环境下使用Visual C+开发工具进行声音文件编程处理的方法。一、实现方法1、RIFF文件结构和WAVE文件格式Windows支持两种RIFF(Resource Interchange File Format,资源交互文件格式)格式的音频文件:MIDI的RMID文件和波形音频文件格式WAVE文件,其中在计算机领域最常用的数字化声音文件格式是后者,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio),由于其扩展名为*.wav,因而该类文件也被称为WAVE文件。为了突出重点,有的放矢,本文涉及到的声音文件所指的就是WAVE文件。常见的WAVE语音文件主要有两种,分别对应于单声道(11.025KHz采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。这里的采样率是指声音信号在进行模数转换过程中单位时间内采样的次数。采样值是指每一次采样周期内声音模拟信号的积分值。对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。在进行声音编程处理以前,首先让我们来了解一下RIFF文件和WAVE文件格式。RIFF文件结构可以看作是树状结构,其基本构成是称为块(Chunk)的单元,每个块有标志符、数据大小及数据所组成,块的结构如图1所示:块的标志符(4BYTES)数据大小 (4BYTES)数据图一、 块的结构示意图从上图可以看出,其中标志符为4个字符所组成的代码,如RIFF,LIST等,指定块的标志ID;数据大小用来指定块的数据域大小,它的尺寸也为4个字符;数据用来描述具体的声音信号,它可以由若干个子块构成,一般情况下块与块是平行的,不能相互嵌套,但是有两种类型的块可以嵌套子块,他们是RIFF或LIST标志的块,其中RIFF块的级别最高,它可以包括LIST块。另外,RIFF块和LIST块与其他块不同,RIFF块的数据总是以一个指定文件中数据存储格式的四个字符码(称为格式类型)开始,如WAVE文件有一个WAVE的格式类型。LIST块的数据总是以一个指定列表内容的4个字符码(称为列表类型)开始,例如扩展名为.AVI的视频文件就有一个strl的列表类型。RIFF和LIST的块结构如下:RIFF/LIST标志符数据1大小数据1格式/列表类型数据图二、RIFF/LIST块结构WAVE文件是非常简单的一种RIFF文件,它的格式类型为WAVE。RIFF块包含两个子块,这两个子块的ID分别是fmt和data,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论