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

下载本文档

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

文档简介

一. RIFF概念在Windows环境下,大部分的多媒体文件都依循着一种结构来存放信息,这种结构称为资源互换文件格式(Resources lnterchange File Format),简称RIFF。例如声音的WAV文件、视频的AV1文件等等均是由此结构衍生出来的。RIFF可以看做是一种树状结构,其基本构成单位为chunk,犹如树状结构中的节点,每个chunk由辨别码、数据大小及数据所组成。块的标志符(4BYTES)数据大小 (4BYTES)数据 图一、 块的结构示意图辨别码由4个ASCII码所构成,数据大小则标示出紧跟其后数据的长度(单位为Byte),而数据大小本身也用掉4个Byte,所以事实上一个chunk的长度为数据大小加8。一般而言,chunk本身并不允许内部再包含chunk,但有两种例外,分别为以RIFF及L1ST为辨别码的chunk。而针对此两种chunk,RIFF又从原先的数据中切出4个Byte。 此4个Byte称为格式辨别码,然而RIFF又规定文件中仅能有一个以RIFF为辨别码的chunk。RIFF/LIST标志符数据1大小数据1格式/列表类型数据 图二、RIFF/LIST块结构只要依循此一结构的文件,我们均称之为RIFF档。此种结构提供了一种系统化的分类。如果和MS一DOS文件系统作比较,RIFFchunk就好比是一台硬盘的根目录,其格式辨别码便是此硬盘的逻辑代码(C:或D:),而L1STchunk即为其下的子目录,其他的chunk则为一般的文件。至于在RIFF文件的处理方面,微软提供了相关的函数。视窗下的各种多媒体文件格式就如同在磁盘机下规定仅能放怎样的目录,而在该目录下仅能放何种数据。二. WAV文件格式WAVE文件是非常简单的一种RIFF文件,它的格式类型为WAVE。RIFF块包含两个子块,这两个子块的ID分别是fmt和data,其中fmt子块由结构PCMWAVEFORMAT所组成,其子块的大小就是sizeofof(PCMWAVEFORMAT),数据组成就是PCMWAVEFORMAT结构中的数据。标志符(RIFF)数据大小格式类型(WAVE)fmtSizeof(PCMWAVEFORMAT)PCMWAVEFORMATdata声音数据大小声音数据图三、WAVE文件结构PCMWAVEFORMAT结构定义如下:Typedef struct. WAVEFORMAT wf; /波形格式; WORD wBitsPerSample; /WAVE文件的采样大小; PCMWAVEFORMAT;/WAVEFORMAT结构定义如下:typedef struct. WORD wFormatag; /编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等 WORD nChannls; /声道数,单声道为1,双声道为2; DWORD nSamplesPerSec; /采样频率; DWORD nAvgBytesperSec; /每秒的数据量; WORD nBlockAlign; /块对齐; WAVEFORMAT;data子块包含WAVE文件的数字化波形声音数据,其存放格式依赖于fmt子块中wFormatTag成员指定的格式种类,在多声道WAVE文件中,样本是交替出现的。如16bit的单声道WAVE文件和双声道WAVE文件的数据采样格式分别如图四所示:16位单声道:采样一采样二低字节高字节低字节高字节16位双声道:采样一左声道右声道低字节高字节低字节高字节 图四、WAVE文件数据采样格式 WAV文件格式实例分析:0 1 2 3 4 5 6 7 8 9 A B C D E F00000000H00000010H00000020H00000030H00000040H52 49 46 46 0A 06 01 00 57 41 56 45 66 6D 74 2012 00 00 00 01 00 02 00 44 AC 00 00 10 B1 02 0004 00 10 00 00 00 66 61 63 74 04 00 00 00 76 4100 00 64 61 74 61 D8 05 01 00 00 00 00 00 FF FF00 00 FE FF FE FF 00 00 00 00 FE FF FE FF 00 00偏移地址字节数数据类型内容文件头00H4char“RIFF”; RIFF标志04H4long int0x00 01 06 0A(注意数据存储顺序); 文件长度08H4char“WAVE”; WAVE标志0CH4char“fmt ”; fmt标志,最后一位为空10H4long int0x12; sizeof(PCMWAVEFORMAT)14H2int1(WAVE_FORMAT_PCM); 格式类别,1表示为PCM形式的声音数据16H2int2; 通道数,单声道为1,双声道为218H2int44100; 采样频率(每秒样本数)1CH4long int0x10B10000; 每秒数据量;其值为通道数每秒数据位数每样本的数据位数8。播放软件利用此值可以估计缓冲区的大小。20H2int数据块的调整数(按字节算的),其值为通道数每样本的数据位值8。播放软件需要一次处理多个该值大小的字节数据,以便将其值用于缓冲区的调整。22H2每样本的数据位数,表示每个声道中各个样本的数据位数。如果有多个声道,对每个声道而言,样本大小都一样。50H4char“data”; 数据标记符54H4long int0x00 01 05 D8; 语音数据大小wav文件格式分析 虽然自己是搞视频图像的,不过偶尔看看音频方面的资料也是可以调节一下的。下面就来分析一下wav波形文件的格式。我们先随便找一个wav文件,查看其属性,就能得到下面的结果。 上面主要注意文件大小,声音长度与比特率。文件占用空间就不用关心了,如果有人想知道为什么文件占用空间比文件大小要大,我在这里也解释一下。这和文件在硬盘中的组织方式有关系,这里的硬盘分区是以最小4096Byte为单位的,我文件的大小是1325044Byte,那么1325044/4096=323.49,为了能把文件对齐的放到硬盘中,所以占用的空间就要是324*4096=1327104Byte了,所以占用的空间就是这么多了。你也可以建立一个只写一个字母的txt文件试试,文件大小虽然为1Byte,不过占用空间也为4096Byte。上面说的当然和wav文件没什么关系,下面就正式说wav文件的问题。用ultraedit打开就是下面这个样子:用表格说明一下文件的格式:起始地址占用空间本地址数字的含义00H4byteRIFF,资源交换文件标志。04H4byte从下一个地址开始到文件尾的总字节数。高位字节在后面,这里就是001437ECH,换成十进制是1325036byte,算上这之前的8byte就正好1325044byte了。08H4byteWAVE,代表wav文件格式。0CH4byteFMT ,波形格式标志10H4byte00000010H,16PCM,我的理解是用16bit的数据表示一个量化结果。14H2byte为1时表示线性PCM编码,大于1时表示有压缩的编码。这里是0001H。16H2byte1为单声道,2为双声道,这里是0001H。18H4byte采样频率,这里是00002B11H,也就是11025Hz。1CH4byteByte率=采样频率*音频通道数*每次采样得到的样本位数/8,00005622H,也就是22050Byte/s=11025*1*16/2。20H2byte块对齐=通道数*每次采样得到的样本位数/8,0002H,也就是2=1*16/8。22H2byte样本数据位数,0010H即16,一个量化样本占2byte。24H4bytedata,一个标志而已。28H4byteWav文件实际音频数据所占的大小,这里是001437C8H即1325000,再加上2CH就正好是1325044,整个文件的大小。2CH不定量化数据。注意属性中的比特率是176kbps,而1CH中为22050Byte/s,换算一下就会发现22050*8/1024并不等于176,而是等于172,这里我想可能是通信中的1K并不等于1024而是等于1000的原因(通信原理书中好像有),如果按22050*8/1000这样算,就正好等于176了。其实比特率也可以这样算,总字节除以时长得到每秒字节率,再乘以8除以1000就得到比特率了,即(1325000/60)*8/1000=176kbps。最后是量化数据的表示。看数据结尾的表示吧,我这音频最初那一段都是0,不好解释。Ultraedit中的表示:Matlab中的表示:上面的matlab是662500个数,正好也是11325000的一半。可以看出数据是有正有负的浮点数,为正负双向PCM量化编码,得到的十六进制位的最高位是一个符号位,为0表示正数,为1表示负数,正好表示-3276832767。而且十六进制的数据正数要除以32767,负数要除以32768才能得到结果,如果是单向PCM就要除以65535了。比如最后一位十六进制为2710H,在Matlab中为0.3052,而2710H的十进制10000除以32767正好近似为0.3052。再比如matlab中662472这个数为-0.0206,考虑到44位的偏差,在ultraedit中为1437BAH位上的FD5DH,表示为十进制-675除以32768正好近似为-0.0206。当然,上面只是针对matlab和ultraedit中的数据进行具体的分析,真正编程处理时还是要根据情况有所不同的。量化位数的不同,32bit或是8bit处理又不同了。符号的表示也可能不同,原码补码反码等等的知识可能也要用到。有机会自己也会编程实践一下。wav文件格式分析(代码) 这个是为上一篇文章做结尾用的。这里我只把基本的数据提取出来了,没有进行下一步处理,数据提取出来,后面怎么应用就看具体情况了。#include #include using namespace std;struct wav_struct unsigned long file_size; /文件大小 unsigned short channel; /通道数 unsigned long frequency; /采样频率 unsigned long Bps; /Byte率 unsigned short sample_num_bit; /一个样本的位数 unsigned long data_size; /数据大小 unsigned char *data; /音频数据 ,这里要定义什么就看样本位数了,我这里只是单纯的复制数据;int main(int argc,char *argv) fstream fs; wav_struct WAV; fs.open(B:output.wav,ios:binary|ios:in);/ fs.seekg(0x04); /从文件数据中获取文件大小/ fs.read(char*)&WAV.file_size,sizeof(WAV.file_size);/ WAV.file_size+=8; fs.seekg(0,ios:end); /用c+常用方法获得文件大小 WAV.file_size=fs.tellg(); fs.seekg(0x14); fs.read(char*)&WAV.channel,sizeof(WAV.channel); fs.seekg(0x18); fs.read(char*)&WAV.frequency,sizeof(WAV.frequency); fs.seekg(0x1c); fs.read(char*)&WAV.Bps,sizeof(WAV.Bps); fs.seekg(0x22); fs.read(char*)&WAV.sample_num_bit,sizeof(WAV.sample_num_bit); fs.seekg(0x28); fs.read(char*)&WAV.data_size,sizeof(WAV.data_size); WAV.data=new unsigned charWAV.data_size; fs.seekg(0x2c); fs.read(char *)WAV.data,sizeof(char)*WAV.data_size); cout文件大小为 :WAV.file_sizeendl; cout音频通道数 :WAV.channelendl; cout采样频率 :WAV.frequencyendl; coutByte率 :WAV.Bpsendl; cout样本位数 :WAV.sample_num_bitendl; cout音频数据大小:WAV.data_sizeendl; cout最后20个数据:endl; for (unsigned long i=WAV.data_size-20;iWAV.data_size;i+) printf(%x ,WAV.datai); fs.close(); delete WAV.data; system(pause);运行结果:可以看出各种数据和上一篇文章中的分析都是对应的。一、综述 WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是“RIFF”。 WAVE文件是由若干个Chunk组成的。按照在文件中的出现位置包括:RIFF WAVEChunk, Format Chunk, Fact Chunk(可选), Data Chunk。具体见下图: 图1 Wav格式包含Chunk示例 其中除了Fact Chunk外,其他三个Chunk是必须的。每个Chunk有各自的ID,位于Chunk最开始位置,作为标示,而且均为4个字节。并且紧跟在ID后面的是Chunk大小(去除ID和Size所占的字节数后剩下的其他字节数目),4个字节表示,低字节表示数值低位,高字节表示数值高位。下面具体介绍各个Chunk内容。PS: 所有数值表示均为低字节表示低位,高字节表示高位。 二、具体介绍RIFF WAVE Chunk 图2 RIFF WAVE Chunk 以FIFF作为标示,然后紧跟着为size字段,该size是整个wav文件大小减去ID和Size所占用的字节数,即FileLen - 8 = Size。然后是Type字段,为WAVE,表示是wav文件。 结构定义如下: struct RIFF_HEADER charszRiffID4;/ R,I,F,F DWORDdwRiffSize; charszRiffFormat4;/ W,A,V,E; Format Chunk 以fmt 作为标示。一般情况下Size为16,此时最后附加信息没有;如果为18则最后多了2个字节的附加信息。主要由一些软件制成的wav格式中含有该2个字节的附加信息。 结构定义如下:struct WAVE_FORMATWORDwFormatTag;WORDwChannels;DWORDdwSamplesPerSec;DWORDdwAvgBytesPerSec;WORDwBlockAlign;WORDwBitsPerSample;struct FMT_BLOCKcharszFmtID4;/ f,m,t, DWORDdwFmtSize;WAVE_FORMATwavFormat; 补充头文件样例说明: 首先是一串“52 49 46 46”这个是Ascii字符“RIFF”,这部分是固定格式,表明这是一个WAVE文件头。然后是“3ec1 0400”,这个是我这个WAV文件的数据大小,记住这个大小是包括头文件的一部分的,包括除了前面8个字节的所有字节,也就等于文件总字节数减去8。这是一个DWORD,我这个文件对应是311614+8 = 311622。然后是“57 41 56 45 66 6D 74 20”,也是Ascii字符“WAVEfmt”,这部分是固定格式。然后是PCMWAVEFORMAT部分,可以对照一下上面的struct定义,首先就是一个WAVEFORMAT的struct。随后是“10 00 00 00”,这是一个DWORD,对应数字16,这个对应定义中的Sizeof(PCMWAVEFORMAT),后面我们可以看到这个段内容正好是16个字节。随后的字节是“01 00”,这是一个WORD,对应定义为编码格式“WAVE_FORMAT_PCM”,我们一般用的是这个。随后的是“02 00”,这是一个WORD,对应数字1,表示声道数为1,2表示双声道,这是个双声道Wav。随后的是“44 AC 00 00”,这是一个DWORD,对应数字4

温馨提示

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

评论

0/150

提交评论