From fa18e7dff4ca45f79b937fbf4ad5b23a3cc143ad Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 26 Mar 2025 09:38:56 +0530 Subject: [PATCH] Fix for 3GPP issue 1408: Decoder crash for ParamMC 5.1 at 48/64/80 kbps decoding to mono in ivas_ls_setup_conversion_fx() Link #1408 --- lib_dec/ivas_out_setup_conversion_fx.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index fc69d3919..93a7c204e 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -657,6 +657,7 @@ void ivas_ls_setup_conversion_process_mdct_fx( Word16 transform_type[MAX_CICP_CHANNELS][2]; Word16 frameSize; Word32 targetEnergy[MAX_SFB + 2], dmxEnergy[MAX_SFB + 2]; + Word16 dmxEnergy_exp[MAX_SFB + 2], dmxEnergy_exp_temp; Word32 dmxCoeff; Word32 dmxSignalReal[L_FRAME48k], dmxSignalImag[L_FRAME48k]; Word32 eqGain; @@ -739,6 +740,9 @@ void ivas_ls_setup_conversion_process_mdct_fx( set32_fx( targetEnergy, 0, MAX_SFB + 2 ); set32_fx( dmxEnergy, 0, MAX_SFB + 2 ); + set16_fx( dmxEnergy_exp, 0, MAX_SFB + 2 ); + dmxEnergy_exp_temp = 0; + move16(); FOR( chOutIdx = 0; chOutIdx < outChannels; chOutIdx++ ) { @@ -829,6 +833,7 @@ void ivas_ls_setup_conversion_process_mdct_fx( FOR( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) { Word32 tmpReal, tmpImag, DMXEne; + Word16 DMXEne_exp; start = hLsSetUpConversion->sfbOffset[bandIdx]; move16(); @@ -838,6 +843,8 @@ void ivas_ls_setup_conversion_process_mdct_fx( /* Loop over all the bins in the band */ DMXEne = 0; move32(); + DMXEne_exp = 0; + move16(); FOR( binIdx = start; binIdx < stop; binIdx++ ) { tmpReal = dmxSignalReal[binIdx]; @@ -845,13 +852,20 @@ void ivas_ls_setup_conversion_process_mdct_fx( tmpImag = dmxSignalImag[binIdx]; move32(); - DMXEne = L_add( DMXEne, L_add( Mpy_32_32( tmpReal, tmpReal ), Mpy_32_32( tmpImag, tmpImag ) ) ); + DMXEne = BASOP_Util_Add_Mant32Exp( DMXEne, DMXEne_exp, L_add( Mpy_32_32( tmpReal, tmpReal ), Mpy_32_32( tmpImag, tmpImag ) ), sub( 40, shl( q_output, 1 ) ), &DMXEne_exp ); } - dmxEnergy[bandIdx] = L_add( dmxEnergy[bandIdx], DMXEne ); + dmxEnergy[bandIdx] = BASOP_Util_Add_Mant32Exp( dmxEnergy[bandIdx], dmxEnergy_exp[bandIdx], DMXEne, DMXEne_exp, &dmxEnergy_exp[bandIdx] ); move32(); + dmxEnergy_exp_temp = s_max( dmxEnergy_exp_temp, dmxEnergy_exp[bandIdx] ); } } /* end of out channel loop */ + /* Scaling to common exponent */ + FOR( bandIdx = 0; bandIdx < MAX_SFB + 2; bandIdx++ ) + { + dmxEnergy[bandIdx] = L_shl( dmxEnergy[bandIdx], sub( dmxEnergy_exp[bandIdx], dmxEnergy_exp_temp ) ); + move32(); + } /* Step 3: Peform energy smoothing */ Word16 te_scale = getScaleFactor32( hLsSetUpConversion->targetEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt ); @@ -860,13 +874,13 @@ void ivas_ls_setup_conversion_process_mdct_fx( scale_sig32( hLsSetUpConversion->dmxEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt, dmx_sacle ); Word16 te_max_e = s_max( sub( 40, shl( q_output, 1 ) ), sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ); - Word16 dmx_max_e = s_max( sub( 40, shl( q_output, 1 ) ), sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ); + Word16 dmx_max_e = s_max( dmxEnergy_exp_temp, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ); FOR( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) { targetEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( targetEnergy[bandIdx], sub( te_max_e, sub( 40, shl( q_output, 1 ) ) ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx], sub( te_max_e, sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ) ) ) ); move32(); - dmxEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( dmxEnergy[bandIdx], sub( dmx_max_e, sub( 40, shl( q_output, 1 ) ) ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], sub( dmx_max_e, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ) ) ) ); + dmxEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( dmxEnergy[bandIdx], sub( dmx_max_e, dmxEnergy_exp_temp ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], sub( dmx_max_e, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ) ) ) ); move32(); hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx] = targetEnergy[bandIdx]; /* te_prev_exp = 40 - 2*q_output */ move32(); -- GitLab