diff --git a/lib_com/options.h b/lib_com/options.h index 46e386b5c1a5bfdeac0a311d7a2bc71497cce205..9765329e56ad40a1bfa16352294d7a7878e48c36 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -93,6 +93,7 @@ #define FIX_1996_MASKING_NOISE /* Dlb: Heavy precision loss in ola buffers causing discontinuity*/ #define FIX1998_APA_EXEC_SCALING /* FhG: fix scaling of apa_exec_ivas_fx(); avoid continuously worse scaling with previous data */ #define FIX2007_BASSPSFILTER_OVERFLOW /* FhG: use saturing operator, to avoid overflow in bass_psfilter_fx() */ +#define FIX_ISSUE_2004_LPC_SHB_SAT /* Dolby: Issue 2004: prevent saturation of the LPC SHB filter */ #define FIX_2009_HIGH_NOISE_FLOOR_FOR_FX_DEC /* FhG: Corrected the q_input in the input of generate_masking_noise_dirac_ivas_fx() */ /* #################### Start BASOP porting switches ############################ */ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 490d80aae077122702158ca499a250bd948a3a8d..e3f318127093acef6ff2b88a7dba21a86afb2d44 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -3161,7 +3161,25 @@ void swb_tbe_enc_ivas_fx( enerG = Enr_1_Az_fx( lpc_shb1, 2 * L_SUBFR ); /* Q3 */ /* if the LP gain is greater than a threshold, avoid saturation */ +#ifdef FIX_ISSUE_2004_LPC_SHB_SAT + Word16 flag_sat = 0; + Word16 lpc_shb_fx0_req_shift = sub( norm_s( lpc_shb_fx[0] ), 2 ); + IF( GT_16( lpc_shb_fx0_req_shift, 0 ) ) + { + FOR( i = 1; i <= LPC_SHB_ORDER; i++ ) + { + IF( LT_16( norm_s( lpc_shb_fx[i] ), lpc_shb_fx0_req_shift ) ) + { + flag_sat = 1; + break; + } + } + } + + IF( GT_16( enerG, 256 /* 32.0 in Q3 */ ) || flag_sat ) +#else IF( GT_16( enerG, 256 /*32 Q3*/ ) ) +#endif { set16_fx( lpc_shb_fx, 0, LPC_SHB_ORDER + 1 ); E_LPC_lev_dur( R_h, R_l, lpc_shb_fx, LepsP, 2, NULL ); /* LPC in Q14 */ @@ -3903,7 +3921,7 @@ void swb_tbe_enc_ivas_fx( #ifdef ISSUE_1867_replace_overflow_libenc shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ #else - shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ + shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ #endif move16(); } @@ -3925,7 +3943,7 @@ void swb_tbe_enc_ivas_fx( #ifdef ISSUE_1867_replace_overflow_libenc L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), tmp ); /* Q31-exp */ #else - L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ + L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ #endif tmp = sub( 32767 /*1.0f Q15*/, tmp ); L_tmp = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); @@ -3933,7 +3951,7 @@ void swb_tbe_enc_ivas_fx( #ifdef ISSUE_1867_replace_overflow_libenc shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ #else - shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ + shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ #endif move16(); } @@ -3946,7 +3964,7 @@ void swb_tbe_enc_ivas_fx( #ifdef ISSUE_1867_replace_overflow_libenc L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), tmp ); /* Q31-exp */ #else - L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ + L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ #endif tmp = sub( 32767 /*1.0f Q15*/, tmp ); L_tmp = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); @@ -3954,7 +3972,7 @@ void swb_tbe_enc_ivas_fx( #ifdef ISSUE_1867_replace_overflow_libenc shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ #else - shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ + shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ #endif move16(); } @@ -4467,7 +4485,7 @@ void swb_tbe_enc_ivas_fx( #ifdef ISSUE_1867_replace_overflow_libenc tmp = round_fx_sat( L_shl_sat( L_tmp, 31 - ( 7 - exp ) ) ); /* Q15 */ #else - tmp = round_fx_o( L_shl_o( L_tmp, 31 - ( 7 - exp ), &Overflow ), &Overflow ); /* Q15 */ + tmp = round_fx_o( L_shl_o( L_tmp, 31 - ( 7 - exp ), &Overflow ), &Overflow ); /* Q15 */ #endif } tmp = s_min( tmp, 32767 /*1.0f Q15*/ ); @@ -4744,10 +4762,10 @@ static void EstimateSHBFrameGain_fx( sig = round_fx_sat( Mult_32_16( mod_syn[i], win_shb[i] ) ); /*Q_synSHB */ synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2*Q_synSHB */ #else - sig = mult_ro( oriSHB[i], win_shb[i], &Overflow ); /* Q_oriSHB */ - oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_orisHB*/ - sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[i] ), &Overflow ); /*Q_synSHB */ - synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_synSHB */ + sig = mult_ro( oriSHB[i], win_shb[i], &Overflow ); /* Q_oriSHB */ + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_orisHB*/ + sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[i] ), &Overflow ); /*Q_synSHB */ + synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_synSHB */ #endif } @@ -4758,9 +4776,9 @@ static void EstimateSHBFrameGain_fx( sig = round_fx_sat( mod_syn[i] ); /* Q_oriSHB */ synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2*Q_oriSHB */ #else - oriNrg = L_mac0_o( oriNrg, oriSHB[i], oriSHB[i], &Overflow ); /* 2*Q_oriSHB */ - sig = round_fx_o( mod_syn[i], &Overflow ); /* Q_oriSHB */ - synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ + oriNrg = L_mac0_o( oriNrg, oriSHB[i], oriSHB[i], &Overflow ); /* 2*Q_oriSHB */ + sig = round_fx_o( mod_syn[i], &Overflow ); /* Q_oriSHB */ + synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ #endif } @@ -4773,8 +4791,8 @@ static void EstimateSHBFrameGain_fx( sig = round_fx_sat( Mult_32_16( mod_syn[i], win_shb[l_frame + l_shb_lahead - 1 - i] ) ); /* Q_oriSHB */ synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2*Q_oriSHB */ #else - sig = mult_ro( oriSHB[i], win_shb[l_frame + l_shb_lahead - 1 - i], &Overflow ); /* Q_oriSHB */ - oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ + sig = mult_ro( oriSHB[i], win_shb[l_frame + l_shb_lahead - 1 - i], &Overflow ); /* Q_oriSHB */ + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[l_frame + l_shb_lahead - 1 - i] ), &Overflow ); /* Q_oriSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */