📄 adpcm.sh
字号:
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 + -