ADPCM 算法那里有  请指路

解决方案 »

  1.   

    struct adpcm_state 
    {
      short    valprev;    /* Previous output value */
      char    index;        /* Index into stepsize table */
    };class G721          // ADPCM codec
    {
    public:
      G721();
      ~G721();
      void adpcm_coder(short* indata,char* outdata,int len,
                          adpcm_state* state);
      void adpcm_decoder(char* indata,short* outdata,int len,
                          adpcm_state* state);
    };// adpcm.cpp
    #include "stdafx.h"
    #include "adpcm.h"
    //#include "stdio.h" 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
    };G721::~G721()
    {
      
    }G721::G721()
    {}
        
    void G721::adpcm_coder(short* indata,char* outdata,int len,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 
          ** 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 &brvbar;= 2;
            diff -= step;
            vpdiff += step;
          }
          step >>= 1;
          if(diff >= step) 
          {
            delta &brvbar;= 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 &brvbar;= 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) &brvbar; outputbuffer;
          }
          bufferstep = !bufferstep;
        }
        /* Output last step, if needed */
        if(!bufferstep)
          *outp++ = outputbuffer;
        state->valprev = valpred;
        state->index = index;
    }void G721::adpcm_decoder(char* indata,short* outdata,int len,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;
    }