ADPCM压缩算法.docx

上传人:b****7 文档编号:10774940 上传时间:2023-02-22 格式:DOCX 页数:21 大小:19.28KB
下载 相关 举报
ADPCM压缩算法.docx_第1页
第1页 / 共21页
ADPCM压缩算法.docx_第2页
第2页 / 共21页
ADPCM压缩算法.docx_第3页
第3页 / 共21页
ADPCM压缩算法.docx_第4页
第4页 / 共21页
ADPCM压缩算法.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

ADPCM压缩算法.docx

《ADPCM压缩算法.docx》由会员分享,可在线阅读,更多相关《ADPCM压缩算法.docx(21页珍藏版)》请在冰豆网上搜索。

ADPCM压缩算法.docx

ADPCM压缩算法

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_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 }

TCPMP原代码赏析

/*****************************************************************************

 *

 *Thisprogramisfreesoftware;youcanredistributeitand/ormodify

 *itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby

 *theFreeSoftwareFoundation;eitherversion2oftheLicense,or

 *(atyouroption)anylaterversion.

 *

 *Thisprogramisdistributedinthehopethatitwillbeuseful,

 *butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof

 *MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe

 *GNUGeneralPublicLicenseformoredetails.

 *

 *YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense

 *alongwiththisprogram;ifnot,writetotheFreeSoftware

 *Foundation,Inc.,59TemplePlace,Suite330,Boston,MA 02111-1307USA

 *

 *$Id:

adpcm.h2712005-08-0908:

31:

35Zpicard$

 *

 *TheCorePocketMediaPlayer

 *Copyright(c)2004-2005GaborKovacs

 *

 ****************************************************************************/

#ifndef__ADPCM_H

#define__ADPCM_H

#defineADPCM_CLASS FOURCC('A','D','P','C')

#defineADPCM_MS_ID FOURCC('A','D','M','S')

#defineADPCM_IMA_IDFOURCC('A','D','I','M')

#defineADPCM_IMA_QT_IDFOURCC('A','D','I','Q')

#defineADPCM_G726_IDFOURCC('G','7','2','6')

externvoidADPCM_Init();

externvoidADPCM_Done();

#endif

/*****************************************************************************

 *

 *Thisprogramisfreesoftware;youcanredistributeitand/ormodify

 *itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby

 *theFreeSoftwareFoundation;eitherversion2oftheLicense,or

 *(atyouroption)anylaterversion.

 *

 *Thisprogramisdistributedinthehopethatitwillbeuseful,

 *butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof

 *MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe

 *GNUGeneralPublicLicenseformoredetails.

 *

 *YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense

 *alongwiththisprogram;ifnot,writetotheFreeSoftware

 *Foundation,Inc.,59TemplePlace,Suite330,Boston,MA 02111-1307USA

 *

 *$Id:

adpcm.c5652006-01-1214:

11:

44Zpicard$

 *

 *TheCorePocketMediaPlayer

 *Copyright(c)2004-2005GaborKovacs

 *

 ****************************************************************************/

#include"../common/common.h"

#include"adpcm.h"

#include"g726/g72x.h"

typedefstructstate

{

   intPredictor;

   intStepIndex;

   intStep;

   intSample1;

   intSample2;

   intCoEff1;

   intCoEff2;

   intIDelta;

}state;

typedefstructadpcm

{

 codecCodec;

 bufferData;

 intChannel;//IMA_QT

 int16_t*Buffer;

 stateState[2];

 g726_stateG726[2];

}adpcm;

staticconstintIndexTable[16]=

{

   -1,-1,-1,-1,2,4,6,8,

   -1,-1,-1,-1,2,4,6,8,

};

staticconstintStepTable[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

};

//AdaptationTable[],AdaptCoeff1[],andAdaptCoeff2[]arefromlibsndfile

staticconstintAdaptationTable[]=

{

 230,230,230,230,307,409,512,614,

 768,614,512,409,307,230,230,230

};

staticconstintAdaptCoeff1[]=

{

 256,512,0,192,240,460,392

};

staticconstintAdaptCoeff2[]=

{

 0,-256,0,64,0,-208,-232

};

static_INLINEintIMA_Calc(state*s,intv)

{

   intStepIndex;

   intPredictor;

   intDiff,Step;

   Step=StepTable[s->StepIndex];

   StepIndex=s->StepIndex+IndexTable[v];

   if(StepIndex<0)

 StepIndex=0;

   elseif(StepIndex>88)

 StepIndex=88;

   Diff=((2*(v&7)+1)*Step)>>3;

   Predictor=s->Predictor;

   if(v&8)

 Predictor-=Diff;

   else

 Predictor+=Diff;

 if(Predictor>32767)

 Predictor=32767;

 elseif(Predictor<-32768)

 Predictor=-32768;

   s->Predictor=Predictor;

   s->StepIndex=StepIndex;

   returnPredictor;

}

static_INLINEintMS_Calc(state*s,intv)

{

   intPredictor;

   Predictor=((s->Sample1*s->CoEff1)+(s->Sample2*s->CoEff2))>>8;

   Predictor+=((v&0x08)?

v-0x10:

v)*s->IDelta;

 if(Predictor>32767)

 Predictor=32767;

 elseif(Predictor<-32768)

 Predictor=-32768;

   s->Sample2=s->Sample1;

   s->Sample1=Predictor;

   s->IDelta=(AdaptationTable[v]*s->IDelta)>>8;

   if(s->IDelta<16)

 s->IDelta=16;

   returnPredictor;

}

staticintProcess(adpcm*p,constpacket*Packet,constflowstate*State)

{

 inti;

 intPredictor;

 constuint8_t*In;

 constuint8_t*InEnd;

 int16_t*Out=p->Buffer;

 if(Packet)

 {

 if(Packet->RefTime>=0)

  p->Codec.Packet.RefTime=Packet->RefTime;

 BufferPack(&p->Data,0);

 BufferWrite(&p->Data,Packet->Data[0],Packet->Length,1024);

 }

 else

 p->Codec.Packet.RefTime=TIME_UNKNOWN;

 if(!

BufferRead(&p->Data,&In,p->Codec.In.Format.Format.Audio.BlockAlign))

 returnERR_NEED_MORE_DATA;

 InEnd=In+p->Codec.In.Format.Format.Audio.BlockAlign;

 switch(p->Codec.Node.Class)

 {

 caseADPCM_G726_ID:

 {

 g726_state*g1,*g2;

 g1=g2=&p->G726[0];

 if(p->Codec.In.Format.Format.Audio.Channels==2)

  ++g2;

 switch(p->Codec.In.Format.Format.Audio.Bits)

 {

 case2:

  for(;In

  {

   Out[0]=(int16_t)g726_16_decoder(In[0]>>6,g1);

   Out[1]=(int16_t)g726_16_decoder(In[0]>>4,g2);

   Out[2]=(int16_t)g726_16_decoder(In[0]>>2,g1);

   Out[3]=(int16_t)g726_16_decoder(In[0],g2);

  }

  break;

 case3:

  InEnd-=2;

  for(;In

  {

   Out[0]=(int16_t)g726_24_decoder(In[0]>>5,g1);

   Out[1]=(int16_t)g726_24_decoder(In[0]>>2,g2);

   Out[2]=(int16_t)g726_24_decoder((In[0]<<1)|(In[1]>>7),g1);

   Out[3]=(int16_t)g726_24_decoder(In[1]>>4,g2);

   Out[4]=(int16_t)g726_24_decoder(In[1]>>1,g1);

   Out[5]=(int16_t)g726_24_decoder((In[1]<<2)|(In[2]>>6),g2);

   Out[6]=(int16_t)g726_24_decoder(In[2]>>3,g1);

   Out[7]=(int16_t)g726_24_decoder(In[2]>>0,g2);

  }

  break;

 case4:

  for(;In

  {

   Out[0]=(int16_t)g726_32_decoder(In[0]>>4,g1);

   Out[1]=(int16_t)g726_32_decoder(In[0],g2);

  }

  break;

 case5:

  InEnd-=4;

  for(;In

  {

   Out[0]=(int16_t)g726_40_decoder(In[0]>>3,g1);

   Out[1]=(int16_t)g726_40_decoder((In[0]<<2)|(In[1]>>6),g2);

   Out[2]=(int16_t)g726_40_decoder(In[1]>>1,g1);

   Out[3]=(int16_t)g726_40_decoder((In[1]<<4)|(In[2]>>4),g2);

   Out[4]=(int16_t)g726_40_decoder((In[2]<<1)|(In[3]>>7),g1);

   Out[5]=(int16_t)g726_40_decoder(In[3]>>2,g2);

   Out[6]=(int16_t)g726_40_decoder((In[3]<<3)|(In[4]>>5),g1);

   Out[7]=(int16_t)g726_40_decoder(In[4]>>0,g2);

  }

  break;

 }

 break;

 }

 caseADPCM_IMA_QT

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 哲学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1