From 04f75bda7d5dcd803f66be084532288d55a5e528 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 8 Jun 2026 12:54:16 +0200 Subject: [PATCH 1/5] Assimilate all changes from basop-2493-usage-of-extract_l-with-values-out-of-range that do fix errors found by STV/LTV pipelines, without the extra problem detection changes. --- lib_basop/enh64.c | 30 +++++++++++++++++++++++++-- lib_com/ivas_spar_com_quant_util_fx.c | 15 ++++++++++++++ lib_com/options.h | 14 +++++++++++++ lib_dec/acelp_core_dec_fx.c | 14 +++++++++++++ lib_dec/bass_psfilter_fx.c | 15 ++++++++++++++ lib_dec/ivas_core_dec_fx.c | 26 +++++++++++++++++++++++ lib_dec/ivas_lfe_plc_fx.c | 4 ++++ lib_enc/bw_detect_fx.c | 18 +++++++++++++++- lib_enc/cod4t64_fast_fx.c | 4 ++++ lib_enc/ivas_stereo_ica_enc_fx.c | 19 ++++++++++++++++- lib_enc/swb_pre_proc_fx.c | 13 ++++++++++++ lib_enc/swb_tbe_enc_fx.c | 4 ++++ lib_enc/transient_detection_fx.c | 4 ++++ 13 files changed, 176 insertions(+), 4 deletions(-) diff --git a/lib_basop/enh64.c b/lib_basop/enh64.c index 8bffb620c..0aba08822 100644 --- a/lib_basop/enh64.c +++ b/lib_basop/enh64.c @@ -18,6 +18,10 @@ #include #include "stl.h" +#ifdef FIX_2493_CHECK_64BIT +#include +#endif + #define WMC_TOOL_SKIP /***************************************************************************** @@ -74,7 +78,9 @@ Word64 W_add_nosat( Word64 L64_var1, Word64 L64_var2 ) { Word64 L64_var_out; - +#ifdef FIX_2493_CHECK_64BIT + assert( W_abs( ( ( L64_var1 + L64_var2 ) >> 1 ) - ( ( L64_var1 >> 1 ) + ( L64_var2 >> 1 ) ) ) < 2 ); +#endif L64_var_out = L64_var1 + L64_var2; #ifdef WMOPS @@ -117,7 +123,9 @@ Word64 W_add_nosat( Word64 L64_var1, Word64 L64_var2 ) Word64 W_sub_nosat( Word64 L64_var1, Word64 L64_var2 ) { Word64 L64_var_out; - +#ifdef FIX_2493_CHECK_64BIT + assert( W_abs( ( ( L64_var1 - L64_var2 ) >> 1 ) - ( ( L64_var1 >> 1 ) - ( L64_var2 >> 1 ) ) ) < 2 ); +#endif L64_var_out = L64_var1 - L64_var2; #ifdef WMOPS @@ -316,6 +324,9 @@ Word64 W_shl_nosat( Word64 L64_var1, Word16 var2 ) } else { +#ifdef FIX_2493_CHECK_64BIT + assert( ( ( L64_var1 << var2 ) >> var2 ) == L64_var1 ); +#endif L64_var_out = L64_var1 << var2; } #ifdef WMOPS @@ -369,6 +380,9 @@ Word64 W_shr_nosat( Word64 L64_var1, Word16 var2 ) if ( var2 < 0 ) { var2 = -var2; +#ifdef FIX_2493_CHECK_64BIT + assert( ( ( L64_var1 << var2 ) >> var2 ) == L64_var1 ); +#endif L64_var_out = L64_var1 << var2; } else @@ -423,6 +437,9 @@ Word64 W_shr_nosat( Word64 L64_var1, Word16 var2 ) Word64 W_mac_32_16( Word64 L64_var1, Word32 L_var2, Word16 var3 ) { Word64 L64_var_out = ( (Word64) L_var2 * var3 ) << 1; +#ifdef FIX_2493_CHECK_64BIT + assert( W_abs( ( ( L64_var_out + L64_var1 ) >> 1 ) - ( ( L64_var_out >> 1 ) + ( L64_var1 >> 1 ) ) ) < 2 ); +#endif L64_var_out += L64_var1; #ifdef WMOPS multiCounter[currCounter].W_mac_32_16++; @@ -470,6 +487,9 @@ Word64 W_mac_32_16( Word64 L64_var1, Word32 L_var2, Word16 var3 ) Word64 W_msu_32_16( Word64 L64_var1, Word32 L_var2, Word16 var3 ) { Word64 L64_var_out = ( (Word64) L_var2 * var3 ) << 1; +#ifdef FIX_2493_CHECK_64BIT + assert( W_abs( ( ( L64_var1 - L64_var_out ) >> 1 ) - ( ( L64_var1 >> 1 ) - ( L64_var_out >> 1 ) ) ) < 2 ); +#endif L64_var_out = L64_var1 - L64_var_out; #ifdef WMOPS multiCounter[currCounter].W_msu_32_16++; @@ -596,6 +616,9 @@ Word64 W_mult0_16_16( Word16 var1, Word16 var2 ) Word64 W_mac0_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) { Word64 L64_var_out = (Word64) var2 * var3; +#ifdef FIX_2493_CHECK_64BIT + assert( W_abs( ( ( L64_var_out + L64_var1 ) >> 1 ) - ( ( L64_var_out >> 1 ) + ( L64_var1 >> 1 ) ) ) < 2 ); +#endif L64_var_out += L64_var1; #ifdef WMOPS multiCounter[currCounter].W_mac0_16_16++; @@ -642,6 +665,9 @@ Word64 W_mac0_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) Word64 W_msu0_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) { Word64 L64_var_out = (Word64) var2 * var3; +#ifdef FIX_2493_CHECK_64BIT + assert( W_abs( ( ( L64_var1 - L64_var_out ) >> 1 ) - ( ( L64_var1 >> 1 ) - ( L64_var_out >> 1 ) ) ) < 2 ); +#endif L64_var_out = L64_var1 - L64_var_out; #ifdef WMOPS multiCounter[currCounter].W_msu0_16_16++; diff --git a/lib_com/ivas_spar_com_quant_util_fx.c b/lib_com/ivas_spar_com_quant_util_fx.c index 50820e240..988510569 100644 --- a/lib_com/ivas_spar_com_quant_util_fx.c +++ b/lib_com/ivas_spar_com_quant_util_fx.c @@ -356,23 +356,38 @@ void ivas_map_prior_coeffs_quant( { FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { +#ifdef FIX_2493_CHECK_EXTRACT_L_FIX_INSTRUMENTATION + Word16 trial1_16 = imult1616( sub( qs.PR.q_levels[0], 1 ), pSpar_md_prior->band_coeffs_idx[i].pred_index_re[j] ); /*q0*/ + pSpar_md_prior->band_coeffs_idx_mapped[i].pred_index_re[j] = round_fx( Mpy_32_16_1( one_by_q_lvl_PR_fx, trial1_16 ) ); /*q0*/ +#else Word32 trial1 = L_mult0( sub( qs.PR.q_levels[0], 1 ), pSpar_md_prior->band_coeffs_idx[i].pred_index_re[j] ); /*q0*/ trial1 = L_shl( trial1, 16 ); /*q16*/ trial1 = round_fx( Mpy_32_32( trial1, one_by_q_lvl_PR_fx ) ); /*q16+q31-31-16->0*/ pSpar_md_prior->band_coeffs_idx_mapped[i].pred_index_re[j] = extract_l( trial1 ); /*q0*/ +#endif move16(); +#ifdef FIX_2493_CHECK_EXTRACT_L_FIX_INSTRUMENTATION + Word16 trial2_16 = imult1616( sub( qs.P_r.q_levels[0], 1 ), pSpar_md_prior->band_coeffs_idx[i].decd_index_re[j] ); /*q0*/ + pSpar_md_prior->band_coeffs_idx_mapped[i].decd_index_re[j] = round_fx( Mpy_32_16_1( one_by_q_lvl_P_r_fx, trial2_16 ) ); /*q0*/ +#else Word32 trial2 = L_mult0( sub( qs.P_r.q_levels[0], 1 ), pSpar_md_prior->band_coeffs_idx[i].decd_index_re[j] ); /*q0*/ trial2 = L_shl( trial2, 16 ); /*q16*/ trial2 = round_fx( Mpy_32_32( trial2, one_by_q_lvl_P_r_fx ) ); /*q16+q31-31-16->0*/ pSpar_md_prior->band_coeffs_idx_mapped[i].decd_index_re[j] = extract_l( trial2 ); /*q0*/ +#endif move16(); } FOR( j = 0; j < IVAS_SPAR_MAX_C_COEFF; j++ ) { +#ifdef FIX_2493_CHECK_EXTRACT_L_FIX_INSTRUMENTATION + Word16 trial1_16 = imult1616( sub( qs.C.q_levels[0], 1 ), pSpar_md_prior->band_coeffs_idx[i].drct_index_re[j] ); /*q0*/ + pSpar_md_prior->band_coeffs_idx_mapped[i].drct_index_re[j] = round_fx( Mpy_32_16_1( one_by_q_lvl_C_fx, trial1_16 ) ); /*q0*/ +#else Word32 trial1 = L_mult0( sub( qs.C.q_levels[0], 1 ), pSpar_md_prior->band_coeffs_idx[i].drct_index_re[j] ); /*q0*/ trial1 = L_shl( trial1, 16 ); /*q16*/ trial1 = round_fx( Mpy_32_32( trial1, one_by_q_lvl_C_fx ) ); /*q16+q31-31-16->0*/ pSpar_md_prior->band_coeffs_idx_mapped[i].drct_index_re[j] = extract_l( trial1 ); /*q0*/ +#endif move16(); } } diff --git a/lib_com/options.h b/lib_com/options.h index aebd87cb0..ad9ad9739 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -100,6 +100,20 @@ #define FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI /* Nokia: BASOP issue 2442: Increase accuracy of computations and add additional gain clamp for low energy decorrelated signal rendering. */ #define FIX_FMSW_DEC_EXT /* float issue 1566: fix EXT output in format switching */ +#define FIX_2493_CHECK_64BIT /* FhG: Verify that 64 bit ops do not encounter an overflow. */ +#define NONBE_FIX_2493_EXTRACT_L_estDownmixGain_fx /* FhG: Fix extract_l overflow inside estDownmixGain_fx() */ +#define NONBE_FIX_2493_EXTRACT_L_swb_pre_proc_fx /* FhG: Fix extract_l overflow inside swb_pre_proc_fx(). Saturation, not a optimal fix. */ +#define NONBE_FIX_2493_EXTRACT_L_spectral_balancer_fx16 /* FhG: Fix extract_l overflow inside spectral_balancer_fx16(). Saturation, not a optimal fix. */ +#define NONBE_FIX_2493_EXTRACT_L_IGF_CalculateStereoEnvelope_fx /* FhG: Fix extract_l overflow inside IGF_CalculateStereoEnvelope_fx(). Was completely wrong. */ +#define NONBE_FIX_2493_EXTRACT_L_GetTCXMaxenergyChange_fx /* FhG: Fix extract_l overflow inside GetTCXMaxenergyChange_fx(). Saturation, not a optimal fix. */ +#define NONBE_FIX_2493_EXTRACT_L_res_bpf_adapt_ivas_fx /* FhG: Fix extract_l overflow inside res_bpf_adapt_ivas_fx() */ +#define NONBE_FIX_2493_EXTRACT_L_ivas_core_dec_fx /* FhG: Fix extract_l overflow inside ivas_core_dec_fx(). Saturation, not a optimal fix. */ +#define NONBE_FIX_2493_EXTRACT_L_d_syn_filt_fx /* FhG: Fix extract_l overflow inside d_syn_filt_fx(). W_shr( x, s ) with s out of range problem. */ +#define NONBE_FIX_2493_EXTRACT_L_acelp_core_dec_fx /* FhG: Fix extract_l overflow inside acelp_core_dec_fx() */ +#define NONBE_FIX_2493_EXTRACT_L_acelp_fast_fx /* FhG: Fix extract_l overflow inside acelp_fast_fx(). Saturation, not a optimal fix. */ +#define NONBE_FIX_2493_EXTRACT_L_swb_tbe_enc_fx /* FhG: Fix extract_l overflow inside swb_tbe_enc_fx() */ +#define NONBE_FIX_2493_EXTRACT_L_bw_detect_fx /* FhG: Fix extract_l overflow inside bw_detect_fx(). Saturation, not a optimal fix. */ +#define FIX_2493_CHECK_EXTRACT_L_FIX_INSTRUMENTATION /* FhG: Fix instrumentation related to extract_l. */ /* ##################### End NON-BE switches ########################### */ /* ################## End MAINTENANCE switches ######################### */ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index f0d79382c..b00a11477 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -2255,12 +2255,26 @@ ivas_error acelp_core_dec_fx( } ELSE { +#ifdef NONBE_FIX_2493_EXTRACT_L_acelp_core_dec_fx + Word16 exc_q; + Word16 old_bwe_exc_fx2[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; + + exc_q = s_min( st->Q_exc, shr( add( norm_arr( st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ), st->hBWE_TD->q_old_bwe_exc_extended_fx ), 1 ) ); + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, sub( shl( exc_q, 1 ), st->hBWE_TD->q_old_bwe_exc_extended_fx ) ); /* Q(q_old_bwe_exc_extended_fx) -> Q(2 * exc_q) */ + Copy_Scale_sig_nosat( old_bwe_exc_fx, old_bwe_exc_fx2, ( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ), sub( exc_q, st->Q_exc ) ); + non_linearity_fx( st->element_mode, old_bwe_exc_fx2 + PIT16k_MAX * 2, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, exc_q, st->coder_type, voice_factors_fx, st->L_frame ); + exp = sub( L_norm_arr( bwe_exc_extended_fx + L_FRAME32k, NL_BUFF_OFFSET ), 16 ); + Copy_Scale_sig_32_16_nosat( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, exp ); /* Q(2 * Q_exc) -> Q(q_old_bwe_exc_extended_fx) */ + st->hBWE_TD->q_old_bwe_exc_extended_fx = add( shl( exc_q, 1 ), exp ); + move16(); +#else Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), st->hBWE_TD->q_old_bwe_exc_extended_fx ) ) ); /* Q(q_old_bwe_exc_extended_fx) -> Q(2 * Q_exc) */ non_linearity_fx( st->element_mode, bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); exp = sub( L_norm_arr( bwe_exc_extended_fx + L_FRAME32k, NL_BUFF_OFFSET ), 16 ); Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, exp ); /* Q(2 * Q_exc) -> Q(q_old_bwe_exc_extended_fx) */ st->hBWE_TD->q_old_bwe_exc_extended_fx = add( shl( st->Q_exc, 1 ), exp ); move16(); +#endif } } diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index d2558f47c..e0da06bfa 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -990,8 +990,13 @@ Word16 res_bpf_adapt_ivas_fx( move16(); i_end = 64; move16(); +#ifdef NONBE_FIX_2493_EXTRACT_L_res_bpf_adapt_ivas_fx + bw_inv = 10486; + move16(); /* 1/(64 - 39) in Q18 */ +#else bw_inv = 1311; move16(); /* 1/(64 - 39) in Q15 */ +#endif } ELSE { @@ -999,8 +1004,13 @@ Word16 res_bpf_adapt_ivas_fx( move16(); i_end = 40; move16(); +#ifdef NONBE_FIX_2493_EXTRACT_L_res_bpf_adapt_ivas_fx + bw_inv = 21845; + move16(); /* 1/(40 - 28) in Q18 */ +#else bw_inv = 2720; move16(); /* 1/(40 - 28) in Q15*/ +#endif } /* Measure energy of high frequency band in MDCT domain */ @@ -1011,8 +1021,13 @@ Word16 res_bpf_adapt_ivas_fx( W_tmp = W_add_nosat( W_tmp, W_mult0_32_32( res_buf[i], res_buf[i] ) ); } +#ifdef NONBE_FIX_2493_EXTRACT_L_res_bpf_adapt_ivas_fx + res_hb_nrg = W_extract_h( W_shl( W_tmp, sub( 32 - 3, shl( q_res, 1 ) ) ) ); // Q-3 + res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 +#else res_hb_nrg = W_extract_l( W_shr( W_tmp, shl( q_res, 1 ) ) ); // Q0 res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 +#endif res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; move32(); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 06ae20608..f10025104 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -98,7 +98,9 @@ ivas_error ivas_core_dec_fx( Word32 synth_32_fx[CPE_CHANNELS][L_FRAME48k]; Word16 e_sig[CPE_CHANNELS]; Word16 tdm_lsfQ_PCh_fx[M]; +#ifndef NONBE_FIX_2493_EXTRACT_L_ivas_core_dec_fx Word32 conceal_eof_gain32; +#endif error = IVAS_ERR_OK; move32(); @@ -259,23 +261,47 @@ ivas_error ivas_core_dec_fx( test(); IF( !st->bfi && st->prev_bfi && GT_32( st->total_brate, SID_2k40 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) { +#ifdef NONBE_FIX_2493_EXTRACT_L_ivas_core_dec_fx + Word32 factor = Mpy_32_16_1( st->hTcxDec->conceal_eof_gain32, st->last_concealed_gain_syn_deemph ); + Word16 shift; + + shift = add( norm_l( factor ), norm_arr( st->hHQ_core->old_out_fx, st->hTcxDec->L_frameTCX ) ); + st->hHQ_core->Q_old_wtda = add( shift, sub( st->hHQ_core->Q_old_wtda, add( st->last_concealed_gain_syn_deemph_e, st->hTcxDec->conceal_eof_gain_e ) ) ); +#else conceal_eof_gain32 = L_shr_sat( st->hTcxDec->conceal_eof_gain32, sub( 16, st->hTcxDec->conceal_eof_gain_e ) ); // e = 31 - Q , 16 - e => 16 - (31 - Q) => Q - 15, // shr(16 -e ) = shr(Q -15) => 15 - Q ==> Q15 +#endif + FOR( i = 0; i < st->hTcxDec->L_frameTCX; i++ ) { +#ifdef NONBE_FIX_2493_EXTRACT_L_ivas_core_dec_fx + L_tmp = L_shl( Mpy_32_16_1( factor, st->hHQ_core->old_out_fx[i] ), shift ); // st->hHQ_core->Q_old_wtda + st->hHQ_core->old_out_fx[i] = extract_h( L_tmp ); +#else L_tmp = Mpy_32_16_1( conceal_eof_gain32, st->hHQ_core->old_out_fx[i] ); // Q0 (15+1+0 - (15 + 1) L_tmp = Mpy_32_16_1( L_tmp, st->last_concealed_gain_syn_deemph ); // Q(0+15 - last_concealed_gain_syn_deemph_e -15) L_tmp = L_shl( L_tmp, st->last_concealed_gain_syn_deemph_e ); // Q0 (-last_concealed_gain_syn_deemph_e +last_concealed_gain_syn_deemph_e) st->hHQ_core->old_out_fx[i] = extract_l( L_tmp ); // Q0 +#endif move16(); } +#ifdef NONBE_FIX_2493_EXTRACT_L_ivas_core_dec_fx + shift = add( norm_l( factor ), norm_arr( st->hHQ_core->old_out_LB_fx, st->L_frame ) ); + st->hHQ_core->Q_old_wtda_LB = add( shift, sub( st->hHQ_core->Q_old_wtda_LB, add( st->last_concealed_gain_syn_deemph_e, st->hTcxDec->conceal_eof_gain_e ) ) ); +#endif + FOR( i = 0; i < st->L_frame; i++ ) { +#ifdef NONBE_FIX_2493_EXTRACT_L_ivas_core_dec_fx + L_tmp = L_shl( Mpy_32_16_1( factor, st->hHQ_core->old_out_LB_fx[i] ), shift ); // st->hHQ_core->Q_old_wtda_LB + st->hHQ_core->old_out_LB_fx[i] = extract_h( L_tmp ); +#else L_tmp = Mpy_32_16_1( conceal_eof_gain32, st->hHQ_core->old_out_LB_fx[i] ); // Q0 (15+1+0 - (15 + 1) L_tmp = Mpy_32_16_1( L_tmp, st->last_concealed_gain_syn_deemph ); // Q(0+15 - last_concealed_gain_syn_deemph_e -15) L_tmp = L_shl( L_tmp, st->last_concealed_gain_syn_deemph_e ); // Q0 (-last_concealed_gain_syn_deemph_e +last_concealed_gain_syn_deemph_e) st->hHQ_core->old_out_LB_fx[i] = extract_l( L_tmp ); // Q0 +#endif move16(); } } diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index a088b44ad..8be016ef2 100755 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -656,7 +656,11 @@ static void d_syn_filt_fx( move32(); yy_q_fx[i] = sub( s_q_fx, 32 ); move16(); +#ifdef NONBE_FIX_2493_EXTRACT_L_d_syn_filt_fx + y_fx[i] = W_extract_l( W_shr( s_fx, s_min( 63, sub( s_q_fx, Q5 ) ) ) ); +#else y_fx[i] = W_extract_l( W_shr( s_fx, sub( s_q_fx, Q5 ) ) ); +#endif move32(); } *y_q_fx = Q5; diff --git a/lib_enc/bw_detect_fx.c b/lib_enc/bw_detect_fx.c index ff60b94d0..e357d9dee 100644 --- a/lib_enc/bw_detect_fx.c +++ b/lib_enc/bw_detect_fx.c @@ -413,11 +413,27 @@ void bw_detect_fx( cldfb_ener_offset_32 = L_deposit_l( cldfb_ener_offset ); /* Q14 in 32bit var */ cldfb_ener_offset_32 = L_shl( cldfb_ener_offset_32, 25 - 14 ); /* Q14 -> Q25 */ +#ifdef NONBE_FIX_2493_EXTRACT_L_bw_detect_fx + if ( st->element_mode == EVS_MONO ) + { + mean_NB = extract_l( L_shr( L_add( mean_NB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ + max_NB = extract_l( L_shr( L_add( max_NB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ + mean_WB = extract_l( L_shr( L_add( mean_WB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ + max_WB = extract_l( L_shr( L_add( max_WB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ + } + ELSE + { + mean_NB = extract_h( L_shr_sat( L_add( mean_NB32, cldfb_ener_offset_32 ), 25 - 11 - 16 ) ); /* (Q25 + Q25) -> Q11 */ + max_NB = extract_h( L_shr_sat( L_add( max_NB32, cldfb_ener_offset_32 ), 25 - 11 - 16 ) ); /* (Q25 + Q25) -> Q11 */ + mean_WB = extract_h( L_shr_sat( L_add( mean_WB32, cldfb_ener_offset_32 ), 25 - 11 - 16 ) ); /* (Q25 + Q25) -> Q11 */ + max_WB = extract_h( L_shr_sat( L_add( max_WB32, cldfb_ener_offset_32 ), 25 - 11 - 16 ) ); /* (Q25 + Q25) -> Q11 */ + } +#else mean_NB = extract_l( L_shr( L_add( mean_NB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ max_NB = extract_l( L_shr( L_add( max_NB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ mean_WB = extract_l( L_shr( L_add( mean_WB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ max_WB = extract_l( L_shr( L_add( max_WB32, cldfb_ener_offset_32 ), 25 - 11 ) ); /* (Q25 + Q25) -> Q11 */ - +#endif /*if WB */ IF( EQ_32( st->input_Fs, 16000 ) ) diff --git a/lib_enc/cod4t64_fast_fx.c b/lib_enc/cod4t64_fast_fx.c index c6a2811e0..9e08b5a51 100644 --- a/lib_enc/cod4t64_fast_fx.c +++ b/lib_enc/cod4t64_fast_fx.c @@ -401,7 +401,11 @@ void acelp_fast_fx( { s64 = W_mac0_16_16( s64, H[j], H[j - i] ); /* Q = shift + 6*/ } +#ifdef NONBE_FIX_2493_EXTRACT_L_acelp_fast_fx + *alp = extract_h( W_extract_h( W_shl( s64, sub( 48, shift ) ) ) ); /*Q6*/ +#else *alp = extract_l( W_extract_l( W_shr( s64, shift ) ) ); /*Q6*/ +#endif move16(); alp_buf[L_subfr - i] = *alp++; /*Q6*/ move16(); diff --git a/lib_enc/ivas_stereo_ica_enc_fx.c b/lib_enc/ivas_stereo_ica_enc_fx.c index f6fb65403..d5c5042f0 100644 --- a/lib_enc/ivas_stereo_ica_enc_fx.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -279,8 +279,12 @@ void spectral_balancer_fx16( x0 = signal[i]; /*Qx*/ move16(); // y0 = (y1 * a1) + (y2 * a2) + (x0 * b0) + (x1 * b1) + (x2 * b2); +#ifdef NONBE_FIX_2493_EXTRACT_L_spectral_balancer_fx16 + y0 = extract_h( W_extract_h( W_shl( 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 ), 2 + 16 ) ) ); // 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 - signal[i] = y0; /*Qx*/ +#endif + signal[i] = y0; /*Qx*/ move16(); y2 = y1; /*Qx*/ move16(); @@ -1310,9 +1314,22 @@ 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_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 = s_min( 16, norm_l( temp32 ) ); + currentGain = round_fx( L_shl( temp32, currentGain_e ) ); + currentGain_e = sub( 16, currentGain_e ); + if ( temp32 == 0 ) + { + currentGain_e = -15; + move16(); + } +#else currentGain = extract_l( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); /* Q15 */ currentGain_e = 0; move16(); +#endif test(); IF( EQ_16( element_mode, IVAS_CPE_TD ) && hStereoClassif != NULL ) diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 52444b37a..9fdbf3449 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -894,8 +894,21 @@ void swb_pre_proc_fx( { FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) { +#ifdef NONBE_FIX_2493_EXTRACT_L_swb_pre_proc_fx + IF( st->element_mode == EVS_MONO ) + { + 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 */ + } + ELSE + { + realQ_neg1 = extract_h( L_shr_sat( realBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 - 16 ) ); + imagQ_neg1 = extract_h( L_shr_sat( imagBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 - 16 ) ); /* 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) */ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 4b0b8b5e2..71b69e4ea 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -2977,7 +2977,11 @@ void swb_tbe_enc_fx( } ELSE IF( EQ_32( st_fx->extl_brate, SWB_TBE_1k10 ) || EQ_32( st_fx->extl_brate, SWB_TBE_1k75 ) ) { +#ifdef NONBE_FIX_2493_EXTRACT_L_swb_tbe_enc_fx + GainFrame_fx = L_shl( Mpy_32_32( GainFrame_fx, L_shl( L_tmp, 16 ) ), 2 ); +#else GainFrame_fx = Mpy_32_16_1( GainFrame_fx, extract_l( L_shl( L_tmp, 2 ) ) ); +#endif } ELSE { diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index f68923d69..2965c92f3 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -422,7 +422,11 @@ Word16 GetTCXMaxenergyChange_fx( { FOR( i = 0; i < nTotBlocks; i++ ) { +#ifdef NONBE_FIX_2493_EXTRACT_L_GetTCXMaxenergyChange_fx + maxEnergyChange = s_max( maxEnergyChange, extract_h( L_shl_sat( pSubblockNrgChange_32[i], sub( pSubblockNrgChange_32_exp[i], 28 - 16 ) ) ) ); // Q3 +#else maxEnergyChange = s_max( maxEnergyChange, extract_l( L_shl_sat( pSubblockNrgChange_32[i], sub( pSubblockNrgChange_32_exp[i], 28 ) ) ) ); // Q3 +#endif } } ELSE -- GitLab From 375179940f94d40862371b5d0b6b02a5a19c5dc9 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 8 Jun 2026 13:25:00 +0200 Subject: [PATCH 2/5] trigger --- lib_com/options.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_com/options.h b/lib_com/options.h index ad9ad9739..ff86f287f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -114,6 +114,7 @@ #define NONBE_FIX_2493_EXTRACT_L_swb_tbe_enc_fx /* FhG: Fix extract_l overflow inside swb_tbe_enc_fx() */ #define NONBE_FIX_2493_EXTRACT_L_bw_detect_fx /* FhG: Fix extract_l overflow inside bw_detect_fx(). Saturation, not a optimal fix. */ #define FIX_2493_CHECK_EXTRACT_L_FIX_INSTRUMENTATION /* FhG: Fix instrumentation related to extract_l. */ + /* ##################### End NON-BE switches ########################### */ /* ################## End MAINTENANCE switches ######################### */ -- GitLab From ff2623e44a3c2d0cbfaf0402c3e8ee398bbb1202 Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 8 Jun 2026 15:41:01 +0200 Subject: [PATCH 3/5] Add missing NONBE_FIX_2493_EXTRACT_L_IGF_CalculateStereoEnvelope_fx switch --- lib_enc/igf_enc_fx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index 27c3a7f2f..79c8467c2 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -2991,7 +2991,11 @@ static void IGF_CalculateStereoEnvelope_fx( { // currDampingFactor += 0.1f * ( ( 10 + adap ) - tonalToNoise ); Word32 temp2 = BASOP_Util_Add_Mant32Exp( L_add( L_shl( 10, sub( 15, adap_e ) ) /*exp:adap_e*/, adap ), add( adap_e, 16 ), L_negate( tonalToNoise ), tonalToNoise_e, &tmp_e ); /* resultant exp is tmp_e*/ +#ifdef NONBE_FIX_2493_EXTRACT_L_IGF_CalculateStereoEnvelope_fx + currDampingFactor_e = BASOP_Util_Add_MantExp( currDampingFactor_fx, currDampingFactor_e, extract_h( L_shl( Mult_32_16( temp2, 3277 /*0.1f Q15*/ ), 3 ) ), sub( tmp_e, 3 ), &currDampingFactor_fx ); /*stores resultant exp for currDampingFactor_fx*/ +#else currDampingFactor_e = BASOP_Util_Add_MantExp( currDampingFactor_fx, currDampingFactor_e, extract_l( Mult_32_16( temp2, 3277 /*0.1f Q15*/ ) ), tmp_e, &currDampingFactor_fx ); /*stores resultant exp for currDampingFactor_fx*/ +#endif } } -- GitLab From efc6c0cf3f8bc617ce0b633d6f85eb6df518a09b Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Mon, 8 Jun 2026 16:12:07 +0200 Subject: [PATCH 4/5] Simplification in NONBE_FIX_2493_EXTRACT_L_IGF_CalculateStereoEnvelope_fx --- lib_enc/igf_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index 79c8467c2..f39768828 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -2992,7 +2992,7 @@ static void IGF_CalculateStereoEnvelope_fx( // currDampingFactor += 0.1f * ( ( 10 + adap ) - tonalToNoise ); Word32 temp2 = BASOP_Util_Add_Mant32Exp( L_add( L_shl( 10, sub( 15, adap_e ) ) /*exp:adap_e*/, adap ), add( adap_e, 16 ), L_negate( tonalToNoise ), tonalToNoise_e, &tmp_e ); /* resultant exp is tmp_e*/ #ifdef NONBE_FIX_2493_EXTRACT_L_IGF_CalculateStereoEnvelope_fx - currDampingFactor_e = BASOP_Util_Add_MantExp( currDampingFactor_fx, currDampingFactor_e, extract_h( L_shl( Mult_32_16( temp2, 3277 /*0.1f Q15*/ ), 3 ) ), sub( tmp_e, 3 ), &currDampingFactor_fx ); /*stores resultant exp for currDampingFactor_fx*/ + currDampingFactor_e = BASOP_Util_Add_MantExp( currDampingFactor_fx, currDampingFactor_e, extract_h( Mult_32_16( temp2, 26214 /*0.1f Q15+3*/ ) ), sub( tmp_e, 3 ), &currDampingFactor_fx ); /*stores resultant exp for currDampingFactor_fx*/ #else currDampingFactor_e = BASOP_Util_Add_MantExp( currDampingFactor_fx, currDampingFactor_e, extract_l( Mult_32_16( temp2, 3277 /*0.1f Q15*/ ) ), tmp_e, &currDampingFactor_fx ); /*stores resultant exp for currDampingFactor_fx*/ #endif -- GitLab From ebccd1b1ddf5998d75e746a710d1ada3287d323e Mon Sep 17 00:00:00 2001 From: Manuel Jander Date: Wed, 17 Jun 2026 15:54:09 +0200 Subject: [PATCH 5/5] Change 64 bit addition/substraction overflow check according to proposal from Cadence. --- lib_basop/enh64.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_basop/enh64.c b/lib_basop/enh64.c index 0aba08822..808701a88 100644 --- a/lib_basop/enh64.c +++ b/lib_basop/enh64.c @@ -79,7 +79,7 @@ Word64 W_add_nosat( Word64 L64_var1, Word64 L64_var2 ) { Word64 L64_var_out; #ifdef FIX_2493_CHECK_64BIT - assert( W_abs( ( ( L64_var1 + L64_var2 ) >> 1 ) - ( ( L64_var1 >> 1 ) + ( L64_var2 >> 1 ) ) ) < 2 ); + assert( !( ( L64_var2 > 0 && L64_var1 > MAX_64 - L64_var2 ) || ( L64_var2 < 0 && L64_var1 < MIN_64 - L64_var2 ) ) ); #endif L64_var_out = L64_var1 + L64_var2; @@ -124,7 +124,7 @@ Word64 W_sub_nosat( Word64 L64_var1, Word64 L64_var2 ) { Word64 L64_var_out; #ifdef FIX_2493_CHECK_64BIT - assert( W_abs( ( ( L64_var1 - L64_var2 ) >> 1 ) - ( ( L64_var1 >> 1 ) - ( L64_var2 >> 1 ) ) ) < 2 ); + assert( !( ( L64_var2 < 0 && L64_var1 > MAX_64 + L64_var2 ) || ( L64_var2 > 0 && L64_var1 < MIN_64 + L64_var2 ) ) ); #endif L64_var_out = L64_var1 - L64_var2; @@ -438,7 +438,7 @@ Word64 W_mac_32_16( Word64 L64_var1, Word32 L_var2, Word16 var3 ) { Word64 L64_var_out = ( (Word64) L_var2 * var3 ) << 1; #ifdef FIX_2493_CHECK_64BIT - assert( W_abs( ( ( L64_var_out + L64_var1 ) >> 1 ) - ( ( L64_var_out >> 1 ) + ( L64_var1 >> 1 ) ) ) < 2 ); + assert( !( ( L64_var_out > 0 && L64_var1 > MAX_64 - L64_var_out ) || ( L64_var_out < 0 && L64_var1 < MIN_64 - L64_var_out ) ) ); #endif L64_var_out += L64_var1; #ifdef WMOPS @@ -488,7 +488,7 @@ Word64 W_msu_32_16( Word64 L64_var1, Word32 L_var2, Word16 var3 ) { Word64 L64_var_out = ( (Word64) L_var2 * var3 ) << 1; #ifdef FIX_2493_CHECK_64BIT - assert( W_abs( ( ( L64_var1 - L64_var_out ) >> 1 ) - ( ( L64_var1 >> 1 ) - ( L64_var_out >> 1 ) ) ) < 2 ); + assert( !( ( L64_var_out < 0 && L64_var1 > MAX_64 + L64_var_out ) || ( L64_var_out > 0 && L64_var1 < MIN_64 + L64_var_out ) ) ); #endif L64_var_out = L64_var1 - L64_var_out; #ifdef WMOPS @@ -617,7 +617,7 @@ Word64 W_mac0_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) { Word64 L64_var_out = (Word64) var2 * var3; #ifdef FIX_2493_CHECK_64BIT - assert( W_abs( ( ( L64_var_out + L64_var1 ) >> 1 ) - ( ( L64_var_out >> 1 ) + ( L64_var1 >> 1 ) ) ) < 2 ); + assert( !( ( L64_var_out > 0 && L64_var1 > MAX_64 - L64_var_out ) || ( L64_var_out < 0 && L64_var1 < MIN_64 - L64_var_out ) ) ); #endif L64_var_out += L64_var1; #ifdef WMOPS @@ -666,7 +666,7 @@ Word64 W_msu0_16_16( Word64 L64_var1, Word16 var2, Word16 var3 ) { Word64 L64_var_out = (Word64) var2 * var3; #ifdef FIX_2493_CHECK_64BIT - assert( W_abs( ( ( L64_var1 - L64_var_out ) >> 1 ) - ( ( L64_var1 >> 1 ) - ( L64_var_out >> 1 ) ) ) < 2 ); + assert( !( ( L64_var_out < 0 && L64_var1 > MAX_64 + L64_var_out ) || ( L64_var_out > 0 && L64_var1 < MIN_64 + L64_var_out ) ) ); #endif L64_var_out = L64_var1 - L64_var_out; #ifdef WMOPS -- GitLab