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

📄 adpcm.sh

📁 ADPCM 4:1 coder and decoder
💻 SH
📖 第 1 页 / 共 2 页
字号:
X    int step;			/* Stepsize */
X    int valprev;		/* virtual previous output value */
X    int vpdiff;			/* Current change to valprev */
X    int index;			/* Current step change index */
X    int outputbuffer;		/* place to keep previous 4-bit value */
X    int bufferstep;		/* toggle between outputbuffer/output */
X
X    outp = (signed char *)outdata;
X    inp = indata;
X
X    valprev = state->valprev;
X    index = state->index;
X    step = stepsizeTable[index];
X    
X    bufferstep = 1;
X
X    for ( ; len > 0 ; len-- ) {
X	val = *inp++;
X
X	/* Step 1 - compute difference with previous value */
X	delta = val - valprev;
X	sign = (delta < 0) ? 8 : 0;
X	if ( sign ) delta = (-delta);
X
X	/* Step 2 - Divide and clamp */
X#ifdef NODIVMUL
X        {
X	    int tmp = 0;
X
X	    vpdiff = 0;
X	    if ( delta > step ) {
X		tmp = 4;
X		delta -= step;
X		vpdiff = step;
X	    }
X	    step >>= 1;
X	    if ( delta > step  ) {
X		tmp |= 2;
X		delta -= step;
X		vpdiff += step;
X	    }
X	    step >>= 1;
X	    if ( delta > step ) {
X		tmp |= 1;
X		vpdiff += step;
X	    }
X	    delta = tmp;
X	}
X#else
X	delta = (delta<<2) / step;
X	if ( delta > 7 ) delta = 7;
X
X	vpdiff = (delta*step) >> 2;
X#endif
X	  
X	/* Step 3 - Update previous value */
X	if ( sign )
X	  valprev -= vpdiff;
X	else
X	  valprev += vpdiff;
X
X	/* Step 4 - Clamp previous value to 16 bits */
X	if ( valprev > 32767 )
X	  valprev = 32767;
X	else if ( valprev < -32768 )
X	  valprev = -32768;
X
X	/* Step 5 - Assemble value, update index and step values */
X	delta |= sign;
X	
X	index += indexTable[delta];
X	if ( index < 0 ) index = 0;
X	if ( index > 88 ) index = 88;
X	step = stepsizeTable[index];
X
X	/* Step 6 - Output value */
X	if ( bufferstep ) {
X	    outputbuffer = (delta << 4) & 0xf0;
X	} else {
X	    *outp++ = (delta & 0x0f) | outputbuffer;
X	}
X	bufferstep = !bufferstep;
X    }
X
X    /* Output last step, if needed */
X    if ( !bufferstep )
X      *outp++ = outputbuffer;
X    
X    state->valprev = valprev;
X    state->index = index;
X}
X
Xvoid
Xadpcm_decoder(indata, outdata, len, state)
X    char indata[];
X    short outdata[];
X    int len;
X    struct adpcm_state *state;
X{
X    signed char *inp;		/* Input buffer pointer */
X    short *outp;		/* output buffer pointer */
X    int sign;			/* Current adpcm sign bit */
X    int delta;			/* Current adpcm output value */
X    int step;			/* Stepsize */
X    int valprev;		/* virtual previous output value */
X    int vpdiff;			/* Current change to valprev */
X    int index;			/* Current step change index */
X    int inputbuffer;		/* place to keep next 4-bit value */
X    int bufferstep;		/* toggle between inputbuffer/input */
X
X    outp = outdata;
X    inp = (signed char *)indata;
X
X    valprev = state->valprev;
X    index = state->index;
X    step = stepsizeTable[index];
X
X    bufferstep = 0;
X    
X    for ( ; len > 0 ; len-- ) {
X	
X	/* Step 1 - get the delta value and compute next index */
X	if ( bufferstep ) {
X	    delta = inputbuffer & 0xf;
X	} else {
X	    inputbuffer = *inp++;
X	    delta = (inputbuffer >> 4) & 0xf;
X	}
X	bufferstep = !bufferstep;
X
X	/* Step 2 - Find new index value (for later) */
X	index += indexTable[delta];
X	if ( index < 0 ) index = 0;
X	if ( index > 88 ) index = 88;
X
X	/* Step 3 - Separate sign and magnitude */
X	sign = delta & 8;
X	delta = delta & 7;
X
X	/* Step 4 - update output value */
X#ifdef NODIVMUL
X	vpdiff = 0;
X	if ( delta & 4 ) vpdiff  = (step << 2);
X	if ( delta & 2 ) vpdiff += (step << 1);
X	if ( delta & 1 ) vpdiff += step;
X	vpdiff >>= 2;
X#else
X	vpdiff = (delta*step) >> 2;
X#endif
X	if ( sign )
X	  valprev -= vpdiff;
X	else
X	  valprev += vpdiff;
X
X	/* Step 5 - clamp output value */
X	if ( valprev > 32767 )
X	  valprev = 32767;
X	else if ( valprev < -32768 )
X	  valprev = -32768;
X
X	/* Step 6 - Update step value */
X	step = stepsizeTable[index];
X
X	/* Step 7 - Output value */
X	*outp++ = valprev;
X    }
X
X    state->valprev = valprev;
X    state->index = index;
X}
END_OF_FILE
if test 6342 -ne `wc -c <'adpcm.c'`; then
    echo shar: \"'adpcm.c'\" unpacked with wrong size!
fi
# end of 'adpcm.c'
fi
if test -f 'testc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'testc.c'\"
else
echo shar: Extracting \"'testc.c'\" \(485 characters\)
sed "s/^X//" >'testc.c' <<'END_OF_FILE'
X/* testc - Test adpcm coder */
X
X#include "adpcm.h"
X#include <stdio.h>
X
Xstruct adpcm_state state;
X
X#define NSAMPLES 1000
X
Xchar	abuf[NSAMPLES/2];
Xshort	sbuf[NSAMPLES];
X
Xmain() {
X    int n;
X
X    while(1) {
X	n = read(0, sbuf, NSAMPLES*2);
X	if ( n < 0 ) {
X	    perror("input file");
X	    exit(1);
X	}
X	if ( n == 0 ) break;
X	adpcm_coder(sbuf, abuf, n/2, &state);
X	write(1, abuf, n/4);
X    }
X    fprintf(stderr, "Final valprev=%d, index=%d\n",
X	    state.valprev, state.index);
X    exit(0);
X}
END_OF_FILE
if test 485 -ne `wc -c <'testc.c'`; then
    echo shar: \"'testc.c'\" unpacked with wrong size!
fi
# end of 'testc.c'
fi
if test -f 'testd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'testd.c'\"
else
echo shar: Extracting \"'testd.c'\" \(489 characters\)
sed "s/^X//" >'testd.c' <<'END_OF_FILE'
X/* testd - Test adpcm decoder */
X
X#include "adpcm.h"
X#include <stdio.h>
X
Xstruct adpcm_state state;
X
X#define NSAMPLES 1000
X
Xchar	abuf[NSAMPLES/2];
Xshort	sbuf[NSAMPLES];
X
Xmain() {
X    int n;
X
X    while(1) {
X	n = read(0, abuf, NSAMPLES/2);
X	if ( n < 0 ) {
X	    perror("input file");
X	    exit(1);
X	}
X	if ( n == 0 ) break;
X	adpcm_decoder(abuf, sbuf, n*2, &state);
X	write(1, sbuf, n*4);
X    }
X    fprintf(stderr, "Final valprev=%d, index=%d\n",
X	    state.valprev, state.index);
X    exit(0);
X}
END_OF_FILE
if test 489 -ne `wc -c <'testd.c'`; then
    echo shar: \"'testd.c'\" unpacked with wrong size!
fi
# end of 'testd.c'
fi
echo shar: End of shell archive.
exit 0
-- 
Mark T. Price (sg)           mark@godzilla.Quotron.COM
>plan 9 studios<             "Bite me, it's fun!" -- Crow, MST 3000


⌨️ 快捷键说明

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