Mercurial > mplayer.hg
comparison adpcm.c @ 4854:4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
(including MS, DK4 and DK3 ADPCM)
author | melanson |
---|---|
date | Mon, 25 Feb 2002 02:48:37 +0000 |
parents | ae6f97724b84 |
children | f9cd6381e327 |
comparison
equal
deleted
inserted
replaced
4853:2853640cea58 | 4854:4a6dde59834c |
---|---|
10 */ | 10 */ |
11 | 11 |
12 #include "config.h" | 12 #include "config.h" |
13 #include "bswap.h" | 13 #include "bswap.h" |
14 #include "adpcm.h" | 14 #include "adpcm.h" |
15 #include "mp_msg.h" | |
15 | 16 |
16 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) | 17 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) |
17 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) | 18 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) |
18 #define LE_16(x) (le2me_16(*(unsigned short *)(x))) | 19 #define LE_16(x) (le2me_16(*(unsigned short *)(x))) |
19 #define LE_32(x) (le2me_32(*(unsigned int *)(x))) | 20 #define LE_32(x) (le2me_32(*(unsigned int *)(x))) |
194 int nibble; | 195 int nibble; |
195 int snibble; // signed nibble | 196 int snibble; // signed nibble |
196 int predictor; | 197 int predictor; |
197 | 198 |
198 // fetch the header information, in stereo if both channels are present | 199 // fetch the header information, in stereo if both channels are present |
200 if (input[stream_ptr] > 6) | |
201 mp_msg(MSGT_DECAUDIO, MSGL_WARN, | |
202 "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", | |
203 input[stream_ptr]); | |
199 coeff1[0] = ms_adapt_coeff1[input[stream_ptr]]; | 204 coeff1[0] = ms_adapt_coeff1[input[stream_ptr]]; |
200 coeff2[0] = ms_adapt_coeff2[input[stream_ptr]]; | 205 coeff2[0] = ms_adapt_coeff2[input[stream_ptr]]; |
201 stream_ptr++; | 206 stream_ptr++; |
202 if (channels == 2) | 207 if (channels == 2) |
203 { | 208 { |
209 if (input[stream_ptr] > 6) | |
210 mp_msg(MSGT_DECAUDIO, MSGL_WARN, | |
211 "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", | |
212 input[stream_ptr]); | |
204 coeff1[1] = ms_adapt_coeff1[input[stream_ptr]]; | 213 coeff1[1] = ms_adapt_coeff1[input[stream_ptr]]; |
205 coeff2[1] = ms_adapt_coeff2[input[stream_ptr]]; | 214 coeff2[1] = ms_adapt_coeff2[input[stream_ptr]]; |
206 stream_ptr++; | 215 stream_ptr++; |
207 } | 216 } |
208 | 217 |
265 } | 274 } |
266 | 275 |
267 return (block_size - (MS_ADPCM_PREAMBLE_SIZE * channels)) * 2; | 276 return (block_size - (MS_ADPCM_PREAMBLE_SIZE * channels)) * 2; |
268 } | 277 } |
269 | 278 |
270 // note: This decoder assumes the format 0x61 data always comes in | 279 int dk4_adpcm_decode_block(unsigned short *output, unsigned char *input, |
271 // mono flavor | 280 int channels, int block_size) |
272 int fox61_adpcm_decode_block(unsigned short *output, unsigned char *input) | |
273 { | 281 { |
274 int i; | 282 int i; |
275 int predictor; | 283 int output_ptr; |
276 int index; | 284 int predictor_l = 0; |
285 int predictor_r = 0; | |
286 int index_l = 0; | |
287 int index_r = 0; | |
277 | 288 |
278 // the first predictor value goes straight to the output | 289 // the first predictor value goes straight to the output |
279 predictor = output[0] = LE_16(&input[0]); | 290 predictor_l = output[0] = LE_16(&input[0]); |
280 SE_16BIT(predictor); | 291 SE_16BIT(predictor_l); |
281 index = input[2]; | 292 index_l = input[2]; |
282 | 293 if (channels == 2) |
283 // unpack the nibbles | 294 { |
284 for (i = 4; i < FOX61_ADPCM_BLOCK_SIZE; i++) | 295 predictor_r = output[1] = LE_16(&input[4]); |
285 { | 296 SE_16BIT(predictor_r); |
286 output[1 + (i - 4) * 2 + 0] = (input[i] >> 4) & 0x0F; | 297 index_r = input[6]; |
287 output[1 + (i - 4) * 2 + 1] = input[i] & 0x0F; | 298 } |
288 } | 299 |
289 | 300 output_ptr = channels; |
290 decode_nibbles(&output[1], FOX61_ADPCM_SAMPLES_PER_BLOCK - 1, 1, | 301 for (i = DK4_ADPCM_PREAMBLE_SIZE * channels; i < block_size; i++) |
291 predictor, index, | 302 { |
292 0, 0); | 303 output[output_ptr++] = input[i] >> 4; |
293 | 304 output[output_ptr++] = input[i] & 0x0F; |
294 return FOX61_ADPCM_SAMPLES_PER_BLOCK; | 305 } |
306 | |
307 decode_nibbles(&output[channels], | |
308 (block_size - DK4_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels, | |
309 channels, | |
310 predictor_l, index_l, | |
311 predictor_r, index_r); | |
312 | |
313 return (block_size - DK4_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels; | |
295 } | 314 } |
315 | |
316 #define DK3_GET_NEXT_NIBBLE() \ | |
317 if (decode_top_nibble_next) \ | |
318 { \ | |
319 nibble = (last_byte >> 4) & 0x0F; \ | |
320 decode_top_nibble_next = 0; \ | |
321 } \ | |
322 else \ | |
323 { \ | |
324 last_byte = input[in_ptr++]; \ | |
325 nibble = last_byte & 0x0F; \ | |
326 decode_top_nibble_next = 1; \ | |
327 } | |
296 | 328 |
297 // note: This decoder assumes the format 0x62 data always comes in | 329 // note: This decoder assumes the format 0x62 data always comes in |
298 // stereo flavor | 330 // stereo flavor |
299 int fox62_adpcm_decode_block(unsigned short *output, unsigned char *input) | 331 int dk3_adpcm_decode_block(unsigned short *output, unsigned char *input) |
300 { | 332 { |
301 int pred1; | 333 int sum_pred; |
302 int pred2; | 334 int diff_pred; |
303 int index1; | 335 int sum_index; |
304 int index2; | 336 int diff_index; |
337 int diff_channel; | |
305 int in_ptr = 0x10; | 338 int in_ptr = 0x10; |
306 int out_ptr = 0; | 339 int out_ptr = 0; |
307 | 340 |
308 int flag1 = 0; | |
309 int flag2 = 1; | |
310 int sum; | |
311 unsigned char last_byte = 0; | 341 unsigned char last_byte = 0; |
312 unsigned char nibble; | 342 unsigned char nibble; |
343 int decode_top_nibble_next = 0; | |
313 | 344 |
314 // ADPCM work variables | 345 // ADPCM work variables |
315 int sign; | 346 int sign; |
316 int delta; | 347 int delta; |
317 int step; | 348 int step; |
318 int diff; | 349 int diff; |
319 | 350 |
320 pred1 = LE_16(&input[10]); | 351 sum_pred = LE_16(&input[10]); |
321 pred2 = LE_16(&input[12]); | 352 diff_pred = LE_16(&input[12]); |
322 SE_16BIT(pred1); | 353 SE_16BIT(sum_pred); |
323 SE_16BIT(pred2); | 354 SE_16BIT(diff_pred); |
324 sum = pred2; | 355 diff_channel = diff_pred; |
325 index1 = input[14]; | 356 sum_index = input[14]; |
326 index2 = input[15]; | 357 diff_index = input[15]; |
327 | 358 |
328 while (in_ptr < 2048) | 359 while (in_ptr < 2048) |
329 { | 360 { |
330 if (flag2) | 361 // process the first predictor of the sum channel |
331 { | 362 DK3_GET_NEXT_NIBBLE(); |
332 last_byte = input[in_ptr++]; | 363 |
333 nibble = last_byte & 0x0F; | 364 step = adpcm_step[sum_index]; |
334 | 365 |
335 step = adpcm_step[index1]; | 366 sign = nibble & 8; |
336 | 367 delta = nibble & 7; |
337 sign = nibble & 8; | 368 |
338 delta = nibble & 7; | 369 diff = step >> 3; |
339 | 370 if (delta & 4) diff += step; |
340 diff = step >> 3; | 371 if (delta & 2) diff += step >> 1; |
341 if (delta & 4) diff += step; | 372 if (delta & 1) diff += step >> 2; |
342 if (delta & 2) diff += step >> 1; | 373 |
343 if (delta & 1) diff += step >> 2; | 374 if (sign) |
344 | 375 sum_pred -= diff; |
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; | |
370 | |
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 | 376 else |
391 { | 377 sum_pred += diff; |
392 nibble = (last_byte >> 4) & 0x0F; | 378 |
393 | 379 CLAMP_S16(sum_pred); |
394 step = adpcm_step[index1]; | 380 |
395 | 381 sum_index += adpcm_index[nibble]; |
396 sign = nibble & 8; | 382 CLAMP_0_TO_88(sum_index); |
397 delta = nibble & 7; | 383 |
398 | 384 // process the diff channel predictor |
399 diff = step >> 3; | 385 DK3_GET_NEXT_NIBBLE(); |
400 if (delta & 4) diff += step; | 386 |
401 if (delta & 2) diff += step >> 1; | 387 step = adpcm_step[diff_index]; |
402 if (delta & 1) diff += step >> 2; | 388 |
403 | 389 sign = nibble & 8; |
404 if (sign) | 390 delta = nibble & 7; |
405 pred1 -= diff; | 391 |
406 else | 392 diff = step >> 3; |
407 pred1 += diff; | 393 if (delta & 4) diff += step; |
408 | 394 if (delta & 2) diff += step >> 1; |
409 CLAMP_S16(pred1); | 395 if (delta & 1) diff += step >> 2; |
410 | 396 |
411 index1 += adpcm_index[nibble]; | 397 if (sign) |
412 CLAMP_0_TO_88(index1); | 398 diff_pred -= diff; |
413 | 399 else |
414 if (flag1) | 400 diff_pred += diff; |
415 flag2 = 1; | 401 |
416 else | 402 CLAMP_S16(diff_pred); |
417 { | 403 |
418 last_byte = input[in_ptr++]; | 404 diff_index += adpcm_index[nibble]; |
419 nibble = last_byte & 0x0F; | 405 CLAMP_0_TO_88(diff_index); |
420 | 406 |
421 step = adpcm_step[index2]; | 407 // output the first pair of stereo PCM samples |
422 | 408 diff_channel = (diff_channel + diff_pred) / 2; |
423 sign = nibble & 8; | 409 output[out_ptr++] = sum_pred + diff_channel; |
424 delta = nibble & 7; | 410 output[out_ptr++] = sum_pred - diff_channel; |
425 | 411 |
426 diff = step >> 3; | 412 // process the second predictor of the sum channel |
427 if (delta & 4) diff += step; | 413 DK3_GET_NEXT_NIBBLE(); |
428 if (delta & 2) diff += step >> 1; | 414 |
429 if (delta & 1) diff += step >> 2; | 415 step = adpcm_step[sum_index]; |
430 | 416 |
431 if (sign) | 417 sign = nibble & 8; |
432 pred2 -= diff; | 418 delta = nibble & 7; |
433 else | 419 |
434 pred2 += diff; | 420 diff = step >> 3; |
435 | 421 if (delta & 4) diff += step; |
436 CLAMP_S16(pred2); | 422 if (delta & 2) diff += step >> 1; |
437 | 423 if (delta & 1) diff += step >> 2; |
438 index2 += adpcm_index[nibble]; | 424 |
439 CLAMP_0_TO_88(index2); | 425 if (sign) |
440 | 426 sum_pred -= diff; |
441 sum = (sum + pred2) / 2; | 427 else |
442 } | 428 sum_pred += diff; |
443 | 429 |
444 output[out_ptr++] = pred1 + sum; | 430 CLAMP_S16(sum_pred); |
445 output[out_ptr++] = pred1 - sum; | 431 |
446 | 432 sum_index += adpcm_index[nibble]; |
447 flag1 ^= 1; | 433 CLAMP_0_TO_88(sum_index); |
448 if (in_ptr >= 2048) | 434 |
449 break; | 435 // output the second pair of stereo PCM samples |
450 } | 436 output[out_ptr++] = sum_pred + diff_channel; |
437 output[out_ptr++] = sum_pred - diff_channel; | |
451 } | 438 } |
452 | 439 |
453 return out_ptr; | 440 return out_ptr; |
454 } | 441 } |