From 24ab597252d72fd3a695535b1b4aace1f7d08b0f Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 26 Mar 2026 15:13:09 +0100 Subject: [PATCH 1/3] Add first series of overflow checks to see what happens. --- lib_basop/basop32.c | 46 +++++++++++++++++++++++++++ lib_basop/basop32.h | 3 ++ lib_basop/enh64.c | 46 +++++++++++++++++++++++++++ lib_basop/enh64.h | 3 ++ lib_com/options.h | 1 + lib_enc/acelp_core_enc_fx.c | 8 +++++ lib_enc/ext_sig_ana_fx.c | 16 ++++++++++ lib_enc/ivas_core_pre_proc_front_fx.c | 4 +++ lib_enc/ivas_stereo_classifier_fx.c | 4 +++ lib_enc/ivas_stereo_ica_enc_fx.c | 24 ++++++++++++++ lib_enc/ivas_tcx_core_enc_fx.c | 4 +++ lib_enc/swb_bwe_enc_fx.c | 16 ++++++++++ lib_enc/swb_pre_proc_fx.c | 15 +++++++++ 13 files changed, 190 insertions(+) diff --git a/lib_basop/basop32.c b/lib_basop/basop32.c index 4f601911b..492a69e3f 100644 --- a/lib_basop/basop32.c +++ b/lib_basop/basop32.c @@ -1210,6 +1210,52 @@ Word16 extract_l( Word32 L_var1 ) return ( var_out ); } +#ifdef FIX_2493_CHECK_EXTRACT_L +/*___________________________________________________________________________ + | | + | Function Name : extract_l2 | + | | + | Purpose : | + | | + | Return the 16 LSB of L_var1. Check range. | + | | + | Complexity weight : 1 | + | | + | Inputs : | + | | + | L_var1 | + | 32 bit long signed integer (Word32 ) whose value falls in the | + | range : 0xffff 8000 <= L_var1 <= 0x0000 7fff. | + | | + | Outputs : | + | | + | none | + | | + | Return Value : | + | | + | var_out | + | 16 bit short signed integer (Word16) whose value falls in the | + | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | + |___________________________________________________________________________| +*/ +Word16 extract_l2( Word32 L_var1 ) +{ + Word16 var_out; + + assert( L_var1 <=(Word32)MAX_16 && L_var1 >= (Word32)(Word16)MIN_16 ); + + var_out = (Word16) L_var1; + +#ifdef WMOPS + multiCounter[currCounter].extract_l++; +#endif + + BASOP_CHECK(); + + + return ( var_out ); +} +#endif /*___________________________________________________________________________ | | diff --git a/lib_basop/basop32.h b/lib_basop/basop32.h index 7fe294167..dbabf9400 100644 --- a/lib_basop/basop32.h +++ b/lib_basop/basop32.h @@ -129,6 +129,9 @@ Word32 L_mult( Word16 var1, Word16 var2 ); /* Word16 negate( Word16 var1 ); /* Short negate, 1 */ Word16 extract_h( Word32 L_var1 ); /* Extract high, 1 */ Word16 extract_l( Word32 L_var1 ); /* Extract low, 1 */ +#ifdef FIX_2493_CHECK_EXTRACT_L +Word16 extract_l2( Word32 L_var1 ); /* Extract low and check range 1 */ +#endif Word16 round_fx( Word32 L_var1 ); /* Round, 1 */ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac, 1 */ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu, 1 */ diff --git a/lib_basop/enh64.c b/lib_basop/enh64.c index 8bffb620c..0edca9f75 100644 --- a/lib_basop/enh64.c +++ b/lib_basop/enh64.c @@ -868,6 +868,52 @@ Word32 W_extract_l( Word64 L64_var1 ) return ( L_var_out ); } +#ifdef FIX_2493_CHECK_EXTRACT_L + +#include + +/*__________________________________________________________________________________ +| | +| Function Name : W_extract_l | +| | +| Purpose : | +| | +| Return the 32 LSB of L64_var1 and check the range | +| | +| Complexity weight : 1 | +| | +| Inputs : | +| | +| L64_var1 | +| 64 bit long long signed integer (Word64) whose value falls in | +| range : 0x00000000 80000000LL <= L64_var1 <= 0xffffffff 7fffffffLL. | +| | +| Outputs : | +| | +| none | +| | +| Return Value : | +| | +| L_var_out | +| 32 bit long signed integer (Word32) whose value falls in the | +| range : 0x8000 0000 <= L_var_out <= 0x7fff 0000. | +|__________________________________________________________________________________| +*/ +Word32 W_extract_l2( Word64 L64_var1 ) +{ + Word32 L_var_out; + + assert( L64_var1 <=(Word64)MAX_32 && L64_var1 >= (Word64)(Word32)MIN_32 ); + + L_var_out = (Word32) L64_var1; + +#ifdef WMOPS + multiCounter[currCounter].W_extract_l++; +#endif /* if WMOPS */ + + return ( L_var_out ); +} +#endif /*__________________________________________________________________________________ | | diff --git a/lib_basop/enh64.h b/lib_basop/enh64.h index c3896bb0d..7a326738f 100644 --- a/lib_basop/enh64.h +++ b/lib_basop/enh64.h @@ -47,6 +47,9 @@ Word32 W_sat_m( Word64 L64_var ); Word32 W_shl_sat_l( Word64 L64_var, Word16 n ); Word32 W_extract_l( Word64 L64_var1 ); +#ifdef FIX_2493_CHECK_EXTRACT_L +Word32 W_extract_l2( Word64 L64_var1 ); +#endif Word32 W_extract_h( Word64 L64_var1 ); Word32 W_round48_L( Word64 L64_var1 ); diff --git a/lib_com/options.h b/lib_com/options.h index c7b50714a..12765968c 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -89,6 +89,7 @@ #define FIX_2480_HARM_TONALMDCT /* FhG: basop issue 2480: Harmonize TonalMDCTConceal_Detect_fx() and TonalMDCTConceal_Detect_ivas_fx() */ #define FIX_2479_HARM_PITCH_GAIN /* FhG: basop issue 2479: Harmonize tcx_ltp_pitch_search_*(), tcx_ltp_find_gain_*fx() */ #define HARMONIZE_2481_EXTEND_SHRINK /* FhG: basop issue 2481: Harmonize extend_frm_*fx() and shrink_frm_*fx() */ +#define FIX_2493_CHECK_EXTRACT_L /* FhG: Verify that extract_l, W_extract_l etc. do not encounter an overflow. */ /* #################### End BE switches ################################## */ diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 27e6e2528..d89cda332 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -377,7 +377,11 @@ ivas_error acelp_core_enc_fx( /* calculate the energy quantization index */ enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ +#ifdef FIX_2493_CHECK_EXTRACT_L + enr_index = extract_l2( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ +#else enr_index = extract_l( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ +#endif /* limit the energy quantization index */ enr_index = s_min( enr_index, 127 ); // Q0 @@ -434,7 +438,11 @@ ivas_error acelp_core_enc_fx( /* calculate the energy quantization index */ enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ +#ifdef FIX_2493_CHECK_EXTRACT_L + enr_index = extract_l2( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ +#else enr_index = extract_l( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ +#endif /* limit the energy quantization index */ enr_index = s_min( enr_index, 127 ); /* Q0 */ diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index f5b91249f..3c842dea4 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1080,7 +1080,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin +#ifdef FIX_2493_CHECK_EXTRACT_L + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin +#else mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin +#endif move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ @@ -1088,7 +1092,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin +#ifdef FIX_2493_CHECK_EXTRACT_L + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin +#else mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin +#endif move32(); } } @@ -1168,7 +1176,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin +#ifdef FIX_2493_CHECK_EXTRACT_L + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin +#else mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin +#endif move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ @@ -1176,7 +1188,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin +#ifdef FIX_2493_CHECK_EXTRACT_L + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin +#else mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin +#endif move32(); } } diff --git a/lib_enc/ivas_core_pre_proc_front_fx.c b/lib_enc/ivas_core_pre_proc_front_fx.c index 9b2631128..79081401d 100644 --- a/lib_enc/ivas_core_pre_proc_front_fx.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1573,7 +1573,11 @@ static void calculate_energy_buffer_ivas_fx( FOR( i = 0; i < no_channels; i++ ) { +#ifdef FIX_2493_CHECK_EXTRACT_L + stop = extract_l2( L_shr( L_add( Mpy_32_16_1( chan_width_bins_fx, add( i, 1 ) ), 1 ), 1 ) ); /* Q0 */ +#else stop = extract_l( L_shr( L_add( Mpy_32_16_1( chan_width_bins_fx, add( i, 1 ) ), 1 ), 1 ) ); /* Q0 */ +#endif FOR( j = start; j < stop; j++ ) { *p_nrg_DMX_fx = W_add( *p_nrg_DMX_fx, W_shr( W_mult_32_32( pDFT_DMX_fx[2 * j], pDFT_DMX_fx[2 * j] ), guard_bits ) ); /* 2 * q_DFT_DMX_fx + 1 - guard_bits */ diff --git a/lib_enc/ivas_stereo_classifier_fx.c b/lib_enc/ivas_stereo_classifier_fx.c index 621a00bd4..f45d283a9 100644 --- a/lib_enc/ivas_stereo_classifier_fx.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -1419,7 +1419,11 @@ void xtalk_classifier_dft_fx( ELSE { // score /= XTALK_SCORE_THR_DFT; +#ifdef FIX_2493_CHECK_EXTRACT_L + score = L_shl_sat( W_extract_l2( W_tmp ), 2 ); // Q27->Q31/XTALK_SCORE_THR_DFT +#else score = L_shl_sat( W_extract_l( W_tmp ), 2 ); // Q27->Q31/XTALK_SCORE_THR_DFT +#endif } /* raw score */ diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 234652072..331382a7a 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -273,7 +273,11 @@ void spectral_balancer_fx16( x0 = signal[i]; /*Qx*/ move16(); // y0 = (y1 * a1) + (y2 * a2) + (x0 * b0) + (x1 * b1) + (x2 * b2); +#ifdef FIX_2493_CHECK_EXTRACT_L + y0 = extract_l2( W_extract_l2( W_shr( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mult_32_16( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ) ); // Qx +#else y0 = extract_l( W_extract_l( W_shr( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mult_32_16( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ) ); // Qx +#endif signal[i] = y0; /*Qx*/ move16(); y2 = y1; /*Qx*/ @@ -355,7 +359,11 @@ void spectral_balancer_fx( move16(); x0 = signal[i]; /*Qx*/ move16(); +#ifdef FIX_2493_CHECK_EXTRACT_L + y0 = W_extract_l2( W_shr( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mult_32_32( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ); // Qx +#else y0 = W_extract_l( W_shr( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mult_32_32( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ); // Qx +#endif signal[i] = y0; /*Qx*/ move16(); y2 = y1; /*Qx*/ @@ -738,7 +746,11 @@ static Word16 TRUNC_FX( Word32 inp /*Q31-exp*/, Word16 exp ) IF( NE_32( temp, L_shl_sat( 1, sub( 31, exp ) ) ) ) { Word32 temp1 = L_add_sat( inp, L_shl_sat( 1, sub( 31, add( exp, 1 ) ) ) ); /* Q31-exp */ +#ifdef FIX_2493_CHECK_EXTRACT_L + ouptut = extract_l2( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/ +#else ouptut = extract_l( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/ +#endif IF( temp < 0 ) { @@ -747,7 +759,11 @@ static Word16 TRUNC_FX( Word32 inp /*Q31-exp*/, Word16 exp ) } ELSE { +#ifdef FIX_2493_CHECK_EXTRACT_L + ouptut = extract_l2( temp ); /*Q0*/ +#else ouptut = extract_l( temp ); /*Q0*/ +#endif move16(); } } @@ -1304,7 +1320,11 @@ static void estDownmixGain_fx( currentGain_log10 = BASOP_Util_Log10( L_deposit_h( currentGain ), currentGain_e ); // Output in Q25 // multiplication result will be Q25 should be fit to Q15 hence right shift by 10. // Q25 - Q10 = Q15 +#ifdef FIX_2493_CHECK_EXTRACT_L + currentGain = extract_l2( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); /* Q15 */ +#else currentGain = extract_l( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); /* Q15 */ +#endif currentGain_e = 0; move16(); @@ -1757,7 +1777,11 @@ void stereo_tca_enc_fx( IF( LT_32( input_Fs, 32000 ) ) { +#ifdef FIX_2493_CHECK_EXTRACT_L + maxCorrStatsDev = extract_l2( Mpy_32_32( imult3216( input_Fs, maxCorrStatsDev ), 67109 /* 1/32000.0f in Q31*/ ) ); // Q0 +#else maxCorrStatsDev = extract_l( Mpy_32_32( imult3216( input_Fs, maxCorrStatsDev ), 67109 /* 1/32000.0f in Q31*/ ) ); // Q0 +#endif } musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE ); diff --git a/lib_enc/ivas_tcx_core_enc_fx.c b/lib_enc/ivas_tcx_core_enc_fx.c index 20f030c6d..b7a8c5202 100644 --- a/lib_enc/ivas_tcx_core_enc_fx.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -623,7 +623,11 @@ void stereo_tcx_core_enc( lev_dur_fx( A_fx32, r_fx, M, NULL, Q12, Q_r ); FOR( Word16 j = 0; j < M; j++ ) { +#ifdef FIX_2493_CHECK_EXTRACT_L + A_fx[j] = extract_l2( A_fx32[j] ); /* Q12 */ +#else A_fx[j] = extract_l( A_fx32[j] ); /* Q12 */ +#endif move16(); } E_LPC_a_lsp_conversion( A_fx, lsptmp_fx, lsp_new_fx, M ); diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 3c099f6aa..82f2337cd 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -677,7 +677,11 @@ static void get_normalize_spec_fx( exp = sub( sub( 30, exp ), Q_new_lf ); tmp = div_s( 16384, tmp ); /*Q(15+exp) */ L_tmp_m = L_shr( L_mult0( SWB_signal[n_freq], tmp ), add( exp, Q_new_lf ) ); /*Q15 */ +#ifdef FIX_2493_CHECK_EXTRACT_L + SWB_signal[n_freq] = extract_l2( L_tmp_m ); /*Q15 */ +#else SWB_signal[n_freq] = extract_l( L_tmp_m ); /*Q15 */ +#endif move16(); } ELSE @@ -854,7 +858,11 @@ static Word16 FD_BWE_class_fx( { L_tmp = L_sub( mean[i], peak ); /*Q_syn */ L_tmp = Mpy_32_16_1( L_tmp, 16913 ); /* 1/31->Q19 -> Q_syn+19-15 */ +#ifdef FIX_2493_CHECK_EXTRACT_L + den = extract_l2( L_shr( L_tmp, 4 ) ); /*Q_syn */ +#else den = extract_l( L_shr( L_tmp, 4 ) ); /*Q_syn */ +#endif if ( den == 0 ) { den = 1; @@ -3273,7 +3281,11 @@ void hq_generic_hf_encoding_fx( L_tmp = L_mult( tmp, 21771 ); /*26 */ L_tmp = L_shr( L_tmp, 10 ); /*16 */ L_Extract( L_tmp, &exp, &tmp ); /* */ +#ifdef FIX_2493_CHECK_EXTRACT_L + tmp = extract_l2( Pow2( 13, tmp ) ); +#else tmp = extract_l( Pow2( 13, tmp ) ); +#endif exp = sub( exp, 13 ); hq_generic_fenv_fx[n_band] = shl_sat( tmp, add( exp, 1 ) ); /*1 */ move16(); @@ -3287,7 +3299,11 @@ void hq_generic_hf_encoding_fx( L_tmp = L_mult( tmp, 21771 ); /*25 */ L_tmp = L_shr( L_tmp, 9 ); /*16 */ L_Extract( L_tmp, &exp, &tmp ); +#ifdef FIX_2493_CHECK_EXTRACT_L tmp = extract_l( Pow2( 13, tmp ) ); +#else + tmp = extract_l( Pow2( 13, tmp ) ); +#endif exp = sub( exp, 13 ); hq_generic_fenv_fx[n_band + nenv] = shl( tmp, add( exp, 1 ) ); /*1 */ move16(); diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 4530bb4db..ce58c3670 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -811,8 +811,13 @@ void swb_pre_proc_fx( { FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) { +#ifdef FIX_2493_CHECK_EXTRACT_L + realQ_neg1 = extract_l2( L_shr( realBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 ) ); + imagQ_neg1 = extract_l2( L_shr( imagBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 ) ); /* Q(-1), headroom needed */ +#else realQ_neg1 = extract_l( L_shr( realBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 ) ); imagQ_neg1 = extract_l( L_shr( imagBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 ) ); /* Q(-1), headroom needed */ +#endif lbEner = L_mac0_o( lbEner, realQ_neg1, realQ_neg1, &Overflow ); lbEner = L_mac0_o( lbEner, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ @@ -958,8 +963,13 @@ void swb_pre_proc_fx( { FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) { +#ifdef FIX_2493_CHECK_EXTRACT_L + realQ_neg1 = extract_l2( L_shr( realBuffer[ts][nB], 16 ) ); + imagQ_neg1 = extract_l2( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ +#else realQ_neg1 = extract_l( L_shr( realBuffer[ts][nB], 16 ) ); imagQ_neg1 = extract_l( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ +#endif icbweRefEner_fx = L_mac0_o( icbweRefEner_fx, realQ_neg1, realQ_neg1, &Overflow ); icbweRefEner_fx = L_mac0_o( icbweRefEner_fx, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ } @@ -977,8 +987,13 @@ void swb_pre_proc_fx( { FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) { +#ifdef FIX_2493_CHECK_EXTRACT_L + realQ_neg1 = extract_l2( L_shr( realBuffer[ts][nB], 16 ) ); + imagQ_neg1 = extract_l2( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ +#else realQ_neg1 = extract_l( L_shr( realBuffer[ts][nB], 16 ) ); imagQ_neg1 = extract_l( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ +#endif lbEner = L_mac0_o( lbEner, realQ_neg1, realQ_neg1, &Overflow ); lbEner = L_mac0_o( lbEner, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ -- GitLab From add528fa942815c89a720e979fa468235033e473 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 26 Mar 2026 15:14:37 +0100 Subject: [PATCH 2/3] clang format --- lib_enc/acelp_core_enc_fx.c | 4 ++-- lib_enc/ext_sig_ana_fx.c | 16 ++++++++-------- lib_enc/ivas_stereo_ica_enc_fx.c | 8 ++++---- lib_enc/swb_bwe_enc_fx.c | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index d89cda332..cdd38da95 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -376,7 +376,7 @@ ivas_error acelp_core_enc_fx( enr = cng_energy_fx( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, /*st->hTdCngEnc->CNG_att*/ 0, exc_fx, st->L_frame, Q_new ); // Q8 /* calculate the energy quantization index */ - enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ + enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ #ifdef FIX_2493_CHECK_EXTRACT_L enr_index = extract_l2( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ #else @@ -437,7 +437,7 @@ ivas_error acelp_core_enc_fx( enr = cng_energy_ivas_fx( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att_fx, exc_fx, st->L_frame, Q_new ); /* Q8 */ /* calculate the energy quantization index */ - enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ + enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ #ifdef FIX_2493_CHECK_EXTRACT_L enr_index = extract_l2( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ #else diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 3c842dea4..dd39a6cdc 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -1081,9 +1081,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin #ifdef FIX_2493_CHECK_EXTRACT_L - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin #else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin #endif move32(); } @@ -1093,9 +1093,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin #ifdef FIX_2493_CHECK_EXTRACT_L - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin #else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin #endif move32(); } @@ -1177,9 +1177,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin #ifdef FIX_2493_CHECK_EXTRACT_L - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin #else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin #endif move32(); } @@ -1189,9 +1189,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp L_tmp = L_shl( L_tmp, shift ); // q_mdstWin #ifdef FIX_2493_CHECK_EXTRACT_L - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l2( L_tmp ) ); // q_mdstWin #else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin #endif move32(); } diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 331382a7a..0e638001e 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -278,7 +278,7 @@ void spectral_balancer_fx16( #else y0 = extract_l( W_extract_l( W_shr( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mult_32_16( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ) ); // Qx #endif - signal[i] = y0; /*Qx*/ + signal[i] = y0; /*Qx*/ move16(); y2 = y1; /*Qx*/ move16(); @@ -364,7 +364,7 @@ void spectral_balancer_fx( #else y0 = W_extract_l( W_shr( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mult_32_32( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ); // Qx #endif - signal[i] = y0; /*Qx*/ + signal[i] = y0; /*Qx*/ move16(); y2 = y1; /*Qx*/ move16(); @@ -747,9 +747,9 @@ static Word16 TRUNC_FX( Word32 inp /*Q31-exp*/, Word16 exp ) { Word32 temp1 = L_add_sat( inp, L_shl_sat( 1, sub( 31, add( exp, 1 ) ) ) ); /* Q31-exp */ #ifdef FIX_2493_CHECK_EXTRACT_L - ouptut = extract_l2( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/ + ouptut = extract_l2( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/ #else - ouptut = extract_l( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/ + ouptut = extract_l( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/ #endif IF( temp < 0 ) diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index 82f2337cd..01708bc5d 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -678,9 +678,9 @@ static void get_normalize_spec_fx( tmp = div_s( 16384, tmp ); /*Q(15+exp) */ L_tmp_m = L_shr( L_mult0( SWB_signal[n_freq], tmp ), add( exp, Q_new_lf ) ); /*Q15 */ #ifdef FIX_2493_CHECK_EXTRACT_L - SWB_signal[n_freq] = extract_l2( L_tmp_m ); /*Q15 */ + SWB_signal[n_freq] = extract_l2( L_tmp_m ); /*Q15 */ #else - SWB_signal[n_freq] = extract_l( L_tmp_m ); /*Q15 */ + SWB_signal[n_freq] = extract_l( L_tmp_m ); /*Q15 */ #endif move16(); } @@ -856,8 +856,8 @@ static Word16 FD_BWE_class_fx( IF( NE_32( mean[i], L_deposit_l( peak ) ) ) { - L_tmp = L_sub( mean[i], peak ); /*Q_syn */ - L_tmp = Mpy_32_16_1( L_tmp, 16913 ); /* 1/31->Q19 -> Q_syn+19-15 */ + L_tmp = L_sub( mean[i], peak ); /*Q_syn */ + L_tmp = Mpy_32_16_1( L_tmp, 16913 ); /* 1/31->Q19 -> Q_syn+19-15 */ #ifdef FIX_2493_CHECK_EXTRACT_L den = extract_l2( L_shr( L_tmp, 4 ) ); /*Q_syn */ #else -- GitLab From 47f4992da7e8ef6003b791aa420604af1a80d31e Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Thu, 26 Mar 2026 16:55:39 +0100 Subject: [PATCH 3/3] Add fix proposal for extract_l() overflow in estDownmixGain_fx(). --- lib_com/options.h | 1 + lib_enc/ivas_stereo_ica_enc_fx.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index ff88b8288..67019b0ff 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -90,6 +90,7 @@ #define FIX_2479_HARM_PITCH_GAIN /* FhG: basop issue 2479: Harmonize tcx_ltp_pitch_search_*(), tcx_ltp_find_gain_*fx() */ #define HARMONIZE_2481_EXTEND_SHRINK /* FhG: basop issue 2481: Harmonize extend_frm_*fx() and shrink_frm_*fx() */ #define FIX_2493_CHECK_EXTRACT_L /* FhG: Verify that extract_l, W_extract_l etc. do not encounter an overflow. */ +#define NONBE_FIX_2493_CHECK_EXTRACT_L_estDownmixGain_fx /* FhG: Fix extract_l overflow inside estDownmixGain_fx() */ /* #################### End BE switches ################################## */ diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index 0e638001e..0832fecf5 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1320,6 +1320,13 @@ static void estDownmixGain_fx( currentGain_log10 = BASOP_Util_Log10( L_deposit_h( currentGain ), currentGain_e ); // Output in Q25 // multiplication result will be Q25 should be fit to Q15 hence right shift by 10. // Q25 - Q10 = Q15 +#ifdef NONBE_FIX_2493_CHECK_EXTRACT_L_estDownmixGain_fx + Word32 temp32; + temp32 = L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ); + currentGain_e = sub( norm_l( temp32 ), 1 ); + currentGain = round_fx( L_shl( temp32, currentGain_e ) ); + currentGain_e = sub( 16, currentGain_e ); +#else #ifdef FIX_2493_CHECK_EXTRACT_L currentGain = extract_l2( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); /* Q15 */ #else @@ -1327,6 +1334,7 @@ static void estDownmixGain_fx( #endif currentGain_e = 0; move16(); +#endif test(); IF( EQ_16( element_mode, IVAS_CPE_TD ) && hStereoClassif != NULL ) -- GitLab