⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adpcmcodec.cpp

📁 adpcm编码 C语言源程序 可供学习和参考
💻 CPP
字号:
// ADPCMCodec.cpp: implementation of the CADPCMCodec class.
//
//////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ADPCMCodec.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

static int adpcm_coder(short *indata, unsigned char *outdata, int len, adpcm_state *state)
{
	short *inp;			/* Input buffer pointer */
    unsigned char *outp;/* output buffer pointer */
    int val;			/* Current input sample value */
    int sign;			/* Current adpcm sign bit */
    unsigned int delta;	/* Current adpcm output value */
    int diff;			/* Difference between val and valprev */
    unsigned int udiff;    /* unsigned value of diff */
    unsigned int step;	/* Stepsize */
    int valpred;		/* Predicted output value */
    unsigned int vpdiff;/* Current change to valpred */
    int index;			/* Current step change index */
    unsigned int outputbuffer = 0;/* place to keep previous 4-bit value */
    int bufferstep;		/* toggle between outputbuffer/output */
    int count = 0;         /* the number of bytes encoded */
    
    outp = outdata;
    inp = indata;
    
    valpred = state->valprev;
    index = (int)state->index;
    step = stepsizeTable[index];
    
    bufferstep = 1;
    
    while (len-- > 0 ) {
        val = *inp++;
        
        /* Step 1 - compute difference with previous value */
        diff = val - valpred;
        if(diff < 0)
        {
            sign = 8;
            diff = (-diff);
        }
        else
        {
            sign = 0;
        }
        /* diff will be positive at this point */
        udiff = (unsigned int)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 ( udiff >= step ) {
            delta = 4;
            udiff -= step;
            vpdiff += step;
        }
        step >>= 1;
        if ( udiff >= step  ) {
            delta |= 2;
            udiff -= step;
            vpdiff += step;
        }
        step >>= 1;
        if ( udiff >= step ) {
            delta |= 1;
            vpdiff += step;
        }

        /* Phil Frisbie combined steps 3 and 4 */
        /* Step 3 - Update previous value */
        /* Step 4 - Clamp previous value to 16 bits */
        if ( sign != 0 )
        {
            valpred -= vpdiff;
            if ( valpred < -32768 )
                valpred = -32768;
        }
        else
        {
            valpred += vpdiff;
            if ( valpred > 32767 )
                valpred = 32767;
        }

        /* 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 != 0 ) {
            outputbuffer = (delta << 4);
        } else {
            *outp++ = (char)(delta | outputbuffer);
            count++;
        }
        bufferstep = !bufferstep;
    }
    
    /* Output last step, if needed */
    if ( bufferstep == 0 )
    {
        *outp++ = (char)outputbuffer;
        count++;
    }
    
    state->valprev = (short)valpred;
    state->index = (char)index;
    
    return count;

}

static int adpcm_decoder(unsigned char *indata, short *outdata, int len, adpcm_state *state)
{
	unsigned char *inp;	/* Input buffer pointer */
    short *outp;		/* output buffer pointer */
    unsigned int sign;	/* Current adpcm sign bit */
    unsigned int delta;	/* Current adpcm output value */
    unsigned int step;	/* Stepsize */
    int valpred;		/* Predicted value */
    unsigned int vpdiff;/* Current change to valpred */
    int index;			/* Current step change index */
    unsigned int inputbuffer = 0;/* place to keep next 4-bit value */
    int bufferstep;		/* toggle between inputbuffer/input */
    int count = 0;
    
    outp = outdata;
    inp = indata;
    
    valpred = state->valprev;
    index = (int)state->index;
    step = stepsizeTable[index];
    
    bufferstep = 0;
    
    len *= 2;
    
    while ( len-- > 0 ) {
        
        /* Step 1 - get the delta value */
        if ( bufferstep != 0 ) {
            delta = inputbuffer & 0xf;
        } else {
            inputbuffer = (unsigned int)*inp++;
            delta = (inputbuffer >> 4);
        }
        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;
        
        /* Phil Frisbie combined steps 4 and 5 */
        /* Step 4 - Compute difference and new predicted value */
        /* Step 5 - clamp output 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;
            if ( valpred < -32768 )
                valpred = -32768;
        }
        else
        {
            valpred += vpdiff;
            if ( valpred > 32767 )
                valpred = 32767;
        }
        
        /* Step 6 - Update step value */
        step = stepsizeTable[index];
        
        /* Step 7 - Output value */
        *outp++ = (short)valpred;
        count++;
    }
    
    state->valprev = (short)valpred;
    state->index = (char)index;
    
    return count;

}

int EncoderFrame(short *soundInput, unsigned char *soundOutput, DWORD dwSamples,adpcm_state *encoder_state)
{
    //   adpcm_state *encoder_state;
      // unsigned char *   Lpsoudout;
	if ((soundInput == NULL) || (soundOutput == NULL) || (0 == dwSamples))
		return 0;

	if (NULL == encoder_state)
		return 0;
	
	int nEncLen = 0;

	nEncLen = adpcm_coder(soundInput, soundOutput, (int)dwSamples, encoder_state);

//       Lpsoudout =(unsigned char*)malloc(sizeof(char)*(nEncLen+sizeof(DWORD)+sizeof(adpcm_state)));
//	   *(DWORD*)Lpsoudout = nEncLen + sizeof(adpcm_state)+sizeof(DWORD);
        
//	   memcpy(Lpsoudout+sizeof(DWORD),encoder_state,sizeof(encoder_state));
  //        memcpy(Lpsoudout+sizeof(DWORD)+sizeof(adpcm_state),soundOutput,nEncLen);
   //        memcpy(soundOutput,Lpsoudout,nEncLen+sizeof(adpcm_state)+sizeof(DWORD));
	//   soundOutput = Lpsoudout;

	//   free(Lpsoudout);
//	return(nEncLen+sizeof(adpcm_state)+sizeof(DWORD));
        return(nEncLen);
	
}

int DecoderFrame(unsigned char *soundInput, short *soundOutput, DWORD dwSamples,adpcm_state *decoder_state)
{
 //     adpcm_state *decoder_state;  
 //     unsigned char *   Lpsoudin;
//      Lpsoudin = (unsigned char*)malloc(sizeof(char)*dwSamples);
	  
	if ((soundInput == NULL) || (soundOutput == NULL) || (0 == dwSamples))
		return 0;	
   
//       memcpy(&dwSamples,soundInput,sizeof(DWORD));    
//	decoder_state = (adpcm_state*)(soundInput+sizeof(DWORD));
//	memcpy(Lpsoudin,soundInput+sizeof(adpcm_state)+sizeof(DWORD),dwSamples-sizeof(DWORD)-sizeof(adpcm_state));
	
	int nDecLen = 0;
      nDecLen = adpcm_decoder(soundInput, soundOutput, (int)dwSamples, decoder_state);
	  
//	nDecLen = adpcm_decoder(Lpsoudin, soundOutput, (int)dwSamples, decoder_state);
 //      free(Lpsoudin);
	   
	return nDecLen;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -