diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index ad20226063325e9a15d75fd7f198e4c3d0186b9d..8177b4567830a3e929e0b2147cd1449bc19a683b 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -677,16 +677,16 @@ static void stereo_dft_generate_comfort_noise( *-------------------------------------------------------------------*/ static void stereo_dft_generate_comfort_noise_fx( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT Stereo decoder handle */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ - const Word16 last_element_mode, /* i : last element mode */ - Decoder_State *st, /* i/o: Core coder decoder state */ - Word32 DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers */ - Decoder_State *st1, /* i/o: Core coder decoder state secondary channel */ - const Word16 targetGain, /* i : ICA target gain */ - const Word16 chan, /* i : channel number */ - const Word16 output_frame, /* i : output frame size */ - Word16 q_dft /* i : Q of DFT */ + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT Stereo decoder handle */ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ + const Word16 last_element_mode, /* i : last element mode */ + Decoder_State *st, /* i/o: Core coder decoder state */ + Word32 DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers */ + Decoder_State *st1, /* i/o: Core coder decoder state secondary channel */ + const Word16 targetGain, /* i : ICA target gain Q13 */ + const Word16 chan, /* i : channel number */ + const Word16 output_frame, /* i : output frame size */ + Word16 q_dft /* i : Q of DFT */ ) { Word16 i, j, k; @@ -710,10 +710,10 @@ static void stereo_dft_generate_comfort_noise_fx( Word16 b, q_cngNoiseLevel_upd, q_cngNoiseLevel; Word32 *pSideGain; Word16 gamma; - Word16 c; + Word16 c, c_e; Word16 scaleMS; - Word16 scaleAvg; - Word16 LR_ratio; + Word16 scaleAvg, scaleAvg_e; + Word16 LR_ratio; /* Q15 */ Word32 factor; Word16 alpha; Word32 ftmp; @@ -807,6 +807,8 @@ static void stereo_dft_generate_comfort_noise_fx( { scaleAvg = 0; move16(); + scaleAvg_e = 15; + move16(); FOR( b = 0; b < hStereoDft->nbands; b++ ) { IF( LT_16( hStereoCng->cm_fx[b], 0x7333 ) ) @@ -827,36 +829,37 @@ static void stereo_dft_generate_comfort_noise_fx( move16(); } - LR_ratio = extract_h( tdm_ratio_tabl_fx[hStereoCng->last_tdm_idx] ); + LR_ratio = extract_h( tdm_ratio_tabl_fx[hStereoCng->last_tdm_idx] ); /* Q15 */ c = BASOP_Util_Divide3232_Scale( L_add( L_mult( add( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ), add( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ) ), L_shr( L_mult( gamma, gamma ), 4 ) ), - L_add( Mpy_32_32( sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ), - sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ) ), + L_add( L_mult( sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ), + sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ) ), L_shr( L_mult( gamma, gamma ), 4 ) ), - &q_div ); - q_sqrt = q_div; + &c_e ); + q_sqrt = c_e; move16(); sqrt_res = Sqrt16( mult( c, hStereoCng->cm_fx[b] ), &q_sqrt ); - // Add 1 to q_sqrt to account for multiplication with 2.0 in float computation. - q_sqrt = add( q_sqrt, 1 ); - tmp32_1 = L_add( L_add( L_shl( 1, sub( Q15, q_div ) ), c ), L_shr( L_deposit_l( sqrt_res ), sub( q_div, q_sqrt ) ) ); - q_sqrt = q_div; + tmp32_1 = L_add( L_add( L_shl( 1, sub( Q15, c_e ) ), c ), L_shl( L_deposit_l( sqrt_res ), sub( add( q_sqrt, 1 ), c_e ) ) ); /* Q(15 - c_e) */ /* +1 to account for multiplication with 2 */ move16(); + // scaleMS = (1 + c + 2 * sqrtf(c * hStereoCng->cm[b])) / (4 * (c * LR_ratio * LR_ratio + (1 - LR_ratio) * (1 - LR_ratio) * targetGain * targetGain + 2 * LR_ratio * (1 - LR_ratio) * targetGain * sqrtf(c * hStereoCng->cm[b]))); sqrt_res = Sqrt16( mult( c, hStereoCng->cm_fx[b] ), &q_sqrt ); - tmp32_2 = L_shl( L_add( L_shl( L_deposit_l( mult( c, mult( LR_ratio, LR_ratio ) ) ), q_div ), - L_add( mult( mult( sub( MAX_16, LR_ratio ), sub( MAX_16, LR_ratio ) ), mult( targetGain, targetGain ) ), - L_shl( L_deposit_l( mult( mult( LR_ratio, sub( MAX_16, LR_ratio ) ), mult( targetGain, sqrt_res ) ) ), add( 1, q_sqrt ) ) ) ), // add(1, q_sqrt) to account for multiplication with 2 and also to maintain uniform q. - 2 ); - scaleMS = BASOP_Util_Divide3232_Scale( tmp32_1, tmp32_2, &q_div ); - q_sqrt = q_div; + tmp32_2 = L_deposit_l( mult( c, mult( LR_ratio, LR_ratio ) ) ); /* Q(15 - c_e) */ + /* (1 - LR_ratio) * (1 - LR_ratio) * targetGain * targetGain */ + tmp32_2 = L_add( tmp32_2, L_shl( mult( mult( sub( MAX_16, LR_ratio ), sub( MAX_16, LR_ratio ) ), mult( targetGain, targetGain ) ), sub( Q4, c_e ) ) ); /* Q(15 - c_e) */ + /* 2 * LR_ratio * (1 - LR_ratio) * targetGain * sqrtf(c * hStereoCng->cm[b]) */ + tmp32_2 = L_add( tmp32_2, L_shl( L_deposit_l( mult( mult( LR_ratio, sub( MAX_16, LR_ratio ) ), mult( targetGain, sqrt_res ) ) ), sub( add( q_sqrt, 3 ), c_e ) ) ); /* Q(15 - c_e) */ /* +1 to account for multiplication with 2 */ + tmp32_2 = L_shl( tmp32_2, 2 ); + scaleMS = BASOP_Util_Divide3232_Scale( tmp32_1, tmp32_2, &c_e ); + q_sqrt = c_e; move16(); scaleMS = Sqrt16( scaleMS, &q_sqrt ); - scaleAvg = add( scaleAvg, shr( scaleMS, sub( Q15, q_sqrt ) ) ); + scaleAvg_e = BASOP_Util_Add_MantExp( scaleAvg, scaleAvg_e, scaleMS, q_sqrt, &scaleAvg ); } - scaleAvg = BASOP_Util_Divide1616_Scale( scaleAvg, hStereoDft->nbands, &q_div ); - hStereoDft->scale_fx = shl_sat( scaleAvg, q_div ); + scaleAvg = BASOP_Util_Divide1616_Scale( scaleAvg, hStereoDft->nbands, &c_e ); + c_e = sub( add( c_e, scaleAvg_e ), 15 ); + hStereoDft->scale_fx = shl_sat( scaleAvg, c_e ); move16(); } }