Mercurial > mplayer.hg
annotate adpcm.c @ 4144:501620ec9b40
fixed to get something - needs a major rewrite
author | arpi |
---|---|
date | Sun, 13 Jan 2002 22:14:06 +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 } |