@ -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 :