|
@@ -42,31 +42,35 @@
|
|
|
* Features and limitations:
|
|
|
*
|
|
|
* Reference documents:
|
|
|
- * http://www.pcisys.net/~melanson/codecs/simpleaudio.html
|
|
|
- * http://www.geocities.com/SiliconValley/8682/aud3.txt
|
|
|
- * http://openquicktime.sourceforge.net/plugins.htm
|
|
|
- * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html
|
|
|
- * http://www.cs.ucla.edu/~leec/mediabench/applications.html
|
|
|
- * SoX source code http://home.sprynet.com/~cbagwell/sox.html
|
|
|
+ * http://wiki.multimedia.cx/index.php?title=Category:ADPCM_Audio_Codecs
|
|
|
+ * http://www.pcisys.net/~melanson/codecs/simpleaudio.html [dead]
|
|
|
+ * http://www.geocities.com/SiliconValley/8682/aud3.txt [dead]
|
|
|
+ * http://openquicktime.sourceforge.net/
|
|
|
+ * XAnim sources (xa_codec.c) http://xanim.polter.net/
|
|
|
+ * http://www.cs.ucla.edu/~leec/mediabench/applications.html [dead]
|
|
|
+ * SoX source code http://sox.sourceforge.net/
|
|
|
*
|
|
|
* CD-ROM XA:
|
|
|
- * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html
|
|
|
- * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html
|
|
|
+ * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html [dead]
|
|
|
+ * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html [dead]
|
|
|
* readstr http://www.geocities.co.jp/Playtown/2004/
|
|
|
*/
|
|
|
|
|
|
/* These are for CD-ROM XA ADPCM */
|
|
|
static const int xa_adpcm_table[5][2] = {
|
|
|
- { 0, 0 },
|
|
|
- { 60, 0 },
|
|
|
- { 115, -52 },
|
|
|
- { 98, -55 },
|
|
|
- { 122, -60 }
|
|
|
+ { 0, 0 },
|
|
|
+ { 60, 0 },
|
|
|
+ { 115, -52 },
|
|
|
+ { 98, -55 },
|
|
|
+ { 122, -60 }
|
|
|
};
|
|
|
|
|
|
static const int ea_adpcm_table[] = {
|
|
|
- 0, 240, 460, 392, 0, 0, -208, -220, 0, 1,
|
|
|
- 3, 4, 7, 8, 10, 11, 0, -1, -3, -4
|
|
|
+ 0, 240, 460, 392,
|
|
|
+ 0, 0, -208, -220,
|
|
|
+ 0, 1, 3, 4,
|
|
|
+ 7, 8, 10, 11,
|
|
|
+ 0, -1, -3, -4
|
|
|
};
|
|
|
|
|
|
// padded to zero where table size is less then 16
|
|
@@ -336,27 +340,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
ADPCMDecodeContext *c = avctx->priv_data;
|
|
|
ADPCMChannelStatus *cs;
|
|
|
int n, m, channel, i;
|
|
|
- int block_predictor[2];
|
|
|
short *samples;
|
|
|
short *samples_end;
|
|
|
const uint8_t *src;
|
|
|
int st; /* stereo */
|
|
|
-
|
|
|
- /* DK3 ADPCM accounting variables */
|
|
|
- unsigned char last_byte = 0;
|
|
|
- unsigned char nibble;
|
|
|
- int decode_top_nibble_next = 0;
|
|
|
- int diff_channel;
|
|
|
-
|
|
|
- /* EA ADPCM state variables */
|
|
|
uint32_t samples_in_chunk;
|
|
|
- int32_t previous_left_sample, previous_right_sample;
|
|
|
- int32_t current_left_sample, current_right_sample;
|
|
|
- int32_t next_left_sample, next_right_sample;
|
|
|
- int32_t coeff1l, coeff2l, coeff1r, coeff2r;
|
|
|
- uint8_t shift_left, shift_right;
|
|
|
int count1, count2;
|
|
|
- int coeff[2][2], shift[2];//used in EA MAXIS ADPCM
|
|
|
|
|
|
if (!buf_size)
|
|
|
return 0;
|
|
@@ -376,7 +365,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
|
|
|
switch(avctx->codec->id) {
|
|
|
case CODEC_ID_ADPCM_IMA_QT:
|
|
|
- n = buf_size - 2*avctx->channels;
|
|
|
+ /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples).
|
|
|
+ Channel data is interleaved per-chunk. */
|
|
|
+ if (buf_size / 34 < avctx->channels) {
|
|
|
+ av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
|
|
|
+ return AVERROR(EINVAL);
|
|
|
+ }
|
|
|
for (channel = 0; channel < avctx->channels; channel++) {
|
|
|
int16_t predictor;
|
|
|
int step_index;
|
|
@@ -409,7 +403,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
|
|
|
samples = (short*)data + channel;
|
|
|
|
|
|
- for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */
|
|
|
+ for (m = 0; m < 32; m++) {
|
|
|
*samples = adpcm_ima_qt_expand_nibble(cs, src[0] & 0x0F, 3);
|
|
|
samples += avctx->channels;
|
|
|
*samples = adpcm_ima_qt_expand_nibble(cs, src[0] >> 4 , 3);
|
|
@@ -439,60 +433,66 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
}
|
|
|
|
|
|
while(src < buf + buf_size){
|
|
|
- for(m=0; m<4; m++){
|
|
|
- for(i=0; i<=st; i++)
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] & 0x0F, 3);
|
|
|
- for(i=0; i<=st; i++)
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] >> 4 , 3);
|
|
|
- src++;
|
|
|
+ for (i = 0; i < avctx->channels; i++) {
|
|
|
+ cs = &c->status[i];
|
|
|
+ for (m = 0; m < 4; m++) {
|
|
|
+ uint8_t v = *src++;
|
|
|
+ *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 3);
|
|
|
+ samples += avctx->channels;
|
|
|
+ *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 3);
|
|
|
+ samples += avctx->channels;
|
|
|
+ }
|
|
|
+ samples -= 8 * avctx->channels - 1;
|
|
|
}
|
|
|
- src += 4*st;
|
|
|
+ samples += 7 * avctx->channels;
|
|
|
}
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_4XM:
|
|
|
- cs = &(c->status[0]);
|
|
|
- c->status[0].predictor= (int16_t)bytestream_get_le16(&src);
|
|
|
- if(st){
|
|
|
- c->status[1].predictor= (int16_t)bytestream_get_le16(&src);
|
|
|
- }
|
|
|
- c->status[0].step_index= (int16_t)bytestream_get_le16(&src);
|
|
|
- if(st){
|
|
|
- c->status[1].step_index= (int16_t)bytestream_get_le16(&src);
|
|
|
- }
|
|
|
- if (cs->step_index < 0) cs->step_index = 0;
|
|
|
- if (cs->step_index > 88) cs->step_index = 88;
|
|
|
+ for (i = 0; i < avctx->channels; i++)
|
|
|
+ c->status[i].predictor= (int16_t)bytestream_get_le16(&src);
|
|
|
|
|
|
- m= (buf_size - (src - buf))>>st;
|
|
|
- for(i=0; i<m; i++) {
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] & 0x0F, 4);
|
|
|
- if (st)
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] & 0x0F, 4);
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] >> 4, 4);
|
|
|
- if (st)
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] >> 4, 4);
|
|
|
+ for (i = 0; i < avctx->channels; i++) {
|
|
|
+ c->status[i].step_index= (int16_t)bytestream_get_le16(&src);
|
|
|
+ c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88);
|
|
|
}
|
|
|
|
|
|
- src += m<<st;
|
|
|
+ m= (buf_size - (src - buf))>>st;
|
|
|
|
|
|
+ for (i = 0; i < avctx->channels; i++) {
|
|
|
+ samples = (short*)data + i;
|
|
|
+ cs = &c->status[i];
|
|
|
+ for (n = 0; n < m; n++) {
|
|
|
+ uint8_t v = *src++;
|
|
|
+ *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 4);
|
|
|
+ samples += avctx->channels;
|
|
|
+ *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 4);
|
|
|
+ samples += avctx->channels;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ samples -= (avctx->channels - 1);
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_MS:
|
|
|
+ {
|
|
|
+ int block_predictor;
|
|
|
+
|
|
|
if (avctx->block_align != 0 && buf_size > avctx->block_align)
|
|
|
buf_size = avctx->block_align;
|
|
|
n = buf_size - 7 * avctx->channels;
|
|
|
if (n < 0)
|
|
|
return -1;
|
|
|
- block_predictor[0] = av_clip(*src++, 0, 6);
|
|
|
- block_predictor[1] = 0;
|
|
|
- if (st)
|
|
|
- block_predictor[1] = av_clip(*src++, 0, 6);
|
|
|
+
|
|
|
+ block_predictor = av_clip(*src++, 0, 6);
|
|
|
+ c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];
|
|
|
+ c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];
|
|
|
+ if (st) {
|
|
|
+ block_predictor = av_clip(*src++, 0, 6);
|
|
|
+ c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor];
|
|
|
+ c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor];
|
|
|
+ }
|
|
|
c->status[0].idelta = (int16_t)bytestream_get_le16(&src);
|
|
|
if (st){
|
|
|
c->status[1].idelta = (int16_t)bytestream_get_le16(&src);
|
|
|
}
|
|
|
- c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[0]];
|
|
|
- c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[0]];
|
|
|
- c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[1]];
|
|
|
- c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[1]];
|
|
|
|
|
|
c->status[0].sample1 = bytestream_get_le16(&src);
|
|
|
if (st) c->status[1].sample1 = bytestream_get_le16(&src);
|
|
@@ -509,39 +509,37 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
src ++;
|
|
|
}
|
|
|
break;
|
|
|
+ }
|
|
|
case CODEC_ID_ADPCM_IMA_DK4:
|
|
|
if (avctx->block_align != 0 && buf_size > avctx->block_align)
|
|
|
buf_size = avctx->block_align;
|
|
|
|
|
|
- c->status[0].predictor = (int16_t)bytestream_get_le16(&src);
|
|
|
- c->status[0].step_index = *src++;
|
|
|
- src++;
|
|
|
- *samples++ = c->status[0].predictor;
|
|
|
- if (st) {
|
|
|
- c->status[1].predictor = (int16_t)bytestream_get_le16(&src);
|
|
|
- c->status[1].step_index = *src++;
|
|
|
- src++;
|
|
|
- *samples++ = c->status[1].predictor;
|
|
|
+ n = buf_size - 4 * avctx->channels;
|
|
|
+ if (n < 0) {
|
|
|
+ av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
|
|
|
+ return AVERROR(EINVAL);
|
|
|
}
|
|
|
- while (src < buf + buf_size) {
|
|
|
-
|
|
|
- /* take care of the top nibble (always left or mono channel) */
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4, 3);
|
|
|
-
|
|
|
- /* take care of the bottom nibble, which is right sample for
|
|
|
- * stereo, or another mono sample */
|
|
|
- if (st)
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[1],
|
|
|
- src[0] & 0x0F, 3);
|
|
|
- else
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] & 0x0F, 3);
|
|
|
|
|
|
+ for (channel = 0; channel < avctx->channels; channel++) {
|
|
|
+ cs = &c->status[channel];
|
|
|
+ cs->predictor = (int16_t)bytestream_get_le16(&src);
|
|
|
+ cs->step_index = *src++;
|
|
|
src++;
|
|
|
+ *samples++ = cs->predictor;
|
|
|
+ }
|
|
|
+ while (n-- > 0) {
|
|
|
+ uint8_t v = *src++;
|
|
|
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 , 3);
|
|
|
+ *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
|
|
|
}
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_IMA_DK3:
|
|
|
+ {
|
|
|
+ unsigned char last_byte = 0;
|
|
|
+ unsigned char nibble;
|
|
|
+ int decode_top_nibble_next = 0;
|
|
|
+ int diff_channel;
|
|
|
+
|
|
|
if (avctx->block_align != 0 && buf_size > avctx->block_align)
|
|
|
buf_size = avctx->block_align;
|
|
|
|
|
@@ -586,50 +584,41 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
*samples++ = c->status[0].predictor - c->status[1].predictor;
|
|
|
}
|
|
|
break;
|
|
|
+ }
|
|
|
case CODEC_ID_ADPCM_IMA_ISS:
|
|
|
- c->status[0].predictor = (int16_t)AV_RL16(src + 0);
|
|
|
- c->status[0].step_index = src[2];
|
|
|
- src += 4;
|
|
|
- if(st) {
|
|
|
- c->status[1].predictor = (int16_t)AV_RL16(src + 0);
|
|
|
- c->status[1].step_index = src[2];
|
|
|
- src += 4;
|
|
|
+ n = buf_size - 4 * avctx->channels;
|
|
|
+ if (n < 0) {
|
|
|
+ av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
|
|
|
+ return AVERROR(EINVAL);
|
|
|
}
|
|
|
|
|
|
- while (src < buf + buf_size) {
|
|
|
+ for (channel = 0; channel < avctx->channels; channel++) {
|
|
|
+ cs = &c->status[channel];
|
|
|
+ cs->predictor = (int16_t)bytestream_get_le16(&src);
|
|
|
+ cs->step_index = *src++;
|
|
|
+ src++;
|
|
|
+ }
|
|
|
|
|
|
+ while (n-- > 0) {
|
|
|
+ uint8_t v1, v2;
|
|
|
+ uint8_t v = *src++;
|
|
|
+ /* nibbles are swapped for mono */
|
|
|
if (st) {
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4 , 3);
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[1],
|
|
|
- src[0] & 0x0F, 3);
|
|
|
+ v1 = v >> 4;
|
|
|
+ v2 = v & 0x0F;
|
|
|
} else {
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] & 0x0F, 3);
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4 , 3);
|
|
|
+ v2 = v >> 4;
|
|
|
+ v1 = v & 0x0F;
|
|
|
}
|
|
|
-
|
|
|
- src++;
|
|
|
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v1, 3);
|
|
|
+ *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3);
|
|
|
}
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_IMA_WS:
|
|
|
- /* no per-block initialization; just start decoding the data */
|
|
|
while (src < buf + buf_size) {
|
|
|
-
|
|
|
- if (st) {
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4 , 3);
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[1],
|
|
|
- src[0] & 0x0F, 3);
|
|
|
- } else {
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4 , 3);
|
|
|
- *samples++ = adpcm_ima_expand_nibble(&c->status[0],
|
|
|
- src[0] & 0x0F, 3);
|
|
|
- }
|
|
|
-
|
|
|
- src++;
|
|
|
+ uint8_t v = *src++;
|
|
|
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4 , 3);
|
|
|
+ *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3);
|
|
|
}
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_XA:
|
|
@@ -668,6 +657,13 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
}
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_EA:
|
|
|
+ {
|
|
|
+ int32_t previous_left_sample, previous_right_sample;
|
|
|
+ int32_t current_left_sample, current_right_sample;
|
|
|
+ int32_t next_left_sample, next_right_sample;
|
|
|
+ int32_t coeff1l, coeff2l, coeff1r, coeff2r;
|
|
|
+ uint8_t shift_left, shift_right;
|
|
|
+
|
|
|
/* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,
|
|
|
each coding 28 stereo samples. */
|
|
|
if (buf_size < 12) {
|
|
@@ -721,7 +717,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
src += 2; // Skip terminating 0x0000
|
|
|
|
|
|
break;
|
|
|
+ }
|
|
|
case CODEC_ID_ADPCM_EA_MAXIS_XA:
|
|
|
+ {
|
|
|
+ int coeff[2][2], shift[2];
|
|
|
+
|
|
|
for(channel = 0; channel < avctx->channels; channel++) {
|
|
|
for (i=0; i<2; i++)
|
|
|
coeff[channel][i] = ea_adpcm_table[(*src >> 4) + 4*i];
|
|
@@ -743,6 +743,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
src+=avctx->channels;
|
|
|
}
|
|
|
break;
|
|
|
+ }
|
|
|
case CODEC_ID_ADPCM_EA_R1:
|
|
|
case CODEC_ID_ADPCM_EA_R2:
|
|
|
case CODEC_ID_ADPCM_EA_R3: {
|
|
@@ -885,18 +886,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_CT:
|
|
|
while (src < buf + buf_size) {
|
|
|
- if (st) {
|
|
|
- *samples++ = adpcm_ct_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4);
|
|
|
- *samples++ = adpcm_ct_expand_nibble(&c->status[1],
|
|
|
- src[0] & 0x0F);
|
|
|
- } else {
|
|
|
- *samples++ = adpcm_ct_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4);
|
|
|
- *samples++ = adpcm_ct_expand_nibble(&c->status[0],
|
|
|
- src[0] & 0x0F);
|
|
|
- }
|
|
|
- src++;
|
|
|
+ uint8_t v = *src++;
|
|
|
+ *samples++ = adpcm_ct_expand_nibble(&c->status[0 ], v >> 4 );
|
|
|
+ *samples++ = adpcm_ct_expand_nibble(&c->status[st], v & 0x0F);
|
|
|
}
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_SBPRO_4:
|
|
@@ -1004,18 +996,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
|
|
|
}
|
|
|
case CODEC_ID_ADPCM_YAMAHA:
|
|
|
while (src < buf + buf_size) {
|
|
|
- if (st) {
|
|
|
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
|
|
|
- src[0] & 0x0F);
|
|
|
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[1],
|
|
|
- src[0] >> 4 );
|
|
|
- } else {
|
|
|
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
|
|
|
- src[0] & 0x0F);
|
|
|
- *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],
|
|
|
- src[0] >> 4 );
|
|
|
- }
|
|
|
- src++;
|
|
|
+ uint8_t v = *src++;
|
|
|
+ *samples++ = adpcm_yamaha_expand_nibble(&c->status[0 ], v & 0x0F);
|
|
|
+ *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4 );
|
|
|
}
|
|
|
break;
|
|
|
case CODEC_ID_ADPCM_THP:
|