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