diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index fef47cf168cf0c6412f411d8974e31d7edb05d1c..1dc21c5f1129c6dd2ced14614acff4d7e3e2e543 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -2958,3 +2958,14 @@ cmplx CL_mult_32x16( cmplx input, cmplx_s coeff ) #endif return result; } + +Word64 Mpy_64_32( Word64 W_var1, Word32 L_var2 ) +{ + Word32 var1_l; + Word64 var_out; + var1_l = W_extract_l( W_var1 ); + var_out = W_mult0_32_32( L_and( var1_l, 1 ), L_var2 ); + var_out = W_mac_32_32( var_out, L_lshr( var1_l, 1 ), L_var2 ); + var_out = W_mac_32_32( W_shr( var_out, 31 ), W_extract_h( W_var1 ), L_var2 ); + return var_out; +} diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index c0f6df8cd0235135dedd8acc4cc59514fda978c0..cbd7838655e95b97380107cd4144c756ad1f2b3e 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -906,4 +906,24 @@ cmplx CL_scale_t( cmplx x, Word16 y ); cmplx CL_dscale_t( cmplx x, Word16 y1, Word16 y2 ); cmplx CL_mult_32x16( cmplx input, cmplx_s coeff ); + +/*! + \brief 64-bit/32-bit multiplication with shift + + This multiplication is similar to Mpy_32_32 except for the fact that the first argument + and the return type are Word64. The function performs the following operation: + + z = ((int128_t)x (int128_t)y) >> 31 + + where: + - x is a 64-bit signed integer + - y is a 32-bit signed integer + - z is a 64-bit signed integer + + \param W_var1 64-bit signed integer argument + \param L_var2 32-bit signed integer argument + \return 64-bit signed integer representing the result of the multiplication with shift +*/ +Word64 Mpy_64_32( Word64 W_var1, Word32 L_var2 ); + #endif /* __BASOP_UTIL_H__ */ diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 746f8d2ddd97fb88b4ee28ef8e8f272ff2ba14bc..6ad270a9ba77be68c23fb5a4a94037db8d1785a1 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -98,6 +98,38 @@ #define Q29 29 #define Q30 30 #define Q31 31 +#define Q32 32 +#define Q33 33 +#define Q34 34 +#define Q35 35 +#define Q36 36 +#define Q37 37 +#define Q38 38 +#define Q39 39 +#define Q40 40 +#define Q41 41 +#define Q42 42 +#define Q43 43 +#define Q44 44 +#define Q45 45 +#define Q46 46 +#define Q47 47 +#define Q48 48 +#define Q49 49 +#define Q50 50 +#define Q51 51 +#define Q52 52 +#define Q53 53 +#define Q54 54 +#define Q55 55 +#define Q56 56 +#define Q57 57 +#define Q58 58 +#define Q59 59 +#define Q60 60 +#define Q61 61 +#define Q62 62 +#define Q63 63 /*----------------------------------------------------------------------------------* * one in Q diff --git a/lib_com/ivas_filters_fx.c b/lib_com/ivas_filters_fx.c index 02e7b272a4beb7759335c88421067918f710763f..c7435ab40bec0d4ea304702d67974f543f3aa6a4 100644 --- a/lib_com/ivas_filters_fx.c +++ b/lib_com/ivas_filters_fx.c @@ -38,13 +38,6 @@ #include "ivas_rom_com.h" #include "ivas_prot_fx.h" -/*------------------------------------------------------------------------------------------* - * Local functions declaration - *------------------------------------------------------------------------------------------*/ - -static void ivas_iir_2_filter_fx( ivas_filters_process_state_t *filter_state, Word32 *pIn_Out_fx, const Word16 length, const Word16 stage, Word16 *pIn_Out_e ); - - /*-----------------------------------------------------------------------------------------* * Function ivas_filters_init() * @@ -71,27 +64,43 @@ void ivas_filters_init_fx( FOR( i = 0; i < IVAS_BIQUAD_FILT_LEN; i++ ) { filter_state->num_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[i]; - filter_state->num_e[IVAS_FILTER_STAGE_0][i] = 1; filter_state->den_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[i + IVAS_BIQUAD_FILT_LEN]; - filter_state->den_e[IVAS_FILTER_STAGE_0][i] = 1; move32(); move32(); +#ifdef OPT_2239_IVAS_FILTER_PROCESS + filter_state->num_shr[IVAS_FILTER_STAGE_0][i] = Q30 - Q31; + filter_state->den_shr[IVAS_FILTER_STAGE_0][i] = Q30 - Q31; + move16(); + move16(); +#else + filter_state->num_e[IVAS_FILTER_STAGE_0][i] = 1; + filter_state->den_e[IVAS_FILTER_STAGE_0][i] = 1; move16(); move16(); +#endif } - filter_state->state_fx[0][0] = 0; - filter_state->state_e[0][0] = 0; - filter_state->state_fx[0][1] = 0; - filter_state->state_e[0][1] = 0; - filter_state->state_fx[0][2] = 0; - filter_state->state_e[0][2] = 0; +#ifdef OPT_2239_IVAS_FILTER_PROCESS + filter_state->state_fx[IVAS_FILTER_STAGE_0][0] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][1] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][2] = 0; + move64(); + move64(); + move64(); +#else + filter_state->state_fx[IVAS_FILTER_STAGE_0][0] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][1] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][2] = 0; move32(); move32(); move32(); + filter_state->state_e[0][0] = 0; + filter_state->state_e[0][1] = 0; + filter_state->state_e[0][2] = 0; move16(); move16(); move16(); +#endif } ELSE { @@ -100,54 +109,208 @@ void ivas_filters_init_fx( FOR( i = 0; i < IVAS_BIQUAD_FILT_LEN; i++ ) { - filter_state->num_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[i]; - filter_state->num_e[IVAS_FILTER_STAGE_0][i] = filt_coeff_e[i]; filter_state->den_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[i + IVAS_BIQUAD_FILT_LEN]; - filter_state->den_e[IVAS_FILTER_STAGE_0][i] = filt_coeff_e[i + IVAS_BIQUAD_FILT_LEN]; filter_state->num_fx[IVAS_FILTER_STAGE_1][i] = filt_coeff_fx[i + IVAS_BIQUAD_FILT_LEN * 2]; - filter_state->num_e[IVAS_FILTER_STAGE_1][i] = filt_coeff_e[i + IVAS_BIQUAD_FILT_LEN * 2]; filter_state->den_fx[IVAS_FILTER_STAGE_1][i] = filt_coeff_fx[i + IVAS_BIQUAD_FILT_LEN * 3]; - filter_state->den_e[IVAS_FILTER_STAGE_1][i] = filt_coeff_e[i + IVAS_BIQUAD_FILT_LEN * 3]; move32(); move32(); move32(); move32(); +#ifdef OPT_2239_IVAS_FILTER_PROCESS + filter_state->num_shr[IVAS_FILTER_STAGE_0][i] = sub( sub( 31, filt_coeff_e[i + 0 * IVAS_BIQUAD_FILT_LEN] ), Q31 ); + filter_state->den_shr[IVAS_FILTER_STAGE_0][i] = sub( sub( 31, filt_coeff_e[i + 1 * IVAS_BIQUAD_FILT_LEN] ), Q31 ); + filter_state->num_shr[IVAS_FILTER_STAGE_1][i] = sub( sub( 31, filt_coeff_e[i + 2 * IVAS_BIQUAD_FILT_LEN] ), Q31 ); + filter_state->den_shr[IVAS_FILTER_STAGE_1][i] = sub( sub( 31, filt_coeff_e[i + 3 * IVAS_BIQUAD_FILT_LEN] ), Q31 ); + move16(); + move16(); + move16(); move16(); +#else + filter_state->num_e[IVAS_FILTER_STAGE_0][i] = filt_coeff_e[i]; + filter_state->den_e[IVAS_FILTER_STAGE_0][i] = filt_coeff_e[i + IVAS_BIQUAD_FILT_LEN]; + filter_state->num_e[IVAS_FILTER_STAGE_1][i] = filt_coeff_e[i + IVAS_BIQUAD_FILT_LEN * 2]; + filter_state->den_e[IVAS_FILTER_STAGE_1][i] = filt_coeff_e[i + IVAS_BIQUAD_FILT_LEN * 3]; move16(); move16(); move16(); + move16(); +#endif } - filter_state->state_fx[0][0] = 0; - filter_state->state_e[0][0] = 0; - filter_state->state_fx[0][1] = 0; - filter_state->state_e[0][1] = 0; - filter_state->state_fx[0][2] = 0; - filter_state->state_e[0][2] = 0; - filter_state->state_fx[1][0] = 0; - filter_state->state_e[1][0] = 0; - filter_state->state_fx[1][1] = 0; - filter_state->state_e[1][1] = 0; - filter_state->state_fx[1][2] = 0; - filter_state->state_e[1][2] = 0; +#ifdef OPT_2239_IVAS_FILTER_PROCESS + filter_state->state_fx[IVAS_FILTER_STAGE_0][0] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][1] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][2] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_1][0] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_1][1] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_1][2] = 0; + move64(); + move64(); + move64(); + move64(); + move64(); + move64(); +#else + filter_state->state_fx[IVAS_FILTER_STAGE_0][0] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][1] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_0][2] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_1][0] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_1][1] = 0; + filter_state->state_fx[IVAS_FILTER_STAGE_1][2] = 0; move32(); move32(); move32(); move32(); move32(); move32(); + filter_state->state_e[0][0] = 0; + filter_state->state_e[0][1] = 0; + filter_state->state_e[0][2] = 0; + filter_state->state_e[1][0] = 0; + filter_state->state_e[1][1] = 0; + filter_state->state_e[1][2] = 0; move16(); move16(); move16(); move16(); move16(); move16(); +#endif + } + + return; +} + +#ifdef OPT_2239_IVAS_FILTER_PROCESS +static Word64 ivas_iir_2_filter_fx( ivas_filters_process_state_t *filter_state, const Word16 stage, const Word64 in ); + +/*-----------------------------------------------------------------------------------------* + * Function ivas_iir_2_filter_fx() + * + * Process call for filtering a sample + *-----------------------------------------------------------------------------------------*/ + +static Word64 ivas_iir_2_filter_fx( + ivas_filters_process_state_t *filter_state, + const Word16 stage, + const Word64 in ) +{ + Word64 tmp_prod, tmp, out; + Word16 j; + + tmp_prod = W_shr( Mpy_64_32( in, filter_state->num_fx[stage][0] ), filter_state->num_shr[stage][0] ); + out = W_add( filter_state->state_fx[stage][0], tmp_prod ); + + FOR( j = 1; j < filter_state->filt_len; j++ ) + { + tmp_prod = W_shr( Mpy_64_32( in, filter_state->num_fx[stage][j] ), filter_state->num_shr[stage][j] ); + tmp = W_add( filter_state->state_fx[stage][j], tmp_prod ); + tmp_prod = W_shr( Mpy_64_32( out, filter_state->den_fx[stage][j] ), filter_state->den_shr[stage][j] ); + filter_state->state_fx[stage][j - 1] = W_sub( tmp, tmp_prod ); + move64(); + } + + return out; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_filter_process_fx32() + * + * Process call for filtering a signal + *-----------------------------------------------------------------------------------------*/ + +void ivas_filter_process_fx32( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word32 *pIn_Out_fx, /* i/o: signal subject to filtering */ + const Word16 length ) /* i : number of samples to filter */ +{ + Word64 in, out; + Word16 i; + + SWITCH( filter_state->order ) + { + case IVAS_FILTER_ORDER_1: + FOR( i = 0; i < length; i++ ) + { + in = W_deposit32_h( pIn_Out_fx[i] ); + + out = ivas_iir_2_filter_fx( filter_state, IVAS_FILTER_STAGE_0, in ); + + pIn_Out_fx[i] = W_extract_h( out ); + move32(); + } + BREAK; + case IVAS_FILTER_ORDER_4: + FOR( i = 0; i < length; i++ ) + { + in = W_deposit32_h( pIn_Out_fx[i] ); + + out = ivas_iir_2_filter_fx( filter_state, IVAS_FILTER_STAGE_0, in ); + out = ivas_iir_2_filter_fx( filter_state, IVAS_FILTER_STAGE_1, out ); + + pIn_Out_fx[i] = W_extract_h( out ); + move32(); + } + BREAK; + default: + BREAK; } return; } +/*-----------------------------------------------------------------------------------------* + * Function ivas_filter_process_fx64() + * + * Process call for filtering a signal + *-----------------------------------------------------------------------------------------*/ + +void ivas_filter_process_fx64( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word64 *pIn_Out_fx, /* i/o: signal subject to filtering */ + const Word16 length ) /* i : number of samples to filter */ + +{ + Word64 in, out; + Word16 i; + + SWITCH( filter_state->order ) + { + case IVAS_FILTER_ORDER_1: + FOR( i = 0; i < length; i++ ) + { + in = pIn_Out_fx[i]; + move64(); + + out = ivas_iir_2_filter_fx( filter_state, IVAS_FILTER_STAGE_0, in ); + + pIn_Out_fx[i] = out; + move64(); + } + BREAK; + case IVAS_FILTER_ORDER_4: + FOR( i = 0; i < length; i++ ) + { + in = pIn_Out_fx[i]; + move64(); + + out = ivas_iir_2_filter_fx( filter_state, IVAS_FILTER_STAGE_0, in ); + out = ivas_iir_2_filter_fx( filter_state, IVAS_FILTER_STAGE_1, out ); + + pIn_Out_fx[i] = out; + move64(); + } + BREAK; + default: + BREAK; + } + + return; +} + +#else +static void ivas_iir_2_filter_fx( ivas_filters_process_state_t *filter_state, Word32 *pIn_Out_fx, const Word16 length, const Word16 stage, Word16 *pIn_Out_e ); /*-----------------------------------------------------------------------------------------* * Function ivas_filter_process() @@ -158,7 +321,7 @@ void ivas_filters_init_fx( void ivas_filter_process_fx( ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ Word32 *pIn_Out_fx, /* i/o: signal subject to filtering Q(q_factor) */ - const Word16 length, /* i : filter order */ + const Word16 length, /* i : number of samples to filter */ Word16 q_factor ) { Word16 pIn_Out_e[L_FRAME_MAX]; @@ -196,11 +359,10 @@ void ivas_filter_process_fx( return; } - 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 */ + const Word16 length, /* i : number of samples to filter */ Word16 *pIn_Out_e ) { SWITCH( filter_state->order ) @@ -223,7 +385,6 @@ void ivas_filter_process_exp_fx( return; } - /*-----------------------------------------------------------------------------------------* * Function ivas_iir_2_filter() * @@ -285,3 +446,4 @@ static void ivas_iir_2_filter_fx( return; } +#endif diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index def4c806b0c503d9d922a5721a416b32e19b959d..3c7f54074230f62520bbf762357f19ca5516f3fc 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3802,20 +3802,33 @@ void ivas_lfe_enc_fx( BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ ); +#ifdef OPT_2239_IVAS_FILTER_PROCESS +void ivas_filter_process_fx32( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word32 *pIn_Out_fx, /* i : signal subject to filtering */ + const Word16 length /* i : number of samples to filter */ +); + +void ivas_filter_process_fx64( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word64 *pIn_Out_fx, /* i : signal subject to filtering */ + const Word16 length /* i : number of samples to filter */ +); +#else void ivas_filter_process_fx( ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ Word32 *pIn_Out_fx, /* i : signal subject to filtering */ - const Word16 length, /* i : filter order */ + const Word16 length, /* i : number of samples to filter */ 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 */ + const Word16 length, /* i : number of samples to filter */ Word16 *pIn_Out_e ); - +#endif ivas_error ivas_osba_enc_open_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ); @@ -6804,13 +6817,6 @@ void ivas_filters_init_fx( const Word16 order ); -void ivas_filter_process_fx( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - Word32 *pIn_Out_fx, /* i/o: signal subject to filtering Q(q_factor) */ - const Word16 length, /* i : filter order */ - Word16 q_factor -); - /*----------------------------------------------------------------------------------* * OSBA prototypes *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 65a081c9c9884c49cda797f81a9889a55959c056..0d4063777234d1488ebdf2355263b203f05f0cdd 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -656,10 +656,16 @@ typedef struct ivas_filters_process_state_t Word16 filt_len; Word32 num_fx[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; Word32 den_fx[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; +#ifdef OPT_2239_IVAS_FILTER_PROCESS + Word64 state_fx[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; + Word16 num_shr[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; + Word16 den_shr[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; +#else Word32 state_fx[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; Word16 num_e[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; Word16 den_e[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; Word16 state_e[IVAS_FILTER_MAX_STAGES][IVAS_BIQUAD_FILT_LEN]; +#endif } ivas_filters_process_state_t; diff --git a/lib_com/ivas_transient_det_fx.c b/lib_com/ivas_transient_det_fx.c index 39dee9314d95f5acf0175589995418fc9918d52f..ac285873c7f37fd37b8ccd33c67a29e7b4c7afe6 100644 --- a/lib_com/ivas_transient_det_fx.c +++ b/lib_com/ivas_transient_det_fx.c @@ -43,8 +43,12 @@ * Local constants *------------------------------------------------------------------------------------------*/ -#define IVAS_TDET_PARM_ENV_EPS ( 1e-5f ) +#define IVAS_TDET_PARM_ENV_EPS ( 1e-5f ) +#ifdef OPT_2239_IVAS_FILTER_PROCESS +#define IVAS_TDET_PARM_ENV_EPS_fx ( ( (Word64) 21474 ) << 12 ) // Q11+32 +#else #define IVAS_TDET_PARM_ENV_EPS_fx 21474 // Q31 +#endif #define IVAS_TDET_DUCK_MULT_FAC ( 590558003 ) // Q29 #define IVAS_TDET_PARM_TRANS_THR ( 107374182 ) // Q30 @@ -381,8 +385,6 @@ void ivas_td_decorr_get_ducking_gains_fx( const Word16 tdet_flag /*Q0*/ ) { 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*/ @@ -394,6 +396,79 @@ void ivas_td_decorr_get_ducking_gains_fx( Word32 duck_mult_fac = hTranDet->duck_mult_fac; /*Q29*/ move32(); +#ifdef OPT_2239_IVAS_FILTER_PROCESS + Word64 e_fast_fx[L_FRAME48k], e_slow_fx[L_FRAME48k]; + Word32 fast_fx, slow_fx; + Word16 fast_e, slow_e; + + FOR( i = 0; i < frame_len; i++ ) + { + e_fast_fx[i] = W_deposit32_h( pIn_pcm[i] ); /*Q43*/ + move64(); + } + + /* env hpf */ + ivas_filter_process_fx64( &hTranDet->env_hpf, e_fast_fx, frame_len ); /*Q43*/ + + FOR( i = 0; i < frame_len; i++ ) + { + e_fast_fx[i] = W_add( W_abs( e_fast_fx[i] ), IVAS_TDET_PARM_ENV_EPS_fx ); + move64(); + e_slow_fx[i] = e_fast_fx[i]; + move64(); + } + + /* env fast*/ + ivas_filter_process_fx64( &hTranDet->env_fast, e_fast_fx, frame_len ); /*Q43*/ + + /* env slow */ + ivas_filter_process_fx64( &hTranDet->env_slow, e_slow_fx, frame_len ); /*Q43*/ + + IF( tdet_flag ) + { + FOR( i = 0; i < frame_len; i++ ) + { + fast_e = W_norm( e_fast_fx[i] ); + fast_fx = W_extract_h( W_shl( e_fast_fx[i], fast_e ) ); /*Q43 + fast_e - 32 = Q11 + fast_e*/ + fast_e = sub( 20, fast_e ); /*exp: 31 - (Q11 + fast_e) = 20 - fast_e*/ + slow_e = W_norm( e_slow_fx[i] ); + slow_fx = W_extract_h( W_shl( e_slow_fx[i], slow_e ) ); /*Q43 + fast_e - 32 = Q11 + slow_e*/ + slow_e = sub( 20, slow_e ); /*exp: 31 - (Q11 + slow_e) = 20 - slow_e*/ + + in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, slow_fx, slow_e, fast_fx, fast_e, duck_mult_fac ); /*Q30*/ + pIn_duck_gains[i] = in_duck_gain; /*Q30*/ + move32(); + } + hTranDet->in_duck_gain = in_duck_gain; /*Q30*/ + move32(); + } + ELSE + { + FOR( i = 0; i < frame_len; i++ ) + { + fast_e = W_norm( e_fast_fx[i] ); + fast_fx = W_extract_h( W_shl( e_fast_fx[i], fast_e ) ); /*Q43 + fast_e - 32 = Q11 + fast_e*/ + fast_e = sub( 20, fast_e ); /*exp: 31 - (Q11 + fast_e) = 20 - fast_e*/ + slow_e = W_norm( e_slow_fx[i] ); + slow_fx = W_extract_h( W_shl( e_slow_fx[i], slow_e ) ); /*Q43 + fast_e - 32 = Q11 + slow_e*/ + slow_e = sub( 20, slow_e ); /*exp: 31 - (Q11 + slow_e) = 20 - slow_e*/ + + in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, slow_fx, slow_e, fast_fx, fast_e, 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, fast_fx, fast_e, slow_fx, slow_e, duck_mult_fac ); /*Q30*/ + pOut_duck_gains[i] = out_duck_gain; /*Q30*/ + move32(); + } + hTranDet->in_duck_gain = in_duck_gain; /*Q30*/ + move32(); + hTranDet->out_duck_gain = out_duck_gain; /*Q30*/ + move32(); + } +#else + Word32 e_fast_fx[L_FRAME48k], e_slow_fx[L_FRAME48k]; + Word16 e_fast_e[L_FRAME48k], e_slow_e[L_FRAME48k]; + Copy32( pIn_pcm, e_fast_fx, frame_len ); /*Q11*/ set16_fx( e_fast_e, 31 - Q11, L_FRAME48k ); @@ -446,6 +521,7 @@ void ivas_td_decorr_get_ducking_gains_fx( hTranDet->out_duck_gain = out_duck_gain; /*Q30*/ move32(); } +#endif return; } diff --git a/lib_com/options.h b/lib_com/options.h index 259e88697a2cd26089e39e1c67d21c738df49e3a..bf55847d1b1bc5d7954e48d301fd0e0ee673f2b8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -109,6 +109,7 @@ #define OPT_2181_MATRIX_TRANSP_1_MUL /* Dolby: Issue 2181, optimize matrixTransp1Mul_fx. */ #define OPT_2182_MATRIX_SCALE_OPS /* Dolby: Issue 2181, move matrix scale operations outside mul operations. */ #define OPT_2185_MATRIX_OUT_SCALING /* Dolby: Issue 2185, optimize matrix-mul output-format. */ +#define OPT_2239_IVAS_FILTER_PROCESS /* Dolby: Issue 2239, optimize ivas_filter_process_fx. */ /* #################### End BASOP optimization switches ############################ */ diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index 74d8de662ea8aadd99c86363b514d42e8164fe1e..1078a1a022a651c0ee3d2c6da9776ce054bccf94 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -408,7 +408,11 @@ void ivas_lfe_dec_fx( IF( hLFE->filter_state.order > 0 ) { /* Low Pass Filter */ +#ifdef OPT_2239_IVAS_FILTER_PROCESS + ivas_filter_process_fx32( &hLFE->filter_state, output_lfe_ch, output_frame ); +#else ivas_filter_process_fx( &hLFE->filter_state, output_lfe_ch, output_frame, q_out ); +#endif } /* add delay to make overall max(block_offset, 11.5) */ diff --git a/lib_enc/ivas_lfe_enc_fx.c b/lib_enc/ivas_lfe_enc_fx.c index 96959c9dd46fe0d60f391fcbb4c5da5f0e2d3f50..96fdc7b5cba11def31d8cecdda6ee10a6c5a1a4a 100644 --- a/lib_enc/ivas_lfe_enc_fx.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -684,7 +684,11 @@ void ivas_lfe_lpf_enc_apply_fx( const Word16 input_frame /* i : input frame length per channel */ ) { +#ifdef OPT_2239_IVAS_FILTER_PROCESS + ivas_filter_process_fx32( hLfeLpf, data_lfe_ch, input_frame ); +#else ivas_filter_process_fx( hLfeLpf, data_lfe_ch, input_frame, (Word16) Q11 ); +#endif return; }