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

📄 adpcm0.c

📁 基于TI xdais算法标准的音频ADPCM算法
💻 C
字号:

/***********************************************************
Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
******************************************************************/

/*
** Intel/DVI ADPCM coder/decoder.
**
** The algorithm for this coder was taken from the IMA Compatability Project
** proceedings, Vol 2, Number 2; May 1992.
**
** Version 1.2, 18-Dec-92.
**
*/

#include "adpcm.h"
#include <stdio.h>

#ifndef __STDC__
#define signed
#endif


/* 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
};
    
void adpcm_encoder(short *indata, char *outdata, short len, adpcm_state *state)
/* *indata输入数据指针,*output输出数据指针,len输入数据长度,*state之前状态结构体指针*/
{
    short *inp;			/* Input buffer pointer 输入缓存指针*/
    signed char *outp;	/* output buffer pointer 输出缓存指针*/
    //int val;			/* Current input sample value 当前采样值*/
    short val;
    int sign;			/* Current adpcm sign bit 当前adpcm编码值符号位*/
    int delta;			/* Current adpcm output value 当前编码输出值*/
    int diff;			/* Difference between val and valprev 编码输出值与之前值得差*/
    int step;			/* Stepsize ??*/
    //int valpred;		/* Predicted output value 预计输出值*/
    short valpred;
    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;/*输出缓存指针=(signed char *)outdata*/
    inp = indata;/*输入缓存指针=(signed char *)indata*/

    valpred = state->valprev;/*预计输出值=之前输出值*/
    index = state->index;/*index=之前的index*/
    step = stepsizeTable[index];/*step=stepsizeTable[index]*/
    
    bufferstep = 1;

    for ( ; len > 0 ; len-- ) {
    {
    	if(bufferstep)
			val = *inp++;
		else
		{
			val = *inp;
			inp=inp+7;
        }
	/* Step 1 - compute difference with previous value 估算差值*/
		diff = val - valpred;
		sign = (diff < 0) ? 8 : 0;
	/*差值diff<0,sign=8即当前值小于之前值,否则sign=0即当前值大于等于之前值*/
		if ( sign ) diff = (-diff);/*如果sign=!0 diff取绝对值*/

	/* Step 2 - Divide and clamp */
	/* Note:
	** This code *approximately* computes:
	**    delta = diff*4/step;预测值=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;//应为16bit?
			  }
			
			bufferstep = !bufferstep;
    }

    /* Output last step, if needed */
    /*if ( !bufferstep )
      *outp++ = outputbuffer;*/
    
    	state->valprev = valpred;
    	state->index = index;
    }
    
}

void adpcm_decoder(char *indata, short *outdata, short 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;
		}
		
		

		/* 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 */
    	if ( bufferstep ){
			*outp = valpred;
			outp=outp+15;
		}
		else
		*outp++ = valpred;  	
		    
    	bufferstep = !bufferstep;
    }

    state->valprev = valpred;
    state->index = index;
    
    //write to file
    //fwrite(outdata, 1, len, fpDecoder);
}

⌨️ 快捷键说明

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