Mercurial > libavcodec.hg
comparison adpcm.c @ 1443:47f4c8a5a7fc libavcodec
New fringe codecs: WC3/Xan video, Xan DPCM, DK3 & DK4 ADPCM
author | tmmm |
---|---|
date | Mon, 08 Sep 2003 04:10:59 +0000 |
parents | eff1dc4bed49 |
children | 222643544cf1 |
comparison
equal
deleted
inserted
replaced
1442:2a4bd3a11d4a | 1443:47f4c8a5a7fc |
---|---|
1 /* | 1 /* |
2 * ADPCM codecs | 2 * ADPCM codecs |
3 * Copyright (c) 2001 Fabrice Bellard. | 3 * Copyright (c) 2001-2003 The ffmpeg Project |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Lesser General Public | 6 * modify it under the terms of the GNU Lesser General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
20 | 20 |
21 /** | 21 /** |
22 * @file adpcm.c | 22 * @file adpcm.c |
23 * ADPCM codecs. | 23 * ADPCM codecs. |
24 * First version by Francois Revol revol@free.fr | 24 * First version by Francois Revol revol@free.fr |
25 * Fringe ADPCM codecs (e.g., DK3 and DK4) | |
26 * by Mike Melanson (melanson@pcisys.net) | |
25 * | 27 * |
26 * Features and limitations: | 28 * Features and limitations: |
27 * | 29 * |
28 * Reference documents: | 30 * Reference documents: |
29 * http://www.pcisys.net/~melanson/codecs/adpcm.txt | 31 * http://www.pcisys.net/~melanson/codecs/simpleaudio.html |
30 * http://www.geocities.com/SiliconValley/8682/aud3.txt | 32 * http://www.geocities.com/SiliconValley/8682/aud3.txt |
31 * http://openquicktime.sourceforge.net/plugins.htm | 33 * http://openquicktime.sourceforge.net/plugins.htm |
32 * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html | 34 * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html |
33 * http://www.cs.ucla.edu/~leec/mediabench/applications.html | 35 * http://www.cs.ucla.edu/~leec/mediabench/applications.html |
34 * SoX source code http://home.sprynet.com/~cbagwell/sox.html | 36 * SoX source code http://home.sprynet.com/~cbagwell/sox.html |
291 if (step_index < 0) step_index = 0; | 293 if (step_index < 0) step_index = 0; |
292 else if (step_index > 88) step_index = 88; | 294 else if (step_index > 88) step_index = 88; |
293 | 295 |
294 sign = nibble & 8; | 296 sign = nibble & 8; |
295 delta = nibble & 7; | 297 delta = nibble & 7; |
296 #if 0 | 298 /* perform direct multiplication instead of series of jumps proposed by |
297 diff = step >> 3; | 299 * the reference ADPCM implementation since modern CPUs can do the mults |
298 if (delta & 4) diff += step; | 300 * quickly enough */ |
299 if (delta & 2) diff += step >> 1; | 301 diff = ((2 * delta + 1) * step) >> 3; |
300 if (delta & 1) diff += step >> 2; | |
301 #else | |
302 diff = ((2 * delta + 1) * step) >> 3; // no jumps | |
303 #endif | |
304 predictor = c->predictor; | 302 predictor = c->predictor; |
305 if (sign) predictor -= diff; | 303 if (sign) predictor -= diff; |
306 else predictor += diff; | 304 else predictor += diff; |
307 | 305 |
308 CLAMP_TO_SHORT(predictor); | 306 CLAMP_TO_SHORT(predictor); |
353 if (c->idelta < 16) c->idelta = 16; | 351 if (c->idelta < 16) c->idelta = 16; |
354 | 352 |
355 return (short)predictor; | 353 return (short)predictor; |
356 } | 354 } |
357 | 355 |
356 /* DK3 ADPCM support macro */ | |
357 #define DK3_GET_NEXT_NIBBLE() \ | |
358 if (decode_top_nibble_next) \ | |
359 { \ | |
360 nibble = (last_byte >> 4) & 0x0F; \ | |
361 decode_top_nibble_next = 0; \ | |
362 } \ | |
363 else \ | |
364 { \ | |
365 last_byte = *src++; \ | |
366 if (src >= buf + buf_size) break; \ | |
367 nibble = last_byte & 0x0F; \ | |
368 decode_top_nibble_next = 1; \ | |
369 } | |
370 | |
358 static int adpcm_decode_frame(AVCodecContext *avctx, | 371 static int adpcm_decode_frame(AVCodecContext *avctx, |
359 void *data, int *data_size, | 372 void *data, int *data_size, |
360 uint8_t *buf, int buf_size) | 373 uint8_t *buf, int buf_size) |
361 { | 374 { |
362 ADPCMContext *c = avctx->priv_data; | 375 ADPCMContext *c = avctx->priv_data; |
364 int n, m, channel, i; | 377 int n, m, channel, i; |
365 int block_predictor[2]; | 378 int block_predictor[2]; |
366 short *samples; | 379 short *samples; |
367 uint8_t *src; | 380 uint8_t *src; |
368 int st; /* stereo */ | 381 int st; /* stereo */ |
382 | |
383 /* DK3 ADPCM accounting variables */ | |
384 unsigned char last_byte = 0; | |
385 unsigned char nibble; | |
386 int decode_top_nibble_next = 0; | |
387 int diff_channel; | |
369 | 388 |
370 samples = data; | 389 samples = data; |
371 src = buf; | 390 src = buf; |
372 | 391 |
373 st = avctx->channels == 2; | 392 st = avctx->channels == 2; |
549 *samples++ = adpcm_ms_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); | 568 *samples++ = adpcm_ms_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); |
550 *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F); | 569 *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F); |
551 src ++; | 570 src ++; |
552 } | 571 } |
553 break; | 572 break; |
573 case CODEC_ID_ADPCM_IMA_DK4: | |
574 if (buf_size > BLKSIZE) { | |
575 if (avctx->block_align != 0) | |
576 buf_size = avctx->block_align; | |
577 else | |
578 buf_size = BLKSIZE; | |
579 } | |
580 c->status[0].predictor = (src[0] | (src[1] << 8)); | |
581 c->status[0].step_index = src[2]; | |
582 src += 4; | |
583 if(c->status[0].predictor & 0x8000) | |
584 c->status[0].predictor -= 0x10000; | |
585 *samples++ = c->status[0].predictor; | |
586 if (st) { | |
587 c->status[1].predictor = (src[0] | (src[1] << 8)); | |
588 c->status[1].step_index = src[2]; | |
589 src += 4; | |
590 if(c->status[1].predictor & 0x8000) | |
591 c->status[1].predictor -= 0x10000; | |
592 *samples++ = c->status[1].predictor; | |
593 } | |
594 while (src < buf + buf_size) { | |
595 | |
596 /* take care of the top nibble (always left or mono channel) */ | |
597 *samples++ = adpcm_ima_expand_nibble(&c->status[0], | |
598 (src[0] >> 4) & 0x0F); | |
599 | |
600 /* take care of the bottom nibble, which is right sample for | |
601 * stereo, or another mono sample */ | |
602 if (st) | |
603 *samples++ = adpcm_ima_expand_nibble(&c->status[1], | |
604 src[0] & 0x0F); | |
605 else | |
606 *samples++ = adpcm_ima_expand_nibble(&c->status[0], | |
607 src[0] & 0x0F); | |
608 | |
609 src++; | |
610 } | |
611 break; | |
612 case CODEC_ID_ADPCM_IMA_DK3: | |
613 if (buf_size > BLKSIZE) { | |
614 if (avctx->block_align != 0) | |
615 buf_size = avctx->block_align; | |
616 else | |
617 buf_size = BLKSIZE; | |
618 } | |
619 c->status[0].predictor = (src[10] | (src[11] << 8)); | |
620 c->status[1].predictor = (src[12] | (src[13] << 8)); | |
621 c->status[0].step_index = src[14]; | |
622 c->status[1].step_index = src[15]; | |
623 /* sign extend the predictors */ | |
624 if(c->status[0].predictor & 0x8000) | |
625 c->status[0].predictor -= 0x10000; | |
626 if(c->status[1].predictor & 0x8000) | |
627 c->status[1].predictor -= 0x10000; | |
628 src += 16; | |
629 diff_channel = c->status[1].predictor; | |
630 | |
631 /* the DK3_GET_NEXT_NIBBLE macro issues the break statement when | |
632 * the buffer is consumed */ | |
633 while (1) { | |
634 | |
635 /* for this algorithm, c->status[0] is the sum channel and | |
636 * c->status[1] is the diff channel */ | |
637 | |
638 /* process the first predictor of the sum channel */ | |
639 DK3_GET_NEXT_NIBBLE(); | |
640 adpcm_ima_expand_nibble(&c->status[0], nibble); | |
641 | |
642 /* process the diff channel predictor */ | |
643 DK3_GET_NEXT_NIBBLE(); | |
644 adpcm_ima_expand_nibble(&c->status[1], nibble); | |
645 | |
646 /* process the first pair of stereo PCM samples */ | |
647 diff_channel = (diff_channel + c->status[1].predictor) / 2; | |
648 *samples++ = c->status[0].predictor + c->status[1].predictor; | |
649 *samples++ = c->status[0].predictor - c->status[1].predictor; | |
650 | |
651 /* process the second predictor of the sum channel */ | |
652 DK3_GET_NEXT_NIBBLE(); | |
653 adpcm_ima_expand_nibble(&c->status[0], nibble); | |
654 | |
655 /* process the second pair of stereo PCM samples */ | |
656 diff_channel = (diff_channel + c->status[1].predictor) / 2; | |
657 *samples++ = c->status[0].predictor + c->status[1].predictor; | |
658 *samples++ = c->status[0].predictor - c->status[1].predictor; | |
659 } | |
660 break; | |
554 default: | 661 default: |
555 *data_size = 0; | 662 *data_size = 0; |
556 return -1; | 663 return -1; |
557 } | 664 } |
558 *data_size = (uint8_t *)samples - (uint8_t *)data; | 665 *data_size = (uint8_t *)samples - (uint8_t *)data; |
581 adpcm_decode_frame, \ | 688 adpcm_decode_frame, \ |
582 }; | 689 }; |
583 | 690 |
584 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); | 691 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); |
585 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); | 692 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); |
693 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); | |
694 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); | |
586 ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); | 695 ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); |
587 ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); | 696 ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); |
588 | 697 |
589 #undef ADPCM_CODEC | 698 #undef ADPCM_CODEC |
590 |