Flutter Dart ADPCM解码

class adpcm{
/* Intel ADPCM step variation table */
  static final List indexTable = [
    -1, -1, -1, -1, 2, 4, 6, 8,
    -1, -1, -1, -1, 2, 4, 6, 8,
  ];
  static final List stepsizeTable = [
    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
  ];
  List adpcm_decoder(List indata, int len, adpcm_state state)
  {

    int sign;    /* Current adpcm sign bit */
    int delta;   /* Current adpcm output value */
    int step;    /* Stepsize */
    int valpred;  /* Predicted value */
    int vpdiff;    /* Current change to valpred */
    int index;   /* Current step change index */
    int inputbuffer = 0;  /* place to keep next 4-bit value */
    // int bufferstep;  /* toggle between inputbuffer/input */
    int indatai = 0;
    List out = new List(len);
    int outi = 0;
    valpred = state.valprev;
    index = state.index;
    step = stepsizeTable[index];
    bool bufferstep = false;
    for ( ; len > 0 ; len-- ) {

      /* Step 1 - get the delta value */
      if (bufferstep) {
        inputbuffer = indata[indatai++];
        delta = inputbuffer & 0xf;
        bufferstep = false;
      } else {
        delta = (inputbuffer >> 4) & 0xf;
        bufferstep = true;
      }
      /* Step 2 - Find new index value (for later) */
      index += indexTable[delta];
      if ( index < 0 ) index = 0;
      if ( index > 88 ) index = 88;

      /* Step 3 - Separate sign and magnitude */
      sign = delta & 8;
      delta = delta & 7;

      /* Step 4 - Compute difference and new predicted value */
      /*
        ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
        ** in adpcm_coder.
        */
      vpdiff = step >> 3;
      if ( delta & 4 !=0) vpdiff += step;
      if ( delta & 2 !=0) vpdiff += step>>1;
      if ( delta & 1 !=0) vpdiff += step>>2;

      if ( sign!=0 )
        valpred -= vpdiff;
      else
        valpred += vpdiff;

      /* Step 5 - clamp output value */
      if ( valpred > 32767 )
        valpred = 32767;
      else if ( valpred < -32768 )
        valpred = -32768;

      /* Step 6 - Update step value */
      step = stepsizeTable[index];

      /* Step 7 - Output value */
      out[outi++] = valpred;
    }
    return out;
  }
}

// ignore: camel_case_types
class adpcm_state{
  int valprev = 0;
  int index = 0;
}

## 使用代码 outp为最终PCM音频数据

List<int> lis = data;
var len = lis.length;
adpcm ad = new adpcm();
adpcm_state state = new adpcm_state();
state.valprev=valprev;
state.index = index;
List rt = ad.adpcm_decoder(lis, len*2, state);
List<int> outp = new List();
for(var i=0;i<rt.length;i++){
  int low =rt[i] & 0xFF;
  int high = (rt[i]>>8)& 0xFF;
  outp.add(low);
  outp.add(high);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值