有疑问可发EMAIL咨询: dragon_hn@sohu.com<br /><br />目前复读机大多采用8k采样率,10bits ADC,而DAC则采用8个IO口+电阻的形式,在语音信号频带范围内音质基本可以保证。<br />--------------------------------------------------------<br />http://www.szkfw.com/AV/ARTICLE/ADPCM.htm<br />--------------------------------------------------------<br /><br /><br /><br />ADPCM压缩算法 <br /> <br /> ADPCM(Adaptive Differential Pulse Code Modulation),是一种针对 16bits( 或8bits或者更高) 声音波形数据的一种有损压缩算法,它将声音流中每次采样的 16bit 数据以 4bit 存储,所以压缩比 1:4. 而且压缩/解压缩算法非常简单,所以是一种低空间消耗,高质量高效率声音获得的好途径。保存声音的数据文件后缀名为 .AUD 的大多用ADPCM 压缩。<br /> ADPCM 主要是针对连续的波形数据的,保存的是波形的变化情况,以达到描述整个波形的目的,由于它的编码和解码的过程却很简洁,列在后面,相信大家能够看懂。<br /> 8bits采样的声音人耳是可以勉强接受的,而 16bit 采样的声音可以算是高音质了。ADPCM 算法却可以将每次采样得到的 16bit 数据压缩到 4bit 。需要注意的是,如果要压缩/解压缩得是立体声信号,采样时,声音信号是放在一起的,需要将两个声道分别处理。<br /><br />ADPCM 压缩过程<br /><br /> 首先我们认为声音信号都是从零开始的,那么需要初始化两个变量 <br /><br /> int index=0,prev_sample=0;<br /><br /> 下面的循环将依次处理声音数据流,注意其中的 getnextsample() 应该得到一个 16bit 的采样数据,而 outputdata() 可以将计算出来的数据保存起来,程序中用到的 step_table[],index_adjust[] 附在后面:<br /><br /> int index=0,prev_sample:=0;<br /><br /> while (还有数据要处理)<br /> {<br /> cur_sample=getnextsample(); // 得到当前的采样数据<br /> delta=cur_sample-prev_sample; // 计算出和上一个的增量<br /> if (delta<0) delta=-delta,sb=8; // 取绝对值<br /> else sb = 0 ; // sb 保存的是符号位<br /> code = 4*delta / step_table[index]; // 根据 steptable[]得到一个 0-7 的值<br /> if (code>7) code=7; // 它描述了声音强度的变化量<br /> index += index_adjust[code] ; // 根据声音强度调整下次取steptable 的序号<br /> if (index<0) index=0; // 便于下次得到更精确的变化量的描述<br /> else if (index>88) index=88;<br /> prev_sample=cur_sample;<br /> outputode(code|sb); // 加上符号位保存起来<br /> }<br /><br /> 有关ADPCM压缩过程更详细的信息,参见本站 ADPCM压缩过程演示程序<br /><br /><br />ADPCM 解压缩过程 <br /><br /> 接压缩实际是压缩的一个逆过程,同样其中的 getnextcode() 应该得到一个编码,,而 outputsample() 可以将解码出来的声音信号保存起来。这段代码同样使用了同一个的 setp_table[] 和 index_adjust() 附在后面:<br /><br /> int index=0,cur_sample=0;<br /><br /> while (还有数据要处理) <br /> {<br /> code=getnextcode(); // 得到下一个数据<br /> if ((code & 8) != 0) sb=1 else sb=0;<br /> code&=7; // 将 code 分离为数据和符号<br /> delta = (step_table[index]*code)/4+step_table[index]/8; // 后面加的一项是为了减少误差<br /> if (sb==1) delta=-delta;<br /> cur_sample+=delta; // 计算出当前的波形数据<br /> if (cur_sample>32767) output_sample(32767);<br /> else if (cur_sample<-32768) output_sample(-32768);<br /> else output_sample(cur_sample);<br /> index+=index_adjust[code];<br /> if (index<0) index=0;<br /> if (index>88) index=88;<br /> }<br /><br /> 有关ADPCM解压过程更详细的信息,参见本站 ADPCM解压过程演示程序<br /><br />附表 <br /><br /> int index_adjust[8] = {-1,-1,-1,-1,2,4,6,8};<br /><br /> int step_table[89] = <br /> {<br /> 7,8,9,10,11,12,13,14,16,17,19,21,23,25,28,31,34,37,41,45,<br /> 50,55,60,66,73,80,88,97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,<br /> 408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,1552,1707,1878,2066,<br /> 2272,2499,2749,3024,3327,3660,4026,4428,4871,5358,5894,6484,7132,7845,8630,9493,<br /> 10442,11487,12635,13899,15289,16818,18500,20350,22385,24623,27086,29794,32767<br /> }<br /><br />特殊ADPCM压缩<br /><br /> 根据ADPCM压缩/解压原理,本站提供了 3bits ADPCM 和 4bits ADPCM 压缩程序,另外还提供 ADPCM系数表设计程序 下载。<br /><br />AUD文件结构<br /><br /> 关于 WestWood 的 .AUD 文件,结构比较简单,这里顺带提一下,有兴趣可以自己写处理AUD文件的程序,其 8bit 的声音压缩算法尚不知晓,但用的最广泛的 16bit 声音正是用 ADPCM 压缩,每个 AUD 文件都有一个文件头,结构如下:<br /><br /> struct<br /> {<br /> unsigned short int samplespersec ; // 频率<br /> long int size; // 除掉文件头的大小<br /> long int outsize; // 输出数据大小 (通常是 4 倍)<br /> unsigned char flags; // 位 0 描述是否立体声,位 1 描述是否 16 bit<br /> unsigned char type ; // 1=WW 压缩,99=IMA ADPCM<br /> }<br /><br /> AUD文件的声音信号是按块存放的,每块大约 512 字节,每一块都有一个块头结构:<br /><br /> struct<br /> {<br /> unsigned short int size; // 压缩过的数据大小<br /> unsigned short int outsize; // 输出数据大小 (通常是 4 倍)<br /> long int id; // 永远是 0x0000DEAF<br /> }<br /><br /> <br /><br /><br />------------------------------------------------------<br /><br /><br />有疑问可发EMAIL咨询: dragon_hn@sohu.com<br />
|