ADPCM压缩算法.docx
《ADPCM压缩算法.docx》由会员分享,可在线阅读,更多相关《ADPCM压缩算法.docx(19页珍藏版)》请在冰豆网上搜索。
![ADPCM压缩算法.docx](https://file1.bdocx.com/fileroot1/2023-2/6/9c75a5d9-68c9-49c5-b80c-011d65447601/9c75a5d9-68c9-49c5-b80c-011d654476011.gif)
ADPCM压缩算法
###############################################################################
ADPCM压缩算法
作者:
龙林EMAIL:
dragon_hn@WEB:
www.dragon-
ADPCM(AdaptiveDifferentialPulseCodeModulation),是一种针对16bits(或8bits或者更高)声音波形数据的一种有损压缩算法,它将声音流中每次采样的16bit数据以4bit存储,所以压缩比1:
4.而且压缩/解压缩算法非常简单,所以是一种低空间消耗,高质量高效率声音获得的好途径。
保存声音的数据文件后缀名为.AUD的大多用ADPCM压缩。
ADPCM主要是针对连续的波形数据的,保存的是波形的变化情况,以达到描述整个波形的目的,由于它的编码和解码的过程却很简洁,列在后面,相信大家能够看懂。
8bits采样的声音人耳是可以勉强接受的,而16bit采样的声音可以算是高音质了。
ADPCM算法却可以将每次采样得到的16bit数据压缩到4bit。
需要注意的是,如果要压缩/解压缩得是立体声信号,采样时,声音信号是放在一起的,需要将两个声道分别处理。
ADPCM压缩过程
首先我们认为声音信号都是从零开始的,那么需要初始化两个变量
intindex=0,prev_sample=0;
下面的循环将依次处理声音数据流,注意其中的getnextsample()应该得到一个16bit的采样数据,而outputdata()可以将计算出来的数据保存起来,程序中用到的step_table[],index_adjust[]附在后面:
intindex=0,prev_sample:
=0;
while(还有数据要处理)
{
cur_sample=getnextsample(); //得到当前的采样数据
delta=cur_sample-prev_sample; //计算出和上一个的增量
if(delta<0)delta=-delta,sb=8; //取绝对值
elsesb=0; //sb保存的是符号位
code=4*delta/step_table[index]; //根据steptable[]得到一个0-7的值
if(code>7)code=7; //它描述了声音强度的变化量
index+=index_adjust[code]; //根据声音强度调整下次取steptable的序号
if(index<0)index=0; //便于下次得到更精确的变化量的描述
elseif(index>88)index=88;
prev_sample=cur_sample;
outputode(code|sb); //加上符号位保存起来
}
有关ADPCM压缩过程更详细的信息,参见本站ADPCM压缩过程演示程序
ADPCM解压缩过程
接压缩实际是压缩的一个逆过程,同样其中的getnextcode()应该得到一个编码,,而outputsample()可以将解码出来的声音信号保存起来。
这段代码同样使用了同一个的setp_table[]和index_adjust()附在后面:
intindex=0,cur_sample=0;
while(还有数据要处理)
{
code=getnextcode(); //得到下一个数据
if((code&8)!
=0)sb=1elsesb=0;
code&=7; //将code分离为数据和符号
delta=(step_table[index]*code)/4+step_table[index]/8; //后面加的一项是为了减少误差
if(sb==1)delta=-delta;
cur_sample+=delta; //计算出当前的波形数据
if(cur_sample>32767)output_sample(32767);
elseif(cur_sample<-32768)output_sample(-32768);
elseoutput_sample(cur_sample);
index+=index_adjust[code];
if(index<0)index=0;
if(index>88)index=88;
}
有关ADPCM解压过程更详细的信息,参见本站ADPCM解压过程演示程序
附表
intindex_adjust[8]={-1,-1,-1,-1,2,4,6,8};
intstep_table[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
}
特殊ADPCM压缩
根据ADPCM压缩/解压原理,本站提供了3bitsADPCM和4bitsADPCM压缩程序,另外还提供ADPCM系数表设计程序下载。
AUD文件结构
关于WestWood的.AUD文件,结构比较简单,这里顺带提一下,有兴趣可以自己写处理AUD文件的程序,其8bit的声音压缩算法尚不知晓,但用的最广泛的16bit声音正是用ADPCM压缩,每个AUD文件都有一个文件头,结构如下:
struct
{
unsignedshortintsamplespersec; //频率
longintsize; //除掉文件头的大小
longintoutsize; //输出数据大小(通常是4倍)
unsignedcharflags; //位0描述是否立体声,位1描述是否16bit
unsignedchartype; //1=WW压缩,99=IMAADPCM
}
AUD文件的声音信号是按块存放的,每块大约512字节,每一块都有一个块头结构:
struct
{
unsignedshortintsize;//压缩过的数据大小
unsignedshortintoutsize;//输出数据大小(通常是4倍)
longintid;//永远是0x0000DEAF
}
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
ADPCM-名称
Adpcm是自适应差分脉冲编码调制的简称,最早使用于数字通信系统中。
该算法利用了语音信号样点间的相关性,并针对语音信号的非平稳特点,使用了自适应预测和自适应量化,在32kbps◎8khz速率上能够给出网络等级话音质量。
编辑本段回目录
ADPCM-用途
现在我们使用的是IMAADPCM算法,该算法中对量化步长的调整使用了简单的查表方法,对于一个输入的PCM值X(n),将其与前一时刻的X(n-1)预测值做差值得到d(n),然后根据当前的量化步长对d(n)进行编码,再用此sample点的编码值调整量化步长,同时还要得到当前sample点的预测值供下一sample点编码使用。
通过此算法可将样点编码成4bit的码流,一个符号位和三个幅度位。
该算法较简单,通过查表简化了运算。
对于编码后的数据我们采用了wav文件格式,该格式对编码后的数据流进行了包装,由文件头和数据码流组成,文件头中指出了音频数据所采用格式、采样率、比特率、块长度、比特数及声道数等信息。
数据码流以块为单位,块头指出了该块起始的预测值和index值,码流中每byte的高四位和低四位分别对应一个PCM。
当前该算法以其简单实用的特点广泛应用到数字音乐盒和数字录音笔中。
……………………………………………………………………………………………………
刚写的一个8位ADPCM压缩程序,秀一下.
问
.PUBLIC_stAtei,_stAteo,_indextAble,_stepsizetAble//定义全局变量
S_STATE:
.STRUCT
PrevVAlue:
.DW1DUP(?
)
PrevIndex:
.DW1DUP(?
)
.ENDS
.DATA
_indextAble:
.DW-1,-1,-1,-1,2,4,6,8,-1,-1,-1,-1,2,4,6,8
_stepsizetAble:
.DW4,5,6,7,8,9,11,13,15,17,19,22,25,28,31,34,38,42,46,50,54,59,64,69,74,79,85,91,97,103,109,116,123,127
.RAM
_stAtei:
.S_STATE[]
_stAteo:
.S_STATE[]
.DEFINESTEP 5
.DEFINEBUFOSTEP 4
.DEFINEBUFISTEP 3
.DEFINESIGN 2
.DEFINELEN 11
.DEFINEOUTDATA 10
.DEFINEINDATA 9
.CODE
.PUBLIC_ADPCM_ENCODE,_ADPCM_DECODE
_ADPCM_ENCODE:
.PROC
pushbpto[sp]
sp-=6
bp=SP+1
r1=[_stAtei.PrevIndex]
r1+=_stepsizetAble
R1=[r1]
[BP+STEP]=R1
R1=0
[BP+BUFOSTEP]=R1//BUFOSTEP
[BP+BUFISTEP]=R1//BUFISTEP
T1:
R1=[BP+LEN]
cmpR1,0
JNELOOP
PC=EXIT
LOOP:
R4=[BP+INDATA]
R2=[R4]
R3=[BP+BUFISTEP]
TESTR3,1
JNZLOW_BIT
R2=R2LSRR2
R2=R2LSRR2
JMPT2
LOW_BIT:
R2&Amp;=0x00FF
R1-=1
R4+=1
[BP+INDATA]=R4
[BP+LEN]=R1
T2:
R3=R3XOR0xFFFF
[BP+BUFISTEP]=R3 //R1,R3,R4FREE;
R1=0
R3=[_stAtei.PrevVAlue]
R2-=R3
JSCT3
R1=8
R2=-R2 //R2DIFF
T3:
//R1DELTA
[BP+SIGN]=R1
R3=[BP+STEP] //R3STEP
R4=R3LSR3 //R4vpdiff
CMPR2,R3
JNGET4
R1=4
R2-=R3
R4+=R3
T4:
R3=R3LSR1
CMPR2,R3
JNGET5
R1|=2
R2-=R3
R4+=R3
T5:
R3=R3LSR1
CMPR2,R3
JNGET6
R1|=1
R4+=R3
T6:
//R2R3FREE
r3=[_stAtei.PrevVAlue]
R2=[BP+SIGN]
TESTR2,0x8
JNZT7
R3+=R4
JMPT8
T7:
R3-=R4
T8:
CMPR3,127
JLET9
R3=127
T9:
CMPR3,-128
JGET10
R3=-128
T10:
[_stAtei.PrevVAlue]=R3
R1|=R2
R2=R1+_indextAble
R2=[R2]
R2+=[_stAtei.PrevIndex]
JSCT11_1
R2=0
T11_1:
CMPR2,33
JLET11
R2=33
T11:
[_stAtei.PrevIndex]=R2
R3=R2+_stepsizetAble
R3=[R3]
[BP+STEP]=R3
R3=[BP+OUTDATA]
R4=[R3]
R2=[BP+BUFOSTEP]
CMPR2,0
JNET12
R1=R1LSR4
R1=R1ROR4
[R3]=R1
JMPT15
T12:
CMPR2,1
JNET13
R1=R1LSL4
R1=R1LSL4
R4|=R1
[R3]=R4
JMPT15
T13:
CMPR2,2
JNET14
R1=R1LSL4
R4|=R1
[R3]=R4
JMPT15
T14:
CMPR2,3
JNET15
R4|=R1
[R3]=R4
R3+=1
[BP+OUTDATA]=R3
R2=0
[BP+BUFOSTEP]=R2
PC=T1
T15:
R2+=1
[BP+BUFOSTEP]=R2
PC=T1
EXIT:
sp+=6;
popbpfrom[sp]
retf
.ENDP
_ADPCM_DECODE:
.PROC
.ENDP
ADPCM简介
Adpcm是自适应差分脉冲编码调制的简称,最早使用于数字通信系统中。
该算法利用了语音信号样点间的相关性,并针对语音信号的非平稳特点,使用了自适应预测和自适应量化,在32kbps◎8khz速率上能够给出网络等级话音质量。
现在我们使用的是IMAADPCM算法,该算法中对量化步长的调整使用了简单的查表方法,对于一个输入的PCM值X(n),将其与前一时刻的X(n-1)预测值做差值得到d(n),然后根据当前的量化步长对d(n)进行编码,再用此sample点的编码值调整量化步长,同时还要得到当前sample点的预测值供下一sample点编码使用。
通过此算法可将样点编码成4bit的码流,一个符号位和三个幅度位。
该算法较简单,通过查表简化了运算。
对于编码后的数据我们采用了wav文件格式,该格式对编码后的数据流进行了包装,由文件头和数据码流组成,文件头中指出了音频数据所采用格式、采样率、比特率、块长度、比特数及声道数等信息。
数据码流以块为单位,块头指出了该块起始的预测值和index值,码流中每byte的高四位和低四位分别对应一个PCM。
当前该算法以其简单实用的特点广泛应用到数字音乐盒和数字录音笔中。
—……—……—……—……—……———————————————————————
ADPCM压缩算法
ADPCM(AdaptiveDifferentialPulseCodeModulation),是一种针对16bits(或8bits或者更高)声音波形数据的一种有损压缩算法,它将声音流中每次采样的16bit数据以4bit存储,所以压缩比1:
4.而且压缩/解压缩算法非常简单,所以是一种低空间消耗,高质量高效率声音获得的好途径。
保存声音的数据文件后缀名为.AUD的大多用ADPCM压缩。
ADPCM主要是针对连续的波形数据的,保存的是波形的变化情况,以达到描述整个波形的目的,由于它的编码和解码的过程却很简洁,列在后面,相信大家能够看懂。
8bits采样的声音人耳是可以勉强接受的,而16bit采样的声音可以算是高音质了。
ADPCM算法却可以将每次采样得到的16bit数据压缩到4bit。
需要注意的是,如果要压缩/解压缩得是立体声信号,采样时,声音信号是放在一起的,需要将两个声道分别处理。
ADPCM压缩过程
首先我们认为声音信号都是从零开始的,那么需要初始化两个变量
intindex=0,prev_sample=0;
下面的循环将依次处理声音数据流,注意其中的getnextsample()应该得到一个16bit的采样数据,而outputdata()可以将计算出来的数据保存起来,程序中用到的step_table[],index_adjust[]附在后面:
intindex=0,prev_sample:
=0;
while(还有数据要处理)
{
cur_sample=getnextsample(); //得到当前的采样数据
delta=cur_sample-prev_sample; //计算出和上一个的增量
if(delta<0)delta=-delta,sb=8; //取绝对值
elsesb=0; //sb保存的是符号位
code=4*delta/step_table[index]; //根据steptable[]得到一个0-7的值
if(code>7)code=7; //它描述了声音强度的变化量
index+=index_adjust[code]; //根据声音强度调整下次取steptable的序号
if(index<0)index=0; //便于下次得到更精确的变化量的描述
elseif(index>88)index=88;
prev_sample=cur_sample;
outputode(code|sb); //加上符号位保存起来
}
ADPCM解压缩过程
接压缩实际是压缩的一个逆过程,同样其中的getnextcode()应该得到一个编码,,而outputsample()可以将解码出来的声音信号保存起来。
这段代码同样使用了同一个的setp_table[]和index_adjust()附在后面:
intindex=0,cur_sample=0;
while(还有数据要处理)
{
code=getnextcode(); //得到下一个数据
if((code&8)!
=0)sb=1elsesb=0;
code&=7; //将code分离为数据和符号
delta=(step_table[index]*code)/4+step_table[index]/8; //后面加的一项是为了减少误差
if(sb==1)delta=-delta;
cur_sample+=delta; //计算出当前的波形数据
if(cur_sample>32767)output_sample(32767);
elseif(cur_sample<-32768)output_sample(-32768);
elseoutput_sample(cur_sample);
index+=index_adjust[code];
if(index<0)index=0;
if(index>88)index=88;
}
附表
intindex