好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

WAVE音频文件格式.doc

5页
  • 卖家[上传人]:e****s
  • 文档编号:1347327
  • 上传时间:2017-06-08
  • 文档格式:DOC
  • 文档大小:25.50KB
  • / 5 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • WAVE 文件的压缩与解压缩[转帖]一、概述:本文叙述了如何通过 IMA-ADPCM 压缩和解压缩算法来完成从 IMA-ADPCM 文件转换为 PCM 文件的过程主要包括的内容有:PCM 和 IMA-ADPCM WAVE 文件内部结构的介绍,IMA-ADPCM 压缩与解压缩算法,以及如何生成特有的音频压缩格式文件等三方面的内容二、WAVE 文件的认识WAVE 文件是计算机领域最常用的数字化声音文件格式之一,它是微软专门为Windows 系统定义的波形文件格式( Waveform Audio) ,由于其扩展名为"*.wav"wave 文件有很多不同的压缩格式,而且现在一些程序生成的 wave 文件都或多或少地含有一些错误这些错误的产生不是因为单个数据压缩和解压缩算法的问题,而是因为在压缩和解压缩后没有正确地组织好文件的内部结构所以,正确而详细地了解各种 WAVE 文件的内部结构是成功完成压缩和解压缩的基础,也是生成特有音频压缩格式文件的前提最基本的 WAVE 文件是 PCM(脉冲编码调制)格式的,这种文件直接存储采样的声音数据没有经过任何的压缩,是声卡直接支持的数据格式,要让声卡正确播放其它被压缩的声音数据,就应该先把压缩的数据解压缩成 PCM 格式,然后再让声卡来播放。

      1.Wave 文件的内部结构WAVE 文件是以 RIFF(Resource Interchange File Format,"资源交互文件格式") 格式来组织内部结构的RIFF 文件结构可以看作是树状结构,其基本构成是称为 "块"( Chunk)的单元,最顶端是一个“RIFF”块,下面的每个块有“类型块标识(可选)” 、 “标志符”、 “数据大小” 及“数据”等项所组成,块的结构如表 1 所示:上面说到的“类型块标识”只在部分 chunk 中用到,如 “WAVE”chunk 中,这时表示下面嵌套有别的 chunk,当使用了“类型块标识” 时,该 chunk 就没有别的项(如块标志符,数据大小等) ,它只作为文件读取时的一个标识先找到这个“类型块标识”,再以它为起来读取它下面嵌套的其它 chunk每个文件最前端写入的是 RIFF 块,每个文件只有一个 RIFF 块从表 2 中可以看出它的结构:非 PCM 格式的文件会至少多加入一个“fact” 块,它用来记录数据解压缩后的大小 (注意是数据而不是文件)这个“fact”块一般加在“data”块的前面2.WAVEFORMAT 结构的认识PCM 和非 PCM 的主要区别是声音数据的组织不同,这些区别可以通过两者的WAVEFORMAT 结构来区分。

      下面以 PCM 和 IMA-ADPCM 来进行对比:WAVE 的基本结构 WAVEFORMATEX 结构定义如下:typedef struct{WORD wFormatag; //编码格式,包括WAVE_FORMAT_PCM,//WAVEFORMAT_ADPCM 等WORD nChannls; //声道数,单声道为 1,双声道为 2;DWORD nSamplesPerSec;//采样频率;DWORD nAvgBytesperSec;//每秒的数据量;WORD nBlockAlign;//块对齐;WORD wBitsPerSample;//WAVE 文件的采样大小;WORD sbSize; //PCM 中忽略此值}WAVEFORMATEX;PCM 的结构就是基本结构;IMAADPCMWAVEFORMAT 结构定义如下:Typedef struct{WAVEFORMATEX wfmt;WORD nSamplesPerBlock;}IMAADPCMWAVEFORMAT;IMA-ADPCM 的 wfmt->cbsize 不能忽略,一般取值为 2,表示此类型的 WAVEFORMAT 比一般的 WAVEFORMAT 多出 2 个字节。

      这两个字符也就是 nSamplesPerBlock3.“fact”chunk 的内部组织在非 PCM 格式的文件中,一般会在 WAVEFORMAT 结构后面加入一个“fact”chunk,结构如下:typedef struct{char[4]; //“fact”字符串DWORD chunksize;DWORD datafactsize; //数据转换为 PCM 格式后的大小}factchunk;datafactsize 是这个 chunk 中最重要的数据,如果这是某种压缩格式的声音文件,那么从这里就可以知道他解压缩后的大小对于解压时的计算会有很大的好处!4. “data”chunk 的内部组织从“data”chunk 的第 9 个字节开始,存储的就是声音信息的数据了,(前八个字节存储的是标志符“data”和后接数据大小 size(DWORD)这些数据可能是压缩的,也可能是没有压缩的PCM 中的声音数据没有被压缩,如果是单声道的文件,采样数据按时间的先后顺序依次存入 (它的基本组织单位是 BYTE(8bit)或 WORD(16bit))如果是双声道的文件,采样数据按时间先后顺序交叉地存入。

      如图所示:IMA-ADPCM 是压缩格式,它是从 PCM 的 16 位采样压缩成 4 位的对于单声道的 IMA-ADPCM 来说,它是将 PCM 的数据按时间次序依次压缩并写入文件中的,每个 byte 中含两个采样,低四位对应第一个采样,高四位对应第二个采样而对于双声道的 IMA-ADPCM 来说,它的存储相对就麻烦一些了,它是将 PCM 的左声道的前 8 个采样依次压缩并写入到一个 DWORD 中,然后写入“data”chunk 里紧接着是右声道的前 8 个采样以此循环,当采样数不足 8 时(到数据尾端) ,应该把多出来的采样用 0 填充其示意图如下:特别注意:在 IMA-ADPCM 中, “data”chuck 中的数据是以 block 形式来组织的,我把它叫做“段”,也就是说在进行压缩时,并不是依次把所有的数据进行压缩保存,而是分段进行的,这样有一个十分重要的好处:那就是在只需要文件中的某一段信息时,可以在解压缩时可以只解所需数据所在的段就行了,没有必要再从文件开始起一个一个地解压缩这对于处理大文件将有相当的优势同时,这样也可以保证声音效果Block 一般是由 block header (block 头) 和 data 两者组成的。

      其中 block header 是一个结构,它在单声道下的定义如下:Typedef struct{short sample0; //block 中第一个采样值(未压缩)BYTE index; //上一个 block 最后一个 index,第一个 block 的 index=0;BYTE reserved; //尚未使用}MonoBlockHeader;有了 blockheader 的信息后,就可以不需要知道这个 block 前面和后面的数据而轻松地解出本 block 中的压缩数据对于双声道,它的 blockheader 应该包含两个 MonoBlockHeader 其定义如下:typedaf struct{MonoBlockHeader leftbher;MonoBlockHeader rightbher;}StereoBlockHeader;在解压缩时,左右声道是分开处理的,所以必须有两个 MonoBlockHeader;注 1:上述的 index 是解压缩算法中必须用到的一个参数详见后面注 2: 关于 block 的大小,通常会有以下几种情况:对于单声道,大小一般为 512byte,显然这里面可以保存的 sample 个数为(512-sizeof(MonoBlockHeader))/4 + 1 = 1017 个7) code=7; // 根据 steptab[] 得到一个 0~7 的值,它描述了采样振幅的变化量index+=index_adjust[code]; // 根据声音强度调整下次取 steptab 的序号,便于下次得到更精确的变化量的描述if (index88) index=88;prev_sample=cur_sample;SaveComCode(code|fg); // 加上符号位保存起来}--------------------------------------------------------------------------------IMA-ADPCM 解压缩过程解压缩实际是压缩的一个逆过程,假设写好了以下两个函数:GetNextCode() —— 得到一个编码(4bit)OutputSamp() —— 将解码出来的声音信号保存起来( 16bit).int index=0,cur_sample=0;while (还有数据要处理) {code=GetNextCode(); // 得到下一个压缩样品 Code 4bitif ((code & 8) != 0) fg=1 else fg=0;code&=7; // 将 code 分离为数据和符号diff = (steptab[index]*code) /4 + steptab[index] / 8; // 后面加的一项是为了减少误差 if (fg==1) diff=-diff;cur_sample+=diff; // 计算出当前的波形数据if (cur_sample>32767) OutputSamp(32767);else if (cur_sample88) index=88;}--------------------------------------------------------------------------------附表int index_adjust[8] = {-1,-1,-1,-1,2,4,6,8};int steptab[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 };四、设计自己特用的压缩声音文件格式。

      有了上述几节的知识,要基于 IMA-ADPCM Encode/Dcode 算法来设计出特有的压缩声音文件格式就不难了!只要 先设计好特有的文件内部结构和特殊的数据组织结构,再以此为标准编写压缩和解压缩程序就行了由于我们已经搞清楚了 PCM 里面的数据组织,所以我们还可以进行 PCM 文件的截取、连接、压缩等更多功能。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.