diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c index 769af269246265885b09319b958a202aeb98c982..e84336385c3a29c1783e912cbaade1fe46edb9f4 100644 --- a/lib_com/gs_gains_fx.c +++ b/lib_com/gs_gains_fx.c @@ -70,12 +70,19 @@ static Word16 VDQ_vec_fx( Word16 *Qvec_out_fx, const Word16 *mean_dic_fx, const /* _ None */ /*========================================================================*/ +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX +Word16 Comp_and_apply_gain_fx( +#else void Comp_and_apply_gain_fx( +#endif Word16 exc_diffQ[], /* i/o: Quantized excitation */ Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */ Word16 Ener_per_bd_yQ[], /* i/o: Ener per band for norm vector i->Q13/o->Q13 */ Word16 Mbands_gn, /* i : number of bands */ const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */ +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX + const Word16 Flag_adj_q_exc, /* i : Flag allowing Q_exc adjustment */ +#endif Word16 Qexc_diff, Word16 Q_exc ) { @@ -83,6 +90,11 @@ void Comp_and_apply_gain_fx( Word16 StartBin, NB_Qbins; Word16 y_gain; Word16 L16, frac, exp1, tmp_exp; +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX + Word16 Q_adapt; + Word16 Q_exc_diffQ[L_FRAME16k]; + Word32 exc_diffQ32[L_FRAME16k]; +#endif Word32 L32; /* Recreate excitation for local synthesis and decoder */ @@ -92,6 +104,7 @@ void Comp_and_apply_gain_fx( move16(); tmp_exp = add( 14, sub( Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/ + FOR( i_band = 0; i_band < Mbands_gn; i_band++ ) { StartBin = add( StartBin, NB_Qbins ); @@ -126,17 +139,55 @@ void Comp_and_apply_gain_fx( Ener_per_bd_yQ[i_band] = shl_sat( y_gain, sub( exp1, 13 ) ); move16(); /*Q1 */ tmp_exp = add( add( exp1, 1 ), sub( Q_exc, Qexc_diff ) ); - - FOR( i = StartBin; i < NB_Qbins + StartBin; i++ ) +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX + IF( Flag_adj_q_exc != 0 ) { - L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */ - exc_diffQ[i] = round_fx_sat( L_shl_sat( L32, tmp_exp ) ); /*Q_exc */ - move16(); + FOR( i = StartBin; i < NB_Qbins + StartBin; i++ ) + { + exc_diffQ32[i] = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */ + move32(); + Q_exc_diffQ[i] = Q_exc; + if ( exc_diffQ[i] ) + { + Q_exc_diffQ[i] = sub( Q_exc_diffQ[i], tmp_exp ); + move16(); + } + } + } + ELSE +#endif + { + FOR( i = StartBin; i < NB_Qbins + StartBin; i++ ) + { + L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */ + exc_diffQ[i] = round_fx_sat( L_shl_sat( L32, tmp_exp ) ); /*Q_exc */ + move16(); + } } } } - +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX + Q_adapt = Q_exc; + move16(); + test(); + IF( EQ_16( ReUseGain, 0 ) && Flag_adj_q_exc != 0 ) + { + Word16 total_bins = add( StartBin, NB_Qbins ); + move16(); + FOR( i = 0; i < total_bins; i++ ) + { + Q_adapt = s_min( Q_adapt, add( Q_exc_diffQ[i], norm_l( exc_diffQ32[i] ) ) ); + move16(); + } + FOR( i = 0; i < total_bins; i++ ) + { + exc_diffQ[i] = round_fx( L_shl( exc_diffQ32[i], sub( Q_adapt, Q_exc_diffQ[i] ) ) ); /*Q_exc*/ + } + } + return Q_adapt; +#else return; +#endif } #ifndef FIX_2338_HARM_GSC_GAIN_COMP diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c index fb11fc327bab38a432ed924b2f6e75fe0a84e7ca..800a9c3beed883f5941fc88fb5d25eeeb44bf516 100644 --- a/lib_com/gs_noisefill_fx.c +++ b/lib_com/gs_noisefill_fx.c @@ -1069,6 +1069,9 @@ void highband_exc_dct_in_ivas_fx( Word16 frac, exp, tmp1; Word16 tmp2; Word16 *end, Q_hb_exc; +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX + Word16 Flag_adj_q_exc, old_Q_exc; +#endif FOR( j = 10; j < MBANDS_GN; j++ ) { @@ -1340,10 +1343,9 @@ void highband_exc_dct_in_ivas_fx( move16(); } } -#ifndef FIX_2338_HARM_GSC_GAIN_COMP +#if !defined FIX_2338_HARM_GSC_GAIN_COMP && !defined FIX_2380_HARM_GSC_GAIN_COMP_FX IF( EQ_16( element_mode, EVS_MONO ) ) { -#endif Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, *Q_exc ); IF( exc_wo_nf != NULL ) @@ -1351,7 +1353,6 @@ void highband_exc_dct_in_ivas_fx( Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, *Q_exc ); Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame ); } -#ifndef FIX_2338_HARM_GSC_GAIN_COMP } ELSE { @@ -1382,7 +1383,34 @@ void highband_exc_dct_in_ivas_fx( Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) ); } } +#elif defined FIX_2380_HARM_GSC_GAIN_COMP_FX + Flag_adj_q_exc = 0; + move16(); + IF( NE_16( element_mode, EVS_MONO ) && lt_ener_per_band_fx != NULL ) /* to keep all EVS BE */ + { + Flag_adj_q_exc = 1; + move16(); + } + old_Q_exc = *Q_exc; + move16(); + *Q_exc = Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Flag_adj_q_exc, Qexc_diffQ, *Q_exc ); + Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, old_Q_exc ) ); + + IF( exc_wo_nf != NULL ) + { + Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Flag_adj_q_exc, Qexc_diffQ, *Q_exc ); + Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame ); + } +#else /* #if defined FIX_2338_HARM_GSC_GAIN_COMP */ + Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, *Q_exc ); + + IF( exc_wo_nf != NULL ) + { + Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, *Q_exc ); + Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame ); + } #endif + /*--------------------------------------------------------------------------------------* * add the correction layer to the LF bins, * and add the quantized pulses or the noise for the higher part of the spectrum diff --git a/lib_com/options.h b/lib_com/options.h index 523ba0ab821e9f6d47c4568d427fc38ed50afa87..7b2865416d8afea3a4f66cd289b258f6b19b3878 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -100,6 +100,7 @@ #define FIX_BASOP_2361_OTR /* FhG: Basop issue 2361: Orientation tracking tests for equivalent rotations fail */ #define FIX_2396_CONSTANT_STRIDE_IN_TC_BUFFER /* FhG/VA: basop issue 2396: keep TC channel pointers in one constant place during decoding and rendering */ #define FIX_2408_FD_BWE_UPDATE /* VA: basop issue 2408: bug-fix in the FD BWE memory updates in wb_pre_proc_ivas_fx() */ +#define FIX_2380_HARM_GSC_GAIN_COMP_FX /* VA: basop issue 2380 & 2381: Fix issue when switching from CNG low energy to active content with high energy */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 252d0646984ef618bc8effd23a89c6c43bbf60ff..7fff909a24b7bd25a824cdb8171ad29e5d96ea4d 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1703,14 +1703,22 @@ void Ener_per_band_comp_ivas_fx( const Word16 L_frame /* i : frame length */ ); +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX +Word16 Comp_and_apply_gain_fx( +#else void Comp_and_apply_gain_fx( +#endif Word16 exc_diffQ[], /* i/o: Quantized excitation */ Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */ - Word16 Ener_per_bd_yQ[], /* i/o : Ener per band for norm vector i->Q13/o->Q13 */ - Word16 Mbands_gn, /* i : number of bands */ - const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */ + Word16 Ener_per_bd_yQ[], /* i/o: Ener per band for norm vector i->Q13/o->Q13 */ + Word16 Mbands_gn, /* i : number of bands */ + const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */ +#ifdef FIX_2380_HARM_GSC_GAIN_COMP_FX + const Word16 Flag_adj_q_exc, /* i : Ener_per_bd_iQ of lt_ener_per_band_fx */ +#endif Word16 Qexc_diff, Word16 Q_exc ); + #ifndef FIX_2338_HARM_GSC_GAIN_COMP void Comp_and_apply_gain_ivas_fx( Word16 exc_diffQ[], /* i/o: Quantized excitation */