|
|
|
@ -21,9 +21,10 @@ |
|
|
|
|
/**
|
|
|
|
|
* @file adpcm.c |
|
|
|
|
* ADPCM codecs. |
|
|
|
|
* First version by Francois Revol revol@free.fr |
|
|
|
|
* First version by Francois Revol (revol@free.fr) |
|
|
|
|
* Fringe ADPCM codecs (e.g., DK3, DK4, Westwood) |
|
|
|
|
* by Mike Melanson (melanson@pcisys.net) |
|
|
|
|
* CD-ROM XA ADPCM codec by BERO |
|
|
|
|
* |
|
|
|
|
* Features and limitations: |
|
|
|
|
* |
|
|
|
@ -34,6 +35,11 @@ |
|
|
|
|
* 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
|
|
|
|
|
* |
|
|
|
|
* CD-ROM XA: |
|
|
|
|
* http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html
|
|
|
|
|
* vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html
|
|
|
|
|
* readstr http://www.geocities.co.jp/Playtown/2004/
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#define BLKSIZE 1024 |
|
|
|
@ -67,7 +73,7 @@ static const int step_table[89] = { |
|
|
|
|
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* Those are for MS-ADPCM */ |
|
|
|
|
/* These are for MS-ADPCM */ |
|
|
|
|
/* AdaptationTable[], AdaptCoeff1[], and AdaptCoeff2[] are from libsndfile */ |
|
|
|
|
static const int AdaptationTable[] = { |
|
|
|
|
230, 230, 230, 230, 307, 409, 512, 614, |
|
|
|
@ -82,6 +88,15 @@ static const int AdaptCoeff2[] = { |
|
|
|
|
0, -256, 0, 64, 0, -208, -232 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* These are for CD-ROM XA ADPCM */ |
|
|
|
|
const static int xa_adpcm_table[5][2] = { |
|
|
|
|
{ 0, 0 }, |
|
|
|
|
{ 60, 0 }, |
|
|
|
|
{ 115, -52 }, |
|
|
|
|
{ 98, -55 }, |
|
|
|
|
{ 122, -60 } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* end of tables */ |
|
|
|
|
|
|
|
|
|
typedef struct ADPCMChannelStatus { |
|
|
|
@ -355,6 +370,74 @@ static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) |
|
|
|
|
return (short)predictor; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void xa_decode(short *out, const unsigned char *in,
|
|
|
|
|
ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc) |
|
|
|
|
{ |
|
|
|
|
int i, j; |
|
|
|
|
int shift,filter,f0,f1; |
|
|
|
|
int s_1,s_2; |
|
|
|
|
int d,s,t; |
|
|
|
|
|
|
|
|
|
for(i=0;i<4;i++) { |
|
|
|
|
|
|
|
|
|
shift = 12 - (in[4+i*2] & 15); |
|
|
|
|
filter = in[4+i*2] >> 4; |
|
|
|
|
f0 = xa_adpcm_table[filter][0]; |
|
|
|
|
f1 = xa_adpcm_table[filter][1]; |
|
|
|
|
|
|
|
|
|
s_1 = left->sample1; |
|
|
|
|
s_2 = left->sample2; |
|
|
|
|
|
|
|
|
|
for(j=0;j<28;j++) { |
|
|
|
|
d = in[16+i+j*4]; |
|
|
|
|
|
|
|
|
|
t = (signed char)(d<<4)>>4; |
|
|
|
|
s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6); |
|
|
|
|
CLAMP_TO_SHORT(s); |
|
|
|
|
*out = s; |
|
|
|
|
out += inc; |
|
|
|
|
s_2 = s_1; |
|
|
|
|
s_1 = s; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (inc==2) { /* stereo */ |
|
|
|
|
left->sample1 = s_1; |
|
|
|
|
left->sample2 = s_2; |
|
|
|
|
s_1 = right->sample1; |
|
|
|
|
s_2 = right->sample2; |
|
|
|
|
out = out + 1 - 28*2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
shift = 12 - (in[5+i*2] & 15); |
|
|
|
|
filter = in[5+i*2] >> 4; |
|
|
|
|
|
|
|
|
|
f0 = xa_adpcm_table[filter][0]; |
|
|
|
|
f1 = xa_adpcm_table[filter][1]; |
|
|
|
|
|
|
|
|
|
for(j=0;j<28;j++) { |
|
|
|
|
d = in[16+i+j*4]; |
|
|
|
|
|
|
|
|
|
t = (signed char)d >> 4; |
|
|
|
|
s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6); |
|
|
|
|
CLAMP_TO_SHORT(s); |
|
|
|
|
*out = s; |
|
|
|
|
out += inc; |
|
|
|
|
s_2 = s_1; |
|
|
|
|
s_1 = s; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (inc==2) { /* stereo */ |
|
|
|
|
right->sample1 = s_1; |
|
|
|
|
right->sample2 = s_2; |
|
|
|
|
out -= 1; |
|
|
|
|
} else { |
|
|
|
|
left->sample1 = s_1; |
|
|
|
|
left->sample2 = s_2; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* DK3 ADPCM support macro */ |
|
|
|
|
#define DK3_GET_NEXT_NIBBLE() \ |
|
|
|
|
if (decode_top_nibble_next) \
|
|
|
|
@ -679,6 +762,17 @@ static int adpcm_decode_frame(AVCodecContext *avctx, |
|
|
|
|
src++; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case CODEC_ID_ADPCM_XA: |
|
|
|
|
c->status[0].sample1 = c->status[0].sample2 =
|
|
|
|
|
c->status[1].sample1 = c->status[1].sample2 = 0; |
|
|
|
|
while (buf_size >= 128) { |
|
|
|
|
xa_decode(samples, src, &c->status[0], &c->status[1],
|
|
|
|
|
avctx->channels); |
|
|
|
|
src += 128; |
|
|
|
|
samples += 28 * 8; |
|
|
|
|
buf_size -= 128; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
*data_size = 0; |
|
|
|
|
return -1; |
|
|
|
@ -731,5 +825,7 @@ ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); |
|
|
|
|
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); |
|
|
|
|
ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); |
|
|
|
|
ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); |
|
|
|
|
ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); |
|
|
|
|
ADPCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); |
|
|
|
|
|
|
|
|
|
#undef ADPCM_CODEC |
|
|
|
|