diff --git a/lib_com/options.h b/lib_com/options.h index a72b234fcbbe23021e797e5df5ef954411586987..0bf9a27d6c8aa6f658ddb56cef542eba27f42580 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -107,7 +107,7 @@ #define FIX_1962_FORMAT_CONV_SPECTRAL_DIFF /* FhG: Improved precision of targetEnergy in ivas_ls_setup_conversion_process_mdct_fx() */ #define FIX_2003_CON_TCX_OVERFLOW /* FhG: Use a dynamic scaling factor for the synth buffer at the output of con_tcx_ivas_fx() */ #define OPT_TCXLTP_FILTER_LOOP /* FhG: optimize loop in tcx_ltp_synth_filter */ - +#define FIX_2602_NONBE_SAT_IN_SWB_TBE_SCALE /* Dolby: fix for issue 2026: Saturation in SWB TBE re-scaling function preventing StereoDownmix complexity job to complete */ /* #################### Start BASOP porting switches ############################ */ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 0de93c9375e25eaec4129c64295af52d17564ef2..0a8113c1d42b03bcdb6785876d49e480eafdc474 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -2703,22 +2703,31 @@ void swb_tbe_dec_fx( Lscale = root_a_over_b_fx( curr_pow, shl( Q_bwe_exc, 1 ), prev_pow, shl( Q_bwe_exc, 1 ), &exp ); + +#ifdef FIX_2602_NONBE_SAT_IN_SWB_TBE_SCALE + /* Note, that the code below comes from the legacy EVS decoder but it leads to saturation issues in L_shl(). Thus, it's been fixed by adding _sat to L_shl() and round_fx() functions. However, this might break the bit-exactness with EVS for some corner case-signals. */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } +#else FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { L_tmp = Mult_32_16( Lscale, shaped_shb_excitation[i] ); /* Q_bwe_exc + (31-exp) - 15 */ shaped_shb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ move16(); } +#endif + IF( exp < 0 ) { Lscale = L_shl( Lscale, exp ); exp = 0; move16(); } - /* - code for EVS and IVAS are basically identical with the exception of i_mult_sat() which has precision issues - thus is was replaced for IVAS and kept for EVS, in order to keep EVS BE to test sequences and legacy implementations - */ + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { FOR( ; i < L_SHB_LAHEAD + 10; i++ )