Mercurial > mplayer.hg
annotate adpcm.c @ 4833:395844d9d5d6
fixes bug in alban's new input handling code that caused the terminal
state to get trashed and not restored on exit. hopefully this change
won't interfere with the functionality of the new code; as far as i
can tell it seems to work fine.
author | rfelker |
---|---|
date | Sun, 24 Feb 2002 04:56:54 +0000 |
parents | ae6f97724b84 |
children | 4a6dde59834c |
rev | line source |
---|---|
3756 | 1 /* |
2 Unified ADPCM Decoder for MPlayer | |
3 | |
3787 | 4 This file is in charge of decoding all of the various ADPCM data |
5 formats that various entities have created. Details about the data | |
6 formats can be found here: | |
7 http://www.pcisys.net/~melanson/codecs/ | |
8 | |
3756 | 9 (C) 2001 Mike Melanson |
10 */ | |
11 | |
12 #include "config.h" | |
13 #include "bswap.h" | |
14 #include "adpcm.h" | |
15 | |
16 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) | |
17 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) | |
18 #define LE_16(x) (le2me_16(*(unsigned short *)(x))) | |
19 #define LE_32(x) (le2me_32(*(unsigned int *)(x))) | |
20 | |
3787 | 21 // pertinent tables |
22 static int adpcm_step[89] = | |
23 { | |
24 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, | |
25 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, | |
26 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, | |
27 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, | |
28 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, | |
29 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, | |
30 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, | |
31 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | |
32 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 | |
33 }; | |
34 | |
35 static int adpcm_index[16] = | |
36 { | |
37 -1, -1, -1, -1, 2, 4, 6, 8, | |
38 -1, -1, -1, -1, 2, 4, 6, 8 | |
39 }; | |
40 | |
41 static int ms_adapt_table[] = | |
42 { | |
43 230, 230, 230, 230, 307, 409, 512, 614, | |
44 768, 614, 512, 409, 307, 230, 230, 230 | |
45 }; | |
46 | |
47 static int ms_adapt_coeff1[] = | |
48 { | |
49 256, 512, 0, 192, 240, 460, 392 | |
50 }; | |
51 | |
52 static int ms_adapt_coeff2[] = | |
53 { | |
54 0, -256, 0, 64, 0, -208, -232 | |
55 }; | |
56 | |
57 // useful macros | |
3756 | 58 // clamp a number between 0 and 88 |
59 #define CLAMP_0_TO_88(x) if (x < 0) x = 0; else if (x > 88) x = 88; | |
60 // clamp a number within a signed 16-bit range | |
61 #define CLAMP_S16(x) if (x < -32768) x = -32768; \ | |
62 else if (x > 32767) x = 32767; | |
3787 | 63 // clamp a number above 16 |
64 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16; | |
3756 | 65 // sign extend a 16-bit value |
66 #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; | |
3787 | 67 // sign extend a 4-bit value |
68 #define SE_4BIT(x) if (x & 0x8) x -= 0x10; | |
3756 | 69 |
3939 | 70 void decode_nibbles(unsigned short *output, |
71 int output_size, int channels, | |
3756 | 72 int predictor_l, int index_l, |
73 int predictor_r, int index_r) | |
74 { | |
75 int step[2]; | |
76 int predictor[2]; | |
77 int index[2]; | |
78 int diff; | |
79 int i; | |
80 int sign; | |
81 int delta; | |
82 int channel_number = 0; | |
83 | |
84 step[0] = adpcm_step[index_l]; | |
85 step[1] = adpcm_step[index_r]; | |
86 predictor[0] = predictor_l; | |
87 predictor[1] = predictor_r; | |
88 index[0] = index_l; | |
89 index[1] = index_r; | |
90 | |
3939 | 91 for (i = 0; i < output_size; i++) |
3756 | 92 { |
93 delta = output[i]; | |
94 | |
95 index[channel_number] += adpcm_index[delta]; | |
96 CLAMP_0_TO_88(index[channel_number]); | |
97 | |
98 sign = delta & 8; | |
99 delta = delta & 7; | |
100 | |
101 diff = step[channel_number] >> 3; | |
102 if (delta & 4) diff += step[channel_number]; | |
103 if (delta & 2) diff += step[channel_number] >> 1; | |
104 if (delta & 1) diff += step[channel_number] >> 2; | |
105 | |
106 if (sign) | |
107 predictor[channel_number] -= diff; | |
108 else | |
109 predictor[channel_number] += diff; | |
110 | |
111 CLAMP_S16(predictor[channel_number]); | |
112 output[i] = predictor[channel_number]; | |
113 step[channel_number] = adpcm_step[index[channel_number]]; | |
114 | |
115 // toggle channel | |
116 channel_number ^= channels - 1; | |
3939 | 117 |
3756 | 118 } |
119 } | |
120 | |
121 int ima_adpcm_decode_block(unsigned short *output, unsigned char *input, | |
122 int channels) | |
123 { | |
124 int initial_predictor_l = 0; | |
125 int initial_predictor_r = 0; | |
126 int initial_index_l = 0; | |
127 int initial_index_r = 0; | |
128 int i; | |
129 | |
3763 | 130 initial_predictor_l = BE_16(&input[0]); |
3756 | 131 initial_index_l = initial_predictor_l; |
132 | |
133 // mask, sign-extend, and clamp the predictor portion | |
134 initial_predictor_l &= 0xFF80; | |
135 SE_16BIT(initial_predictor_l); | |
136 CLAMP_S16(initial_predictor_l); | |
137 | |
138 // mask and clamp the index portion | |
139 initial_index_l &= 0x7F; | |
140 CLAMP_0_TO_88(initial_index_l); | |
141 | |
142 // handle stereo | |
143 if (channels > 1) | |
144 { | |
3763 | 145 initial_predictor_r = BE_16(&input[IMA_ADPCM_BLOCK_SIZE]); |
3756 | 146 initial_index_r = initial_predictor_r; |
147 | |
148 // mask, sign-extend, and clamp the predictor portion | |
149 initial_predictor_r &= 0xFF80; | |
150 SE_16BIT(initial_predictor_r); | |
151 CLAMP_S16(initial_predictor_r); | |
152 | |
153 // mask and clamp the index portion | |
154 initial_index_r &= 0x7F; | |
155 CLAMP_0_TO_88(initial_index_r); | |
156 } | |
157 | |
158 // break apart all of the nibbles in the block | |
159 if (channels == 1) | |
160 for (i = 0; i < IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++) | |
161 { | |
3763 | 162 output[i * 2 + 0] = input[2 + i] & 0x0F; |
163 output[i * 2 + 1] = input[2 + i] >> 4; | |
3756 | 164 } |
165 else | |
166 for (i = 0; i < IMA_ADPCM_SAMPLES_PER_BLOCK / 2 * 2; i++) | |
167 { | |
3763 | 168 output[i * 4 + 0] = input[2 + i] & 0x0F; |
169 output[i * 4 + 1] = input[2 + IMA_ADPCM_BLOCK_SIZE + i] & 0x0F; | |
170 output[i * 4 + 2] = input[2 + i] >> 4; | |
171 output[i * 4 + 3] = input[2 + IMA_ADPCM_BLOCK_SIZE + i] >> 4; | |
3756 | 172 } |
173 | |
3939 | 174 decode_nibbles(output, |
175 IMA_ADPCM_SAMPLES_PER_BLOCK * channels, channels, | |
3756 | 176 initial_predictor_l, initial_index_l, |
177 initial_predictor_r, initial_index_r); | |
178 | |
179 return IMA_ADPCM_SAMPLES_PER_BLOCK * channels; | |
180 } | |
3787 | 181 |
182 int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, | |
3875
e3caff2daa98
fixed stereo MS ADPCM decoder and reinstated opensource decoder as the
melanson
parents:
3826
diff
changeset
|
183 int channels, int block_size) |
3787 | 184 { |
185 int current_channel = 0; | |
186 int idelta[2]; | |
187 int sample1[2]; | |
188 int sample2[2]; | |
189 int coeff1[2]; | |
190 int coeff2[2]; | |
191 int stream_ptr = 0; | |
192 int out_ptr = 0; | |
193 int upper_nibble = 1; | |
194 int nibble; | |
195 int snibble; // signed nibble | |
196 int predictor; | |
197 | |
198 // fetch the header information, in stereo if both channels are present | |
199 coeff1[0] = ms_adapt_coeff1[input[stream_ptr]]; | |
200 coeff2[0] = ms_adapt_coeff2[input[stream_ptr]]; | |
201 stream_ptr++; | |
202 if (channels == 2) | |
203 { | |
204 coeff1[1] = ms_adapt_coeff1[input[stream_ptr]]; | |
205 coeff2[1] = ms_adapt_coeff2[input[stream_ptr]]; | |
206 stream_ptr++; | |
207 } | |
208 | |
209 idelta[0] = LE_16(&input[stream_ptr]); | |
210 stream_ptr += 2; | |
211 SE_16BIT(idelta[0]); | |
212 if (channels == 2) | |
213 { | |
214 idelta[1] = LE_16(&input[stream_ptr]); | |
215 stream_ptr += 2; | |
216 SE_16BIT(idelta[1]); | |
217 } | |
218 | |
219 sample1[0] = LE_16(&input[stream_ptr]); | |
220 stream_ptr += 2; | |
221 SE_16BIT(sample1[0]); | |
222 if (channels == 2) | |
223 { | |
224 sample1[1] = LE_16(&input[stream_ptr]); | |
225 stream_ptr += 2; | |
226 SE_16BIT(sample1[1]); | |
227 } | |
228 | |
229 sample2[0] = LE_16(&input[stream_ptr]); | |
230 stream_ptr += 2; | |
231 SE_16BIT(sample2[0]); | |
232 if (channels == 2) | |
233 { | |
234 sample2[1] = LE_16(&input[stream_ptr]); | |
235 stream_ptr += 2; | |
236 SE_16BIT(sample2[1]); | |
237 } | |
238 | |
3875
e3caff2daa98
fixed stereo MS ADPCM decoder and reinstated opensource decoder as the
melanson
parents:
3826
diff
changeset
|
239 while (stream_ptr < block_size) |
3787 | 240 { |
241 // get the next nibble | |
242 if (upper_nibble) | |
243 nibble = snibble = input[stream_ptr] >> 4; | |
244 else | |
245 nibble = snibble = input[stream_ptr++] & 0x0F; | |
246 upper_nibble ^= 1; | |
247 SE_4BIT(snibble); | |
248 | |
249 predictor = ( | |
250 ((sample1[current_channel] * coeff1[current_channel]) + | |
251 (sample2[current_channel] * coeff2[current_channel])) / 256) + | |
252 (snibble * idelta[current_channel]); | |
253 CLAMP_S16(predictor); | |
254 sample2[current_channel] = sample1[current_channel]; | |
255 sample1[current_channel] = predictor; | |
256 output[out_ptr++] = predictor; | |
257 | |
258 // compute the next adaptive scale factor (a.k.a. the variable idelta) | |
259 idelta[current_channel] = | |
260 (ms_adapt_table[nibble] * idelta[current_channel]) / 256; | |
261 CLAMP_ABOVE_16(idelta[current_channel]); | |
262 | |
263 // toggle the channel | |
264 current_channel ^= channels - 1; | |
265 } | |
266 | |
3875
e3caff2daa98
fixed stereo MS ADPCM decoder and reinstated opensource decoder as the
melanson
parents:
3826
diff
changeset
|
267 return (block_size - (MS_ADPCM_PREAMBLE_SIZE * channels)) * 2; |
3787 | 268 } |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
269 |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
270 // note: This decoder assumes the format 0x61 data always comes in |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
271 // mono flavor |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
272 int fox61_adpcm_decode_block(unsigned short *output, unsigned char *input) |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
273 { |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
274 int i; |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
275 int predictor; |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
276 int index; |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
277 |
3939 | 278 // the first predictor value goes straight to the output |
279 predictor = output[0] = LE_16(&input[0]); | |
280 SE_16BIT(predictor); | |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
281 index = input[2]; |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
282 |
3939 | 283 // unpack the nibbles |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
284 for (i = 4; i < FOX61_ADPCM_BLOCK_SIZE; i++) |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
285 { |
3939 | 286 output[1 + (i - 4) * 2 + 0] = (input[i] >> 4) & 0x0F; |
287 output[1 + (i - 4) * 2 + 1] = input[i] & 0x0F; | |
288 } | |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
289 |
3939 | 290 decode_nibbles(&output[1], FOX61_ADPCM_SAMPLES_PER_BLOCK - 1, 1, |
291 predictor, index, | |
292 0, 0); | |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
293 |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
294 return FOX61_ADPCM_SAMPLES_PER_BLOCK; |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
295 } |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
296 |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
297 // note: This decoder assumes the format 0x62 data always comes in |
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
298 // stereo flavor |
4001 | 299 int fox62_adpcm_decode_block(unsigned short *output, unsigned char *input) |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
300 { |
4001 | 301 int pred1; |
302 int pred2; | |
303 int index1; | |
304 int index2; | |
305 int in_ptr = 0x10; | |
306 int out_ptr = 0; | |
307 | |
308 int flag1 = 0; | |
309 int flag2 = 1; | |
310 int sum; | |
311 unsigned char last_byte = 0; | |
312 unsigned char nibble; | |
313 | |
314 // ADPCM work variables | |
315 int sign; | |
316 int delta; | |
317 int step; | |
318 int diff; | |
319 | |
320 pred1 = LE_16(&input[10]); | |
321 pred2 = LE_16(&input[12]); | |
322 SE_16BIT(pred1); | |
323 SE_16BIT(pred2); | |
324 sum = pred2; | |
325 index1 = input[14]; | |
326 index2 = input[15]; | |
327 | |
328 while (in_ptr < 2048) | |
329 { | |
330 if (flag2) | |
331 { | |
332 last_byte = input[in_ptr++]; | |
333 nibble = last_byte & 0x0F; | |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
334 |
4001 | 335 step = adpcm_step[index1]; |
336 | |
337 sign = nibble & 8; | |
338 delta = nibble & 7; | |
339 | |
340 diff = step >> 3; | |
341 if (delta & 4) diff += step; | |
342 if (delta & 2) diff += step >> 1; | |
343 if (delta & 1) diff += step >> 2; | |
344 | |
345 if (sign) | |
346 pred1 -= diff; | |
347 else | |
348 pred1 += diff; | |
349 | |
350 CLAMP_S16(pred1); | |
351 | |
352 index1 += adpcm_index[nibble]; | |
353 CLAMP_0_TO_88(index1); | |
354 | |
355 if (flag1) | |
356 flag2 = 0; | |
357 else | |
358 { | |
359 nibble = (last_byte >> 4) & 0x0F; | |
360 | |
361 step = adpcm_step[index2]; | |
362 | |
363 sign = nibble & 8; | |
364 delta = nibble & 7; | |
365 | |
366 diff = step >> 3; | |
367 if (delta & 4) diff += step; | |
368 if (delta & 2) diff += step >> 1; | |
369 if (delta & 1) diff += step >> 2; | |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
370 |
4001 | 371 if (sign) |
372 pred2 -= diff; | |
373 else | |
374 pred2 += diff; | |
375 | |
376 CLAMP_S16(pred2); | |
377 | |
378 index2 += adpcm_index[nibble]; | |
379 CLAMP_0_TO_88(index2); | |
380 | |
381 sum = (sum + pred2) / 2; | |
382 } | |
383 output[out_ptr++] = pred1 + sum; | |
384 output[out_ptr++] = pred1 - sum; | |
385 | |
386 flag1 ^= 1; | |
387 if (in_ptr >= 2048) | |
388 break; | |
389 } | |
390 else | |
391 { | |
392 nibble = (last_byte >> 4) & 0x0F; | |
393 | |
394 step = adpcm_step[index1]; | |
395 | |
396 sign = nibble & 8; | |
397 delta = nibble & 7; | |
398 | |
399 diff = step >> 3; | |
400 if (delta & 4) diff += step; | |
401 if (delta & 2) diff += step >> 1; | |
402 if (delta & 1) diff += step >> 2; | |
403 | |
404 if (sign) | |
405 pred1 -= diff; | |
406 else | |
407 pred1 += diff; | |
408 | |
409 CLAMP_S16(pred1); | |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
410 |
4001 | 411 index1 += adpcm_index[nibble]; |
412 CLAMP_0_TO_88(index1); | |
413 | |
414 if (flag1) | |
415 flag2 = 1; | |
416 else | |
417 { | |
418 last_byte = input[in_ptr++]; | |
419 nibble = last_byte & 0x0F; | |
420 | |
421 step = adpcm_step[index2]; | |
422 | |
423 sign = nibble & 8; | |
424 delta = nibble & 7; | |
425 | |
426 diff = step >> 3; | |
427 if (delta & 4) diff += step; | |
428 if (delta & 2) diff += step >> 1; | |
429 if (delta & 1) diff += step >> 2; | |
430 | |
431 if (sign) | |
432 pred2 -= diff; | |
433 else | |
434 pred2 += diff; | |
435 | |
436 CLAMP_S16(pred2); | |
437 | |
438 index2 += adpcm_index[nibble]; | |
439 CLAMP_0_TO_88(index2); | |
440 | |
441 sum = (sum + pred2) / 2; | |
442 } | |
443 | |
444 output[out_ptr++] = pred1 + sum; | |
445 output[out_ptr++] = pred1 - sum; | |
446 | |
447 flag1 ^= 1; | |
448 if (in_ptr >= 2048) | |
449 break; | |
450 } | |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
451 } |
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
452 |
4001 | 453 return out_ptr; |
3939 | 454 } |