~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/audio/adpcm.c

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /*
  2  * adpcm.c --
  3  *
  4  *      Intel/DVI ADPCM coder/decoder.
  5  */
  6 
  7 /***********************************************************
  8 Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
  9 Netherlands.
 10 
 11                         All Rights Reserved
 12 
 13 Permission to use, copy, modify, and distribute this software and its
 14 documentation for any purpose and without fee is hereby granted,
 15 provided that the above copyright notice appear in all copies and that
 16 both that copyright notice and this permission notice appear in
 17 supporting documentation, and that the names of Stichting Mathematisch
 18 Centrum or CWI not be used in advertising or publicity pertaining to
 19 distribution of the software without specific, written prior permission.
 20 
 21 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
 22 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 23 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
 24 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 25 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 26 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 27 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 28 
 29 ******************************************************************/
 30 
 31 /*
 32 ** Intel/DVI ADPCM coder/decoder.
 33 **
 34 ** The algorithm for this coder was taken from the IMA Compatability Project
 35 ** proceedings, Vol 2, Number 2; May 1992.
 36 **
 37 ** Version 1.1, 16-Dec-92.
 38 **
 39 ** Change log:
 40 ** - Fixed a stupid bug, where the delta was computed as
 41 **   stepsize*code/4 in stead of stepsize*(code+0.5)/4. The old behavior can
 42 **   still be gotten by defining STUPID_V1_BUG.
 43 */
 44 static const char rcsid[] =
 45     "@(#) $Header: /usr/mash/src/repository/mash/mash-1/audio/adpcm.c,v 1.4 2001/04/05 17:17:11 lim Exp $";
 46 
 47 #include "adpcm.h"
 48 
 49 /* Intel ADPCM step variation table */
 50 static int indexTable[16] = {
 51     -1, -1, -1, -1, 2, 4, 6, 8,
 52     -1, -1, -1, -1, 2, 4, 6, 8,
 53 };
 54 
 55 static int stepsizeTable[89] = {
 56     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
 57     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
 58     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
 59     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
 60     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
 61     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
 62     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
 63     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
 64     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
 65 };
 66 
 67 extern short mulawtolin[];
 68 extern unsigned char lintomulaw[];
 69 
 70 void
 71 adpcm_coder(
 72     const unsigned char *inp,
 73     unsigned char *outp,
 74     int len,
 75     struct adpcm_state *state)
 76 {
 77     int val;                    /* Current input sample value */
 78     int sign;                   /* Current adpcm sign bit */
 79     int delta;                  /* Current adpcm output value */
 80     int step;                   /* Stepsize */
 81     int valprev;                /* virtual previous output value */
 82     int vpdiff;                 /* Current change to valprev */
 83     int index;                  /* Current step change index */
 84     int outputbuffer = 0;       /* place to keep previous 4-bit value */
 85     int bufferstep;             /* toggle between outputbuffer/output */
 86 
 87     valprev = state->valprev;
 88     index = state->index;
 89     step = stepsizeTable[index];
 90 
 91     bufferstep = 1;
 92 
 93     while (--len >= 0) {
 94         val = mulawtolin[*inp++];
 95 
 96         /* Step 1 - compute difference with previous value */
 97         delta = val - valprev;
 98         sign = (delta < 0) ? 8 : 0;
 99         if ( sign ) delta = (-delta);
100 
101         /* Step 2 - Divide and clamp */
102 #ifdef sun
103         {
104             int tmp = 0;
105 
106             vpdiff = step >> 3;
107             if ( delta > step ) {
108                 tmp = 4;
109                 delta -= step;
110                 vpdiff += step;
111             }
112             step >>= 1;
113             if ( delta > step  ) {
114                 tmp |= 2;
115                 delta -= step;
116                 vpdiff += step;
117             }
118             step >>= 1;
119             if ( delta > step ) {
120                 tmp |= 1;
121                 vpdiff += step;
122             }
123             delta = tmp;
124         }
125 #else
126         delta = (delta<<2) / step;
127         if ( delta > 7 ) delta = 7;
128 
129         vpdiff = ((delta*step) >> 2) + (step >> 3);
130 #endif
131 
132         /* Step 3 - Update previous value */
133         if ( sign )
134           valprev -= vpdiff;
135         else
136           valprev += vpdiff;
137 
138         /* Step 4 - Clamp previous value to 16 bits */
139         if ( valprev > 32767 )
140           valprev = 32767;
141         else if ( valprev < -32768 )
142           valprev = -32768;
143 
144         /* Step 5 - Assemble value, update index and step values */
145         delta |= sign;
146 
147         index += indexTable[delta];
148         if ( index < 0 ) index = 0;
149         if ( index > 88 ) index = 88;
150         step = stepsizeTable[index];
151 
152         /* Step 6 - Output value */
153         if ( bufferstep ) {
154             outputbuffer = (delta << 4) & 0xf0;
155         } else {
156             *outp++ = (delta & 0x0f) | outputbuffer;
157         }
158         bufferstep = !bufferstep;
159     }
160 
161     /* Output last step, if needed */
162     if ( !bufferstep )
163       *outp++ = outputbuffer;
164 
165     state->valprev = valprev;
166     state->index = index;
167 }
168 
169 void
170 adpcm_decoder(
171     const unsigned char *inp,
172     unsigned char *outp,
173     int len,
174     struct adpcm_state *state)
175 {
176     int sign;                   /* Current adpcm sign bit */
177     int delta;                  /* Current adpcm output value */
178     int step;                   /* Stepsize */
179     int valprev;                /* virtual previous output value */
180     int vpdiff;                 /* Current change to valprev */
181     int index;                  /* Current step change index */
182     int inputbuffer = 0;        /* place to keep next 4-bit value */
183     int bufferstep;             /* toggle between inputbuffer/input */
184 
185     valprev = state->valprev;
186     index = state->index;
187     if ( index < 0 ) index = 0;
188     else if ( index > 88 ) index = 88;
189     step = stepsizeTable[index];
190 
191     bufferstep = 0;
192 
193     for ( ; len > 0 ; len-- ) {
194 
195         /* Step 1 - get the delta value and compute next index */
196         if ( bufferstep ) {
197             delta = inputbuffer & 0xf;
198         } else {
199             inputbuffer = *inp++;
200             delta = (inputbuffer >> 4) & 0xf;
201         }
202         bufferstep = !bufferstep;
203 
204         /* Step 2 - Find new index value (for later) */
205         index += indexTable[delta];
206         if ( index < 0 ) index = 0;
207         else if ( index > 88 ) index = 88;
208 
209         /* Step 3 - Separate sign and magnitude */
210         sign = delta & 8;
211         delta = delta & 7;
212 
213         /* Step 4 - update output value */
214 #ifdef sun
215         vpdiff = step >> 1;
216         if ( delta & 4 ) vpdiff += (step << 2);
217         if ( delta & 2 ) vpdiff += (step << 1);
218         if ( delta & 1 ) vpdiff += step;
219         vpdiff >>= 2;
220 #else
221         vpdiff = ((delta*step) >> 2) + (step >> 3);
222 #endif
223         if ( sign )
224           valprev -= vpdiff;
225         else
226           valprev += vpdiff;
227 
228         /* Step 5 - clamp output value */
229         if ( valprev > 32767 )
230           valprev = 32767;
231         else if ( valprev < -32768 )
232           valprev = -32768;
233 
234         /* Step 6 - Update step value */
235         step = stepsizeTable[index];
236 
237         /* Step 7 - Output value */
238         *outp++ = lintomulaw[(unsigned short)valprev];
239     }
240 
241     state->valprev = valprev;
242     state->index = index;
243 }
244 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.