<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > adpcm音頻壓縮算法源代碼

          adpcm音頻壓縮算法源代碼

          作者: 時間:2017-06-04 來源:網(wǎng)絡(luò) 收藏


          #include stdio.h>

          本文引用地址:http://www.ex-cimer.com/article/201706/348587.htm

          #ifndef __STDC__
          #define signed
          #endif

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

          /*-------------adpcm_ecoder---------------------------------------------*/
          void
          adpcm_coder(indata, outdata, len, state)
          short indata[];
          char outdata[];
          int len;
          struct adpcm_state *state;
          {
          short *inp;/* Input buffer pointer */
          signed char *outp;/* output buffer pointer */
          int val;/* Current input sample value */
          int sign;/* Current adpcm sign bit */
          int delta;/* Current adpcm output value */
          int diff;/* Difference between val and valprev */
          int step;/* Stepsize */
          int valpred;/* Predicted output value */
          int vpdiff;/* Current change to valpred */
          int index;/* Current step change index */
          int outputbuffer;/* place to keep previous 4-bit value */
          int bufferstep;/* toggle between outputbuffer/output */

          outp = (signed char *)outdata;
          inp = indata;

          valpred = state->valprev;
          index = state->index;
          step = stepsizeTable[index];

          bufferstep = 1;

          for ( ; len > 0 ; len-- ) {
          val = *inp++;

          /* Step 1 - compute difference with previous value */
          diff = val - valpred;
          sign = (diff 0) ? 8 : 0;
          if ( sign ) diff = (-diff);

          /* Step 2 - Divide and clamp */
          /* Note:
          ** This code *approximately* computes:
          ** delta = diff*4/step;
          ** vpdiff = (delta+0.5)*step/4;
          ** but in shift step bits are dropped. The net result of this is
          ** that even if you have fast mul/div hardware you cannot put it to
          ** good use since the fixup would be too expensive.
          */
          delta = 0;
          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;
          }

          /* Step 3 - Update previous value */
          if ( sign )
          valpred -= vpdiff;
          else
          valpred += vpdiff;

          /* Step 4 - Clamp previous value to 16 bits */
          if ( valpred > 32767 )
          valpred = 32767;
          else if ( valpred -32768 )
          valpred = -32768;

          /* Step 5 - Assemble value, update index and step values */
          delta |= sign;

          index += indexTable[delta];
          if ( index 0 ) index = 0;
          if ( index > 88 ) index = 88;
          step = stepsizeTable[index];

          /* Step 6 - Output value */
          if ( bufferstep ) {
          outputbuffer = (delta 4) 0xf0;
          } else {
          *outp++ = (delta 0x0f) | outputbuffer;
          }
          bufferstep = !bufferstep;
          }

          /* Output last step, if needed */
          if ( !bufferstep )
          *outp++ = outputbuffer;

          state->valprev = valpred;
          state->index = index;
          }


          /*-------------adpcm_decoder---------------------------------------------*/
          void
          adpcm_decoder(indata, outdata, len, state)
          char indata[];
          short outdata[];
          int len;
          struct adpcm_state *state;
          {
          signed char *inp;/* Input buffer pointer */
          short *outp;/* output buffer pointer */
          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;/* place to keep next 4-bit value */
          int bufferstep;/* toggle between inputbuffer/input */

          outp = outdata;
          inp = (signed char *)indata;

          valpred = state->valprev;
          index = state->index;
          step = stepsizeTable[index];

          bufferstep = 0;

          for ( ; len > 0 ; len-- ) {

          /* Step 1 - get the delta value */
          if ( bufferstep ) {
          delta = inputbuffer 0xf;
          } else {
          inputbuffer = *inp++;
          delta = (inputbuffer >> 4) 0xf;
          }
          bufferstep = !bufferstep;

          /* 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 ) vpdiff += step;
          if ( delta 2 ) vpdiff += step>>1;
          if ( delta 1 ) vpdiff += step>>2;

          if ( sign )
          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 */
          *outp++ = valpred;
          }

          state->valprev = valpred;
          state->index = index;
          }



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();