adpcm 转换wave

11 篇文章 0 订阅

项目中使用了ffmpeg做留影留言,由于ffmpeg一直到该平台式使用了adpcm压缩声音,所以录制的avi文件播放出来时需要将adpcm编码的声音解码出来,为此,移植了adpcm的解码器。

实现如下:

struct adpcm_state
{
short valprev; /* Previous output value */
char index; /* Index into stepsize table */
};

/* Intel ADPCM step variation table */
static int indexTable[16] = {
    -1, -1, -1, -1, 2, 4, 6, 8,
    -1, -1, -1, -1, 2, 4, 6, 8,
};

static int stepsizeTable[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
};

 

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

Function:使用adpcm解码将四位的压缩数据还原成16位pcm

Author:Ericjiang

Input:inbuff:要解码的数据;outbuff:已解码数据,len_of_in:输入的编码数据长度;state:上一次编码使用的编码值和索引(开始都赋值为0)

Ouput:

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

void adpcm_decoder(char *inbuff,char *outbuff,int len_of_in,struct adpcm_state * state )
{
 int  i=0,j=0;
 char tmp_data;
 struct adpcm_state * tmp_state =state;
 signed long diff; /* Difference between sample and predicted sample */
 long step; /* Quantizer step size */
 signed long predsample; /* Output of ADPCM predictor */
 signed long diffq; /* Dequantized predicted difference */
 int index; /* Index into step size table */
 int indexa,indexb;

 int Samp;
 unsigned char SampH, SampL;
 unsigned char inCode; 
 
 /* Restore previous values of predicted sample and quantizer step
 size index
 */
 predsample = state->valprev;
 index = state->index;
 
 for(i=0;i<len_of_in*2;i++)
  {
   tmp_data=inbuff[i/2];  
   if(i%2)
    inCode=(tmp_data& 0xf0) >> 4;
   else
    inCode=tmp_data & 0x0f;
   {
    
    step = stepsizeTable[index];
    /* Inverse quantize the ADPCM code into a predicted difference
    using the quantizer step size
    */
    
    diffq = step >> 3;
    if( inCode & 4 )
    diffq += step;
    if( inCode & 2 )
    diffq += step >> 1;
    if( inCode & 1 )
    diffq += step >> 2;
    /* Fixed predictor computes new predicted sample by adding the
    old predicted sample to predicted difference
    */
    if( inCode & 8 )
    predsample -= diffq;
    else
    predsample += diffq;
    /* Check for overflow of the new predicted sample
    */
    if( predsample > 32767 )
    predsample = 32767;
    else if( predsample < -32768 )
    predsample = -32768;
    /* Find new quantizer stepsize index by adding the old index
    to a table lookup using the ADPCM code
    */
    index += indexTable[inCode];
    /* Check for overflow of the new quantizer step size index
    */
    if( index < 0 )
    index = 0;
    if( index > 88 )
    index = 88;
    /* Return the new ADPCM code */
    Samp=predsample;
    
   
   }
   if (Samp >= 0)
    {
    SampH=Samp / 256;
    SampL = Samp - 256 * SampH;
    }
   else
    {
    Samp= 32768+Samp;
    SampH = Samp / 256;
    SampL = Samp - 256 * SampH;
    SampH += 0x80;
    }
   outbuff[j++]=SampL;
   outbuff[j++]=SampH;   
  }
 
 /* Save the predicted sample and quantizer step size index for
 next iteration
 */
 state->valprev  = predsample;
 state->index  = index;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值