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
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.