From 0a3825bb32ac300460be380cf9105abbb9955fc4 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 12 Sep 2025 14:28:06 +0200 Subject: [PATCH 1/2] Add FIX_2000_NON_LINEARITY_OVERSHOOT to address SWB TBE overshoot in issue 2000 --- lib_com/options.h | 2 ++ lib_com/swb_tbe_com_fx.c | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index d2ffa2ca1..31c786278 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -98,6 +98,7 @@ #define FIX_2009_HIGH_NOISE_FLOOR_FOR_FX_DEC /* FhG: Corrected the q_input in the input of generate_masking_noise_dirac_ivas_fx() */ #define FIX_ISSUE_2013_MDCT_STEREO_DTX_DISCONTINUITIES /* Eri/FhG: Issue 2013 fix for dtx discontinuities */ #define FIX_ISSUE_2013_MDCT_STEREO_FER_DISCONTINUITIES /* Eri/FhG: Issue 2013 fix for FER discontinuities */ +#define FIX_2000_NON_LINEARITY_OVERSHOOT /* Eri: Issue 2000: SWB TBE energy overshoot in non-linearity. Aligns with float */ /* #################### Start BASOP porting switches ############################ */ @@ -114,6 +115,7 @@ #define NONBE_FIX_1376_MDCT_CONCEALMENT /* FhG: fix concealment artifact in MDCT Stereo with DTX, in case transition frame gets lost */ #define NONBE_1377_REND_DIRATT_CONF /* Eri: Issue 1377: Error in directivity attenuation configuration for both IVAS_dec and IVAS_rend */ + /* #################### End BASOP porting switches ############################ */ #endif diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6f5d2a4f0..6529a4a56 100755 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6221,13 +6221,22 @@ void non_linearity_ivas_fx( } #ifdef NONBE_1328_FIX_NON_LINEARITY - /* sc_factor = 32; */ /* Here we divide prev_scale, so 32 == 2 << (15-10) 1024.0 corresponds to 10 bits and 32 to 5 bits */ - /* if ( element_mode > EVS_MONO ) */ /* element mode is not needed because the function is duplicated for IVAS */ + /* sc_factor = 32; */ /* Here we divide prev_scale, so 32 == 2 << (15-10) 1024.0 corresponds to 10 bits and 32 to 5 bits */ + /* if ( element_mode > EVS_MONO ) */ /* element mode is not needed because the function is duplicated for IVAS */ +#ifdef FIX_2000_NON_LINEARITY_OVERSHOOT + sc_factor = s_max( sub( 12, norm_s( add( sub( j, length_half ), 1 ) ) ), 0 ); /* allowed intra frame jump is smaller */ + sc_factor = s_max( sc_factor, 1 ); +#else sc_factor = shl_sat( 1, sub( 16, max( 12 - norm_s( add( j, 1 ) ), 0 ) ) ); /* Adapt the scaling factor allowed depending of max position */ sc_factor = s_max( s_min( sc_factor, 16384 ), 2 * 32 ); /* note: The thresholding is purposely different between float and BASOP implementations. */ +#endif test(); +#ifdef FIX_2000_NON_LINEARITY_OVERSHOOT + IF( prev_scale <= 0 || GT_32( L_shr( prev_scale, sub( sc_factor, 1 ) /*Q30 -> Q31*/ ), scale /*Q31*/ ) ) +#else IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, sc_factor ) /*Q30 -> Q31*/, scale /*Q31*/ ) ) +#endif #else IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 64 ), scale ) ) #endif -- GitLab From 3073f8671eadd14bba0db8c87588ec2bb6a4667e Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 12 Sep 2025 15:23:58 +0200 Subject: [PATCH 2/2] Added missing fix NONBE_1328_FIX_NON_LINEARITY for first half-frame --- lib_com/swb_tbe_com_fx.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 6529a4a56..be3d1f29c 100755 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6125,13 +6125,21 @@ void non_linearity_ivas_fx( } #ifdef NONBE_1328_FIX_NON_LINEARITY +#ifdef FIX_2000_NON_LINEARITY_OVERSHOOT + sc_factor = s_max( sub( 13, norm_s( add( j, 1 ) ) ), 0 ); /* Adapt the scaling factor allowed depending of max position */ + sc_factor = s_max( sc_factor, 1 ); /* Note: The sc_factor is the log2 of the sc_factor in the float code to simplify condition below */ +#else /* sc_factor = 32; */ /* Here we divide prev_scale, so 32 == 2 << (15-10) 1024.0 corresponds to 10 bits and 32 to 5 bits */ /* if ( element_mode > EVS_MONO ) */ /* element mode is not needed because the function is duplicated for IVAS */ sc_factor = shl_sat( 1, sub( 16, max( 13 - norm_s( add( j, 1 ) ), 0 ) ) ); /* Adapt the scaling factor allowed depending of max position */ sc_factor = s_max( s_min( sc_factor, 16384 ), 2 * 32 ); /* note: The thresholding is purposely different between float and BASOP implementations. */ - +#endif test(); +#ifdef FIX_2000_NON_LINEARITY_OVERSHOOT + IF( prev_scale <= 0 || GT_32( L_shr( prev_scale, sub( sc_factor, 1 ) /*Q30 -> Q31*/ ), scale /*Q31*/ ) ) /* Since the sc_factor is the log2 of sc_factor in float, we apply it using L_shr */ +#else IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, sc_factor ) /*Q30 -> Q31*/, scale /*Q31*/ ) ) +#endif #else test(); IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, 64 ) /*Q30 -> Q31*/, scale /*Q31*/ ) ) @@ -6221,19 +6229,20 @@ void non_linearity_ivas_fx( } #ifdef NONBE_1328_FIX_NON_LINEARITY - /* sc_factor = 32; */ /* Here we divide prev_scale, so 32 == 2 << (15-10) 1024.0 corresponds to 10 bits and 32 to 5 bits */ - /* if ( element_mode > EVS_MONO ) */ /* element mode is not needed because the function is duplicated for IVAS */ #ifdef FIX_2000_NON_LINEARITY_OVERSHOOT + /* if ( element_mode > EVS_MONO ) */ /* element mode is not needed because the function is duplicated for IVAS */ sc_factor = s_max( sub( 12, norm_s( add( sub( j, length_half ), 1 ) ) ), 0 ); /* allowed intra frame jump is smaller */ - sc_factor = s_max( sc_factor, 1 ); + sc_factor = s_max( sc_factor, 1 ); /* Note: The sc_factor is the log2 of the sc_factor in the float code to simplify condition below */ #else + /* sc_factor = 32; */ /* Here we divide prev_scale, so 32 == 2 << (15-10) 1024.0 corresponds to 10 bits and 32 to 5 bits */ + /* if ( element_mode > EVS_MONO ) */ /* element mode is not needed because the function is duplicated for IVAS */ sc_factor = shl_sat( 1, sub( 16, max( 12 - norm_s( add( j, 1 ) ), 0 ) ) ); /* Adapt the scaling factor allowed depending of max position */ sc_factor = s_max( s_min( sc_factor, 16384 ), 2 * 32 ); /* note: The thresholding is purposely different between float and BASOP implementations. */ #endif test(); #ifdef FIX_2000_NON_LINEARITY_OVERSHOOT - IF( prev_scale <= 0 || GT_32( L_shr( prev_scale, sub( sc_factor, 1 ) /*Q30 -> Q31*/ ), scale /*Q31*/ ) ) + IF( prev_scale <= 0 || GT_32( L_shr( prev_scale, sub( sc_factor, 1 ) /*Q30 -> Q31*/ ), scale /*Q31*/ ) ) /* Since the sc_factor is the log2 of sc_factor in float, we apply it using L_shr */ #else IF( prev_scale <= 0 || GT_32( Mult_32_16( prev_scale, sc_factor ) /*Q30 -> Q31*/, scale /*Q31*/ ) ) #endif -- GitLab