ADPCM编码与解码原理.docx
- 文档编号:24396378
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:17
- 大小:19KB
ADPCM编码与解码原理.docx
《ADPCM编码与解码原理.docx》由会员分享,可在线阅读,更多相关《ADPCM编码与解码原理.docx(17页珍藏版)》请在冰豆网上搜索。
ADPCM编码与解码原理
ADPCM编码与解码原理
一、前言
之前许多次说过,有空的时候写写博客,可是一直没有好好落实。
由于工作的原因,经常会接触到一些音视频的编解码技术,而ADPCM就是我第一接触的音频编码技术。
所以,本人的第一篇博客就是对ADPCM的编码与解码进行详解。
本文对ADPCM编码与解码的描述,分为两章进行。
二、IMA-ADPCM的编码原理
ADPCM(AdaptiveDifferentialPulseCodeModulation差分脉冲编码调制)主要是针对连续的波形数据的,保存的是相临波形的变化情况,以达到描述整个波形的目的。
本文的以IMA的ADPCM编码标准为例进行描述,IMA-ADPCM是Intel公司首先开发的是一种主要针对16bit采样波形数据的有损压缩算法,压缩比为4:
1.它与通常的DVI-ADPCM是同一算法。
(对8bit数据压缩时是3.2:
1,也有非标准的IMA-ADPCM压缩算法,可以达到5:
1甚至更高的压缩比)4:
1的压缩是目前使用最多的压缩方式。
结尾附adpcm编解码的源代码adpcm.h与adpcm.c。
ADPCM编码本质是一种预测编码,那么它是怎么样进行预测的呢?
预测编码利用相邻的音频数据在时间上的相关性,相邻采样点的音频数据具有相似的特点。
因此,进过压缩后的数据并不是音频数据本身,而是该数据的预测值与实际值之差。
偏差需要量化器进行量化,假如我们对于16bit的音频数据采用16bit的量化,那么偏差与实际的数据值占据的位数一样则无法达到压缩数据的目的,如果采用4bit的量化位数,其最大的量化步数只能是16,显然是不能满足使用要求,因此ADPCM应运而生,ADPCM是一种采用变步长的量化器的预测编码算法,它的本质是根据预测值与实际的偏差范围,在量化表格中选择出合适的量化值,使预测变化的幅度保持在4bit的范围内。
ADPCM的核心公式如下,其中代表为量化后的值,为量化步长,代表经过量化后有效的偏差值,加上本次的预测值做为下一次的运算的预测值:
整个ADPCM的编码过程分三步进行:
第一步为计算出当前实际值与预测值的偏差,代表了当前数据的实际值,为当前数的预测值。
为量化后的带符号的有效数据为4bit的数据,其最高位代表的数据的方向,bit3为1代表负数,代表-7~7的整型数据。
当小于0, bit3被值1。
第二步为对进行量化,简易实现不考虑计算效率的情况下完全可以直接参考上面的公式,因为是在计算机平台进行了除法运算与小数运算,该作者很巧妙的把这些运算使用与或非来实现了,提高了运算的效率,有兴趣的读者可以看看代码,学习一下这种思路。
我们细看一下公式,,可以发现公式可以拆分为两部分实现,小数部分的量化被转换为了固定的,因此节约了计算的成本。
vpdiff就是对应这部分的值。
vpdiff=(step>>3);
staticintindexTable[16]={
-1,-1,-1,-1,2,4,6,8,
-1,-1,-1,-1,2,4,6,8,
};
staticintstepsizeTable[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.h
/*
**adpcm.h-includefileforadpcmcoder.
**
**Version1.0,7-Jul-92.
*/
#ifndefADPCM_H
#defineADPCM_H
#ifdef__cplusplus
extern"C"{
#endif
structadpcm_state{
shortvalprev;/*Previousoutputvalue*/
charindex;/*Indexintostepsizetable*/
};
intadpcm_coder(short*indata,unsignedchar*outdata,intlen,structadpcm_state*state);
intadpcm_decoder(unsignedchar*indata,short*outdata,intlen,structadpcm_state*state);
#ifdef__cplusplus
}/*extern"C"*/
#endif
#endif/*ADPCM_H*/
adpcm.c
/***********************************************************
Copyright1992byStichtingMathematischCentrum,Amsterdam,The
Netherlands.
AllRightsReserved
Permissiontouse,copy,modify,anddistributethissoftwareandits
documentationforanypurposeandwithoutfeeisherebygranted,
providedthattheabovecopyrightnoticeappearinallcopiesandthat
boththatcopyrightnoticeandthispermissionnoticeappearin
supportingdocumentation,andthatthenamesofStichtingMathematisch
CentrumorCWInotbeusedinadvertisingorpublicitypertainingto
distributionofthesoftwarewithoutspecific,writtenpriorpermission.
STICHTINGMATHEMATISCHCENTRUMDISCLAIMSALLWARRANTIESWITHREGARDTO
THISSOFTWARE,INCLUDINGALLIMPLIEDWARRANTIESOFMERCHANTABILITYAND
FITNESS,INNOEVENTSHALLSTICHTINGMATHEMATISCHCENTRUMBELIABLE
FORANYSPECIAL,INDIRECTORCONSEQUENTIALDAMAGESORANYDAMAGES
WHATSOEVERRESULTINGFROMLOSSOFUSE,DATAORPROFITS,WHETHERINAN
ACTIONOFCONTRACT,NEGLIGENCEOROTHERTORTIOUSACTION,ARISINGOUT
OFORINCONNECTIONWITHTHEUSEORPERFORMANCEOFTHISSOFTWARE.
******************************************************************/
/*
*CleanedupbyPhilFrisbieforuseinHawkVoice
*/
/*
**Intel/DVIADPCMcoder/decoder.
**
**ThealgorithmforthiscoderwastakenfromtheIMACompatabilityProject
**proceedings,Vol2,Number2;May1992.
**
**Version1.2,18-Dec-92.
**
**Changelog:
**-Fixedastupidbug,wherethedeltawascomputedas
**stepsize*code/4insteadofstepsize*(code+0.5)/4.
**-Therewasanoff-by-oneerrorcausingittopick
**anincorrectdeltaonceinabluemoon.
**-TheNODIVMULdefinehasbeenremoved.Computationsarenowalwaysdone
**usingshifts,addsandsubtracts.Itturnedoutthat,becausethestandard
**isdefinedusingshift/add/subtract,youneededbitsoffixupcode
**(becausethediv/mulsimulationusingshift/add/submadesomerounding
**errorsthatrealdiv/muldon'tmake)andalltogethertheresultantcode
**ranslowerthanjustusingtheshiftsallthetime.
**-Changedsomeofthevariablenamestobemoremeaningful.
*/
#include"adpcm.h"
/*IntelADPCMstepvariationtable*/
staticintindexTable[16]={
-1,-1,-1,-1,2,4,6,8,
-1,-1,-1,-1,2,4,6,8,
};
staticintstepsizeTable[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
};
intadpcm_coder(short*indata,unsignedchar*outdata,intlen,structadpcm_state*state)
{
intval;/*Currentinputsamplevalue*/
unsignedintdelta;/*Currentadpcmoutputvalue*/
intdiff;/*Differencebetweenvalandvalprev*/
intstep;/*Stepsize*/
intvalpred;/*Predictedoutputvalue*/
intvpdiff;/*Currentchangetovalpred*/
intindex;/*Currentstepchangeindex*/
unsignedintoutputbuffer=0;/*placetokeepprevious4-bitvalue*/
intcount=0;/*thenumberofbytesencoded*/
valpred=state->valprev;
index=(int)state->index;
step=stepsizeTable[index];
while(len>0){
/*Step1-computedifferencewithpreviousvalue*/
val=*indata++;
diff=val-valpred;
if(diff<0)
{
delta=8;
diff=(-diff);
}
else
{
delta=0;
}
/*Step2-Divideandclamp*/
/*Note:
**Thiscode*approximately*computes:
**delta=diff*4/step;
**vpdiff=(delta+0.5)*step/4;
**butinshiftstepbitsaredropped.Thenetresultofthisis
**thatevenifyouhavefastmul/divhardwareyoucannotputitto
**goodusesincethefixupwouldbetooexpensive.
*/
vpdiff=(step>>3);
if(diff>=step){
delta|=4;
diff-=step;
vpdiff+=step;
}
step>>=1;
if(diff>=step){
delta|=2;
diff-=step;
vpdiff+=step;
}
step>>=1;
if(diff>=step){
delta|=1;
vpdiff+=step;
}
/*PhilFrisbiecombinedsteps3and4*/
/*Step3-Updatepreviousvalue*/
/*Step4-Clamppreviousvalueto16bits*/
if((delta&8)!
=0)
{
valpred-=vpdiff;
if(valpred<-32768)
valpred=-32768;
}
else
{
valpred+=vpdiff;
if(valpred>32767)
valpred=32767;
}
/*Step5-Assemblevalue,updateindexandstepvalues*/
index+=indexTable[delta];
if(index<0)index=0;
elseif(index>88)index=88;
step=stepsizeTable[index];
/*Step6-Outputvalue*/
outputbuffer=(delta<<4);
/*Step1-computedifferencewithpreviousvalue*/
val=*indata++;
diff=val-valpred;
if(diff<0)
{
delta=8;
diff=(-diff);
}
else
{
delta=0;
}
/*Step2-Divideandclamp*/
/*Note:
**Thiscode*approximately*computes:
**delta=diff*4/step;
**vpdiff=(delta+0.5)*step/4;
**butinshiftstepbitsaredropped.Thenetresultofthisis
**thatevenifyouhavefastmul/divhardwareyoucannotputitto
**goodusesincethefixupwouldbetooexpensive.
*/
vpdiff=(step>>3);
if(diff>=step){
delta|=4;
diff-=step;
vpdiff+=step;
}
step>>=1;
if(diff>=step){
delta|=2;
diff-=step;
vpdiff+=step;
}
step>>=1;
if(diff>=step){
delta|=1;
vpdiff+=step;
}
/*PhilFrisbiecombinedsteps3and4*/
/*Step3-Updatepreviousvalue*/
/*Step4-Clamppreviousvalueto16bits*/
if((delta&8)!
=0)
{
valpred-=vpdiff;
if(valpred<-32768)
valpred=-32768;
}
else
{
valpred+=vpdiff;
if(valpred>32767)
valpred=32767;
}
/*Step5-Assemblevalue,updateindexandstepvalues*/
index+=indexTable[delta];
if(index<0)index=0;
elseif(index>88)index=88;
step=stepsizeTable[index];
/*Step6-Outputvalue*/
*outdata++=(unsignedchar)(delta|outputbuffer);
count++;
len-=2;
}
state->valprev=(short)valpred;
state->index=(char)index;
returncount;
}
intadpcm_decoder(unsignedchar*indata,short*outdata,intlen,structadpcm_state*state)
{
unsignedintdelta;/*Currentadpcmoutputvalue*/
intstep;/*Stepsize*/
intvalpred;/*Predictedvalue*/
intvpdiff;/*Currentchangetovalpred*/
intindex;/*Currentstepchangeindex*/
unsignedintinputbuffer=0;/*placetokeepnext4-bitvalue*/
intcount=0;
valpred=state->valprev;
index=(int)state->index;
step=stepsizeTable[index];
/*LoopunrollingbyPhilFrisbie*/
/*ThisassumesthereareALWAYSanevennumberofsamples*/
while(len-->0){
/*Step1-getthedeltavalue*/
inputbuffer=(unsignedint)*indata++;
delta=(inputbuffer>>4);
/*Step2-Findnewindexvalue(forlater)*/
index+=indexTable[delta];
if(index<0)index=0;
elseif(index>88)index=88;
/*PhilFrisbiecombinedsteps3,4,and5*/
/*Step3-Separatesignandmagnitude*/
/*Step4-Computedifferenceandnewpredictedvalue*/
/*Step5-clampoutputvalue*/
/*
**Computes'vpdiff=(delta+0.5)*step/4',butseecomment
**inadpcm_
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ADPCM 编码 解码 原理