@ -815,14 +815,105 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
/* spectral extension strategy */
if ( s - > eac3 & & ( ! blk | | get_bits1 ( gbc ) ) ) {
if ( get_bits1 ( gbc ) ) {
av_log_missing_feature ( s - > avctx , " Spectral extension " , 1 ) ;
s - > spx_in_use = get_bits1 ( gbc ) ;
if ( s - > spx_in_use ) {
int dst_start_freq , dst_end_freq , src_start_freq ,
start_subband , end_subband ;
/* determine which channels use spx */
if ( s - > channel_mode = = AC3_CHMODE_MONO ) {
s - > channel_uses_spx [ 1 ] = 1 ;
} else {
for ( ch = 1 ; ch < = fbw_channels ; ch + + )
s - > channel_uses_spx [ ch ] = get_bits1 ( gbc ) ;
}
/* get the frequency bins of the spx copy region and the spx start
and end subbands */
dst_start_freq = get_bits ( gbc , 2 ) ;
start_subband = get_bits ( gbc , 3 ) + 2 ;
if ( start_subband > 7 )
start_subband + = start_subband - 7 ;
end_subband = get_bits ( gbc , 3 ) + 5 ;
if ( end_subband > 7 )
end_subband + = end_subband - 7 ;
dst_start_freq = dst_start_freq * 12 + 25 ;
src_start_freq = start_subband * 12 + 25 ;
dst_end_freq = end_subband * 12 + 25 ;
/* check validity of spx ranges */
if ( start_subband > = end_subband ) {
av_log ( s - > avctx , AV_LOG_ERROR , " invalid spectral extension "
" range (%d >= %d) \n " , start_subband , end_subband ) ;
return - 1 ;
}
/* TODO: parse spectral extension strategy info */
if ( dst_start_freq > = src_start_freq ) {
av_log ( s - > avctx , AV_LOG_ERROR , " invalid spectral extension "
" copy start bin (%d >= %d) \n " , dst_start_freq , src_start_freq ) ;
return - 1 ;
}
s - > spx_dst_start_freq = dst_start_freq ;
s - > spx_src_start_freq = src_start_freq ;
s - > spx_dst_end_freq = dst_end_freq ;
decode_band_structure ( gbc , blk , s - > eac3 , 0 ,
start_subband , end_subband ,
ff_eac3_default_spx_band_struct ,
& s - > num_spx_bands ,
s - > spx_band_sizes ) ;
} else {
for ( ch = 1 ; ch < = fbw_channels ; ch + + ) {
s - > channel_uses_spx [ ch ] = 0 ;
s - > first_spx_coords [ ch ] = 1 ;
}
}
}
/* TODO: spectral extension coordinates */
/* spectral extension coordinates */
if ( s - > spx_in_use ) {
for ( ch = 1 ; ch < = fbw_channels ; ch + + ) {
if ( s - > channel_uses_spx [ ch ] ) {
if ( s - > first_spx_coords [ ch ] | | get_bits1 ( gbc ) ) {
float spx_blend ;
int bin , master_spx_coord ;
s - > first_spx_coords [ ch ] = 0 ;
spx_blend = get_bits ( gbc , 5 ) * ( 1.0f / 32 ) ;
master_spx_coord = get_bits ( gbc , 2 ) * 3 ;
bin = s - > spx_src_start_freq ;
for ( bnd = 0 ; bnd < s - > num_spx_bands ; bnd + + ) {
int bandsize ;
int spx_coord_exp , spx_coord_mant ;
float nratio , sblend , nblend , spx_coord ;
/* calculate blending factors */
bandsize = s - > spx_band_sizes [ bnd ] ;
nratio = ( ( float ) ( ( bin + ( bandsize > > 1 ) ) ) / s - > spx_dst_end_freq ) - spx_blend ;
nratio = av_clipf ( nratio , 0.0f , 1.0f ) ;
nblend = sqrtf ( 3.0f * nratio ) ; // noise is scaled by sqrt(3) to give unity variance
sblend = sqrtf ( 1.0f - nratio ) ;
bin + = bandsize ;
/* decode spx coordinates */
spx_coord_exp = get_bits ( gbc , 4 ) ;
spx_coord_mant = get_bits ( gbc , 2 ) ;
if ( spx_coord_exp = = 15 ) spx_coord_mant < < = 1 ;
else spx_coord_mant + = 4 ;
spx_coord_mant < < = ( 25 - spx_coord_exp - master_spx_coord ) ;
spx_coord = spx_coord_mant * ( 1.0f / ( 1 < < 23 ) ) ;
/* multiply noise and signal blending factors by spx coordinate */
s - > spx_noise_blend [ ch ] [ bnd ] = nblend * spx_coord ;
s - > spx_signal_blend [ ch ] [ bnd ] = sblend * spx_coord ;
}
}
} else {
s - > first_spx_coords [ ch ] = 1 ;
}
}
}
/* coupling strategy */
if ( s - > eac3 ? s - > cpl_strategy_exists [ blk ] : get_bits1 ( gbc ) ) {
@ -859,9 +950,9 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
s - > phase_flags_in_use = get_bits1 ( gbc ) ;
/* coupling frequency range */
/* TODO: modify coupling end freq if spectral extension is used */
cpl_start_subband = get_bits ( gbc , 4 ) ;
cpl_end_subband = get_bits ( gbc , 4 ) + 3 ;
cpl_end_subband = s - > spx_in_use ? ( s - > spx_src_start_freq - 37 ) / 12 :
get_bits ( gbc , 4 ) + 3 ;
if ( cpl_start_subband > = cpl_end_subband ) {
av_log ( s - > avctx , AV_LOG_ERROR , " invalid coupling range (%d >= %d) \n " ,
cpl_start_subband , cpl_end_subband ) ;
@ -934,8 +1025,11 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
if ( channel_mode = = AC3_CHMODE_STEREO ) {
if ( ( s - > eac3 & & ! blk ) | | get_bits1 ( gbc ) ) {
s - > num_rematrixing_bands = 4 ;
if ( cpl_in_use & & s - > start_freq [ CPL_CH ] < = 61 )
if ( cpl_in_use & & s - > start_freq [ CPL_CH ] < = 61 ) {
s - > num_rematrixing_bands - = 1 + ( s - > start_freq [ CPL_CH ] = = 37 ) ;
} else if ( s - > spx_in_use & & s - > spx_src_start_freq < = 61 ) {
s - > num_rematrixing_bands - - ;
}
for ( bnd = 0 ; bnd < s - > num_rematrixing_bands ; bnd + + )
s - > rematrixing_flags [ bnd ] = get_bits1 ( gbc ) ;
} else if ( ! blk ) {
@ -960,6 +1054,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
int prev = s - > end_freq [ ch ] ;
if ( s - > channel_in_cpl [ ch ] )
s - > end_freq [ ch ] = s - > start_freq [ CPL_CH ] ;
else if ( s - > channel_uses_spx [ ch ] )
s - > end_freq [ ch ] = s - > spx_src_start_freq ;
else {
int bandwidth_code = get_bits ( gbc , 6 ) ;
if ( bandwidth_code > 60 ) {
@ -1156,8 +1252,6 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
/* TODO: generate enhanced coupling coordinates and uncouple */
/* TODO: apply spectral extension */
/* recover coefficients if rematrixing is in use */
if ( s - > channel_mode = = AC3_CHMODE_STEREO )
do_rematrixing ( s ) ;
@ -1173,6 +1267,11 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
s - > dsp . int32_to_float_fmul_scalar ( s - > transform_coeffs [ ch ] , s - > fixed_coeffs [ ch ] , gain , 256 ) ;
}
/* apply spectral extension to high frequency bins */
if ( s - > spx_in_use ) {
ff_eac3_apply_spectral_extension ( s ) ;
}
/* downmix and MDCT. order depends on whether block switching is used for
any channel in this block . this is because coefficients for the long
and short transforms cannot be mixed . */