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

Open Mash Cross Reference
mash/codec/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 
 45 #include "adpcm.h"
 46 
 47 /* Intel ADPCM step variation table */
 48 static int indexTable[16] = {
 49     -1, -1, -1, -1, 2, 4, 6, 8,
 50     -1, -1, -1, -1, 2, 4, 6, 8,
 51 };
 52 
 53 static int stepsizeTable[89] = {
 54     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
 55     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
 56     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
 57     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
 58     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
 59     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
 60     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
 61     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
 62     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
 63 };
 64 
 65 extern short mulawtolin[];
 66 extern unsigned char lintomulaw[];
 67 
 68 void
 69 adpcm_coder(
 70     const unsigned char *inp,
 71     unsigned char *outp,
 72     int len,
 73     struct adpcm_state *state)
 74 {
 75     int val;                    /* Current input sample value */
 76     int sign;                   /* Current adpcm sign bit */
 77     int delta;                  /* Current adpcm output value */
 78     int step;                   /* Stepsize */
 79     int valprev;                /* virtual previous output value */
 80     int vpdiff;                 /* Current change to valprev */
 81     int index;                  /* Current step change index */
 82     int outputbuffer;           /* place to keep previous 4-bit value */
 83     int bufferstep;             /* toggle between outputbuffer/output */
 84 
 85     valprev = state->valprev;
 86     index = state->index;
 87     step = stepsizeTable[index];
 88 
 89     bufferstep = 1;
 90 
 91     while (--len >= 0) {
 92         val = mulawtolin[*inp++];
 93 
 94         /* Step 1 - compute difference with previous value */
 95         delta = val - valprev;
 96         sign = (delta < 0) ? 8 : 0;
 97         if ( sign ) delta = (-delta);
 98 
 99         /* Step 2 - Divide and clamp */
100 #ifdef sun
101         {
102             int tmp = 0;
103 
104             vpdiff = step >> 3;
105             if ( delta > step ) {
106                 tmp = 4;
107                 delta -= step;
108                 vpdiff += step;
109             }
110             step >>= 1;
111             if ( delta > step  ) {
112                 tmp |= 2;
113                 delta -= step;
114                 vpdiff += step;
115             }
116             step >>= 1;
117             if ( delta > step ) {
118                 tmp |= 1;
119                 vpdiff += step;
120             }
121             delta = tmp;
122         }
123 #else
124         delta = (delta<<2) / step;
125         if ( delta > 7 ) delta = 7;
126 
127         vpdiff = ((delta*step) >> 2) + (step >> 3);
128 #endif
129 
130         /* Step 3 - Update previous value */
131         if ( sign )
132           valprev -= vpdiff;
133         else
134           valprev += vpdiff;
135 
136         /* Step 4 - Clamp previous value to 16 bits */
137         if ( valprev > 32767 )
138           valprev = 32767;
139         else if ( valprev < -32768 )
140           valprev = -32768;
141 
142         /* Step 5 - Assemble value, update index and step values */
143         delta |= sign;
144 
145         index += indexTable[delta];
146         if ( index < 0 ) index = 0;
147         if ( index > 88 ) index = 88;
148         step = stepsizeTable[index];
149 
150         /* Step 6 - Output value */
151         if ( bufferstep ) {
152             outputbuffer = (delta << 4) & 0xf0;
153         } else {
154             *outp++ = (delta & 0x0f) | outputbuffer;
155         }
156         bufferstep = !bufferstep;
157     }
158 
159     /* Output last step, if needed */
160     if ( !bufferstep )
161       *outp++ = outputbuffer;
162 
163     state->valprev = valprev;
164     state->index = index;
165 }
166 
167 void
168 adpcm_decoder(
169     const unsigned char *inp,
170     unsigned char *outp,
171     int len,
172     struct adpcm_state *state)
173 {
174     int sign;                   /* Current adpcm sign bit */
175     int delta;                  /* Current adpcm output value */
176     int step;                   /* Stepsize */
177     int valprev;                /* virtual previous output value */
178     int vpdiff;                 /* Current change to valprev */
179     int index;                  /* Current step change index */
180     int inputbuffer;            /* place to keep next 4-bit value */
181     int bufferstep;             /* toggle between inputbuffer/input */
182 
183     valprev = state->valprev;
184     index = state->index;
185     if ( index < 0 ) index = 0;
186     else if ( index > 88 ) index = 88;
187     step = stepsizeTable[index];
188 
189     bufferstep = 0;
190 
191     for ( ; len > 0 ; len-- ) {
192 
193         /* Step 1 - get the delta value and compute next index */
194         if ( bufferstep ) {
195             delta = inputbuffer & 0xf;
196         } else {
197             inputbuffer = *inp++;
198             delta = (inputbuffer >> 4) & 0xf;
199         }
200         bufferstep = !bufferstep;
201 
202         /* Step 2 - Find new index value (for later) */
203         index += indexTable[delta];
204         if ( index < 0 ) index = 0;
205         else if ( index > 88 ) index = 88;
206 
207         /* Step 3 - Separate sign and magnitude */
208         sign = delta & 8;
209         delta = delta & 7;
210 
211         /* Step 4 - update output value */
212 #ifdef sun
213         vpdiff = step >> 1;
214         if ( delta & 4 ) vpdiff += (step << 2);
215         if ( delta & 2 ) vpdiff += (step << 1);
216         if ( delta & 1 ) vpdiff += step;
217         vpdiff >>= 2;
218 #else
219         vpdiff = ((delta*step) >> 2) + (step >> 3);
220 #endif
221         if ( sign )
222           valprev -= vpdiff;
223         else
224           valprev += vpdiff;
225 
226         /* Step 5 - clamp output value */
227         if ( valprev > 32767 )
228           valprev = 32767;
229         else if ( valprev < -32768 )
230           valprev = -32768;
231 
232         /* Step 6 - Update step value */
233         step = stepsizeTable[index];
234 
235         /* Step 7 - Output value */
236         *outp++ = lintomulaw[(unsigned short)valprev];
237     }
238 
239     state->valprev = valprev;
240     state->index = index;
241 }
242 

~ [ 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.