From dccea68aac5805e9349a27041ebba46318308c84 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 19 Nov 2024 14:35:02 +0530 Subject: [PATCH] Fix for 3GPP issue 951: Higher noise floor observed in SBA fixed-point output link #951 --- lib_com/ivas_filters.c | 27 +++++++++++++++++++ lib_com/ivas_prot_fx.h | 6 +++++ lib_com/ivas_transient_det.c | 50 +++++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/lib_com/ivas_filters.c b/lib_com/ivas_filters.c index 0ef0960d7..7d67ec9c4 100644 --- a/lib_com/ivas_filters.c +++ b/lib_com/ivas_filters.c @@ -279,6 +279,33 @@ void ivas_filter_process_fx( } #endif +void ivas_filter_process_exp_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word32 *pIn_Out_fx, /* i/o: signal subject to filtering (exp[i] : pIn_out_e[i]) */ + const Word16 length, /* i : filter order */ + Word16 *pIn_Out_e ) +{ + SWITCH( filter_state->order ) + { + case IVAS_FILTER_ORDER_1: + case IVAS_FILTER_ORDER_2: + ivas_iir_2_filter_fx( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, pIn_Out_e ); + /* Scale pIn_Out_fx back to input Q */ + BREAK; + case IVAS_FILTER_ORDER_4: + /* biquad-1 */ + ivas_iir_2_filter_fx( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, pIn_Out_e ); + /* biquad-2 */ + ivas_iir_2_filter_fx( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_1, pIn_Out_e ); + /* Scale pIn_Out_fx back to input Q */ + BREAK; + default: + BREAK; + } + + return; +} + /*-----------------------------------------------------------------------------------------* * Function ivas_iir_2_filter() diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index e383aeea0..fe45bafb6 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3753,6 +3753,12 @@ void ivas_filter_process_fx( const Word16 length, /* i : filter order */ Word16 q_factor ); +void ivas_filter_process_exp_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word32 *pIn_Out_fx, /* i/o: signal subject to filtering (exp[i] : pIn_out_e[i]) */ + const Word16 length, /* i : filter order */ + Word16 *pIn_Out_e ); + ivas_error ivas_osba_enc_open_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ); diff --git a/lib_com/ivas_transient_det.c b/lib_com/ivas_transient_det.c index a41e5ea92..db0a9ca81 100644 --- a/lib_com/ivas_transient_det.c +++ b/lib_com/ivas_transient_det.c @@ -554,15 +554,18 @@ static float ivas_calc_duck_gain( static Word32 ivas_calc_duck_gain_fx( const Word32 duck_gain, /*Q30*/ const Word32 duck_coeff, /*Q30*/ - const Word32 env_1, /*Q14*/ - const Word32 env_2, /*Q14*/ + const Word32 env_1, /*exp : env1_e*/ + const Word16 env1_e, + const Word32 env_2, /*exp : env2_e*/ + const Word16 env2_e, const Word32 duck_mult_fac /*Q29*/ ) { - Word32 duck_gain_out; + Word32 duck_gain_out, L_tmp; + Word16 tmp_e; duck_gain_out = L_add( L_shl( Mpy_32_32( L_sub( duck_gain, ONE_IN_Q30 ), duck_coeff ), Q1 ), ONE_IN_Q30 ); /*Q30*/ - IF( LT_32( Mpy_32_32( duck_mult_fac, env_1 ), Mpy_32_32( L_shr( duck_gain_out, 1 ), env_2 ) ) ) + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( Mpy_32_32( duck_mult_fac, env_1 ), add( 2, env1_e ), Mpy_32_32( duck_gain_out, env_2 ), add( 1, env2_e ) ), -1 ) ) { test(); IF( ( env_1 == 0 ) || ( env_2 == 0 ) ) @@ -572,8 +575,11 @@ static Word32 ivas_calc_duck_gain_fx( } ELSE { - duck_gain_out = Mpy_32_32( duck_mult_fac, L_shl( (Word32) ( divide3232( env_1, env_2 ) ), Q16 ) ); /*Q29*/ - duck_gain_out = L_shl( duck_gain_out, Q1 ); /*Q30*/ + L_tmp = BASOP_Util_Divide3232_Scale_cadence( env_1, env_2, &tmp_e ); + L_tmp = L_shl( L_tmp, add( sub( env1_e, env2_e ), tmp_e ) ); + + duck_gain_out = Mpy_32_32( duck_mult_fac, L_tmp ); /*Q29*/ + duck_gain_out = L_shl( duck_gain_out, Q1 ); /*Q30*/ } } @@ -660,9 +666,9 @@ void ivas_td_decorr_get_ducking_gains_fx( const Word16 frame_len, /*Q0*/ const Word16 tdet_flag /*Q0*/ ) { - Word16 i, q = Q14; - move16(); + Word16 i; Word32 e_fast_fx[L_FRAME48k], e_slow_fx[L_FRAME48k]; + Word16 e_fast_e[L_FRAME48k], e_slow_e[L_FRAME48k]; Word32 in_duck_gain = hTranDet->in_duck_gain; /*Q30*/ move32(); Word32 out_duck_gain = hTranDet->out_duck_gain; /*Q30*/ @@ -676,31 +682,35 @@ void ivas_td_decorr_get_ducking_gains_fx( Copy32( pIn_pcm, e_fast_fx, frame_len ); /*Q11*/ + set16_fx( e_fast_e, 31 - Q11, L_FRAME48k ); + /* env hpf */ - ivas_filter_process_fx( &hTranDet->env_hpf, e_fast_fx, frame_len, q ); + ivas_filter_process_exp_fx( &hTranDet->env_hpf, e_fast_fx, frame_len, e_fast_e ); - Word16 q_factor_diff = sub( 31, q ); FOR( i = 0; i < frame_len; i++ ) { - e_fast_fx[i] = L_add( L_abs( e_fast_fx[i] ), L_shr( IVAS_TDET_PARM_ENV_EPS_fx, q_factor_diff ) ); /*Q14*/ + // e_fast_fx[i] = L_add( L_abs( e_fast_fx[i] ), L_shr( IVAS_TDET_PARM_ENV_EPS_fx, q_factor_diff ) ); /*Q14*/ + e_fast_fx[i] = BASOP_Util_Add_Mant32Exp( L_abs( e_fast_fx[i] ), e_fast_e[i], IVAS_TDET_PARM_ENV_EPS_fx, 0, &e_fast_e[i] ); move32(); - e_slow_fx[i] = e_fast_fx[i]; /*Q14*/ + e_slow_fx[i] = e_fast_fx[i]; move32(); + e_slow_e[i] = e_fast_e[i]; + move16(); } /* env fast*/ - ivas_filter_process_fx( &hTranDet->env_fast, e_fast_fx, frame_len, q ); + ivas_filter_process_exp_fx( &hTranDet->env_fast, e_fast_fx, frame_len, e_fast_e ); /* env slow */ - ivas_filter_process_fx( &hTranDet->env_slow, e_slow_fx, frame_len, q ); + ivas_filter_process_exp_fx( &hTranDet->env_slow, e_slow_fx, frame_len, e_slow_e ); IF( tdet_flag ) { FOR( i = 0; i < frame_len; i++ ) { - in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, e_slow_fx[i], e_fast_fx[i], duck_mult_fac ); /*Q30*/ - pIn_duck_gains[i] = in_duck_gain; /*Q30*/ + in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, e_slow_fx[i], e_slow_e[i], e_fast_fx[i], e_fast_e[i], duck_mult_fac ); /*Q30*/ + pIn_duck_gains[i] = in_duck_gain; /*Q30*/ move32(); } hTranDet->in_duck_gain = in_duck_gain; /*Q30*/ @@ -710,11 +720,11 @@ void ivas_td_decorr_get_ducking_gains_fx( { FOR( i = 0; i < frame_len; i++ ) { - in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, e_slow_fx[i], e_fast_fx[i], duck_mult_fac ); /*Q30*/ - pIn_duck_gains[i] = in_duck_gain; /*Q30*/ + in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, e_slow_fx[i], e_slow_e[i], e_fast_fx[i], e_fast_e[i], duck_mult_fac ); /*Q30*/ + pIn_duck_gains[i] = in_duck_gain; /*Q30*/ move32(); - out_duck_gain = ivas_calc_duck_gain_fx( out_duck_gain, out_duck_coeff, e_fast_fx[i], e_slow_fx[i], duck_mult_fac ); /*Q30*/ - pOut_duck_gains[i] = out_duck_gain; /*Q30*/ + out_duck_gain = ivas_calc_duck_gain_fx( out_duck_gain, out_duck_coeff, e_fast_fx[i], e_fast_e[i], e_slow_fx[i], e_slow_e[i], duck_mult_fac ); /*Q30*/ + pOut_duck_gains[i] = out_duck_gain; /*Q30*/ move32(); } hTranDet->in_duck_gain = in_duck_gain; /*Q30*/ -- GitLab