From a83457654ec4fd962d825ed8473acfb0e3ed4a21 Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 26 Jun 2025 09:45:11 +0200 Subject: [PATCH 01/12] fix mpy issue in i_mult (passed always 16-bit truncated product to saturate_o) --- lib_com/basop32.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index fbe08a11f..da5254b91 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -3582,13 +3582,14 @@ Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) #ifdef ORIGINAL_G7231 return a * b; #else - register Word32 c = a * b; + register Word32 c = (Word32) a * b; + return saturate_o( c, Overflow ); #endif } Word16 i_mult( Word16 a, Word16 b ) { - return i_mult_o( a, b, NULL ); + return i_mult_sat( a, b ); } Word16 i_mult_sat( Word16 a, Word16 b ) { -- GitLab From abd5d3d86652e25865f260c55055c30102bfdab6 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 27 Jun 2025 23:40:09 +0200 Subject: [PATCH 02/12] added watches into all i_mult functions, improved use of them in SWB TBE enc/dec for test-only --- Makefile | 3 +- lib_com/basop32.c | 8 +++ lib_com/basop32.h | 111 +++++++++++++++++++++++++++++++++++++-- lib_com/options.h | 8 +++ lib_dec/swb_tbe_dec_fx.c | 13 +++++ lib_enc/swb_tbe_enc_fx.c | 9 ++++ 6 files changed, 148 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 9d18cbde3..d212bb314 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,8 @@ endif CFLAGS += -std=c99 -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long \ -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \ -Werror-implicit-function-declaration \ - -Wno-implicit-fallthrough -ffp-contract=off + -Wno-implicit-fallthrough -ffp-contract=off \ + -Wno-attributes -Wno-unused-function # to be uncommented in CI # CFLAGS += -Werror CFLAGS += -Winit-self diff --git a/lib_com/basop32.c b/lib_com/basop32.c index da5254b91..6dd653764 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -3577,6 +3577,8 @@ Word16 DEPR_i_mult( Word16 a, Word16 b ) #endif } +#ifndef BASOP_WATCH_i_mult_o + Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) { #ifdef ORIGINAL_G7231 @@ -3587,15 +3589,21 @@ Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) return saturate_o( c, Overflow ); #endif } +#endif +#ifndef BASOP_WATCH_i_mult Word16 i_mult( Word16 a, Word16 b ) { return i_mult_sat( a, b ); } +#endif + +#ifndef BASOP_WATCH_i_mult_sat Word16 i_mult_sat( Word16 a, Word16 b ) { Flag Overflow; return i_mult_o( a, b, &Overflow ); } +#endif /* ****************************************************************************** * The following three operators are not part of the original diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 9bbf24f1c..672ea3095 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -102,6 +102,12 @@ extern Flag BASOP_Carry; #define BASOP_SATURATE_ERROR_OFF #define BASOP_CHECK() +/* BASOP-Watches */ +#define BASOP_WATCH_i_mult +#define BASOP_WATCH_i_mult_o +#define BASOP_WATCH_i_mult_sat +#define INLINE __attribute__((always_inline)) +#include #define MAX_32 (Word32) 0x7fffffffL #define MIN_32 (Word32) 0x80000000L @@ -177,7 +183,37 @@ Word32 L_sat( Word32 L_var1 ); /* Long saturation, 4 */ */ Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ -Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +//Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +#ifdef BASOP_WATCH_i_mult +#define i_mult(a,b) i_mult_watch(a,b, __FILE__, __LINE__) +static INLINE Word16 i_mult_watch( Word16 a, Word16 b , const char *fname, int linenumber) /* Weight FFS: currently assigned 3 */ +#else +static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FFS: currently assigned 3 */ +#endif /* BASOP_WATCH_i_mult */ +{ + Word32 c = (Word32) a * b; +#ifdef BASOP_WATCH_i_mult + static Word32 BASOP_WATCH_i_mult_Cnt = 0; + if (BASOP_WATCH_i_mult_Cnt == 0) + { + Word16 c1 = a * b; + if ((Word32) c1 != c) + { + printf( "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber); + BASOP_WATCH_i_mult_Cnt++; + } + } +#endif + if (c > MAX_16) + { + c = MAX_16; + } + else if (c < MIN_16) + { + c = MIN_16; + } + return (Word16) c; +} Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ /* @@ -190,7 +226,49 @@ Word32 L_msu0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Msu w/o shift 1 * /* * Overflowing operators */ -Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ); +//Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ); +#ifdef BASOP_WATCH_i_mult_o +#define i_mult_o( a, b, c ) i_mult_o_watch( a, b, c, __FILE__, __LINE__ ) +static INLINE Word16 i_mult_o_watch( Word16 a, Word16 b, Flag *Overflow, const char *fname, int linenumber ) +#else +static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer Mpy with ovl ? */ +#endif /* BASOP_WATCH_i_mult_o */ +{ +#ifdef ORIGINAL_G7231 + return a * b; +#else + Word32 c = (Word32) a * b; +#ifdef BASOP_WATCH_i_mult_o + static Word32 BASOP_WATCH_i_mult_o_Cnt = 0; + if (BASOP_WATCH_i_mult_o_Cnt == 0) + { + Word16 c1 = a * b; + if ( (Word32) c1 != c ) + { + printf( "BASOP WATCH i_mult_o: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X) <= 16 bit Overflow File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + if (Overflow == (Flag *) NULL) + printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber); + BASOP_WATCH_i_mult_o_Cnt++; + //return (Word16) c1; // Legacy return value to bypass Crash due to NULL pointer + } + } + +#endif /* BASOP_WATCH_i_mult_o */ + if (c > MAX_16) + { + c = MAX_16; + if (Overflow) + *Overflow = 1; + } + else if (c < MIN_16) + { + c = MIN_16; + if (Overflow) + *Overflow = 1; + } + return (Word16) c; +#endif /* ORIGINAL_G7231 */ +} Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ); Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ); @@ -220,7 +298,34 @@ Word32 L_msuNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *O /* * Saturating operators */ -Word16 i_mult_sat( Word16 a, Word16 b ); +//Word16 i_mult_sat( Word16 a, Word16 b ); +#ifdef BASOP_WATCH_i_mult_sat +#define i_mult_sat( a, b ) i_mult_sat_watch( a, b, __FILE__, __LINE__ ) +static INLINE Word16 i_mult_sat_watch( Word16 a, Word16 b, const char *fname, int linenumber ) +#else +static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with saturation */ +#endif /* BASOP_WATCH_i_mult_sat */ +{ + Word32 c = (Word32) a * b; + +#ifdef BASOP_WATCH_i_mult_sat + static Word32 BASOP_WATCH_i_mult_sat_Cnt = 0; + if (BASOP_WATCH_i_mult_sat_Cnt == 0) + { + Word16 c1 = a * b; /* emulate strange behaviour interpreting product as 16-bit */ + if ( (Word32) c1 != c ) + { + printf( "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + BASOP_WATCH_i_mult_sat_Cnt++; + } + } +#endif /* BASOP_WATCH_i_mult_sat */ + if (c > MAX_16) + c = MAX_16; + else if (c < MIN_16) + c = MIN_16; + return (Word16) c; +} Word16 add_sat( Word16 var1, Word16 var2 ); Word16 sub_sat( Word16 var1, Word16 var2 ); Word16 shl_sat( Word16 var1, Word16 var2 ); diff --git a/lib_com/options.h b/lib_com/options.h index 5f33170bf..d131a53eb 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -99,4 +99,12 @@ #define FIX_1762_COMPILER_ISSUE /* FhG: fix compiler issues with W_mac_32_32() + ONE_IN_Q30 */ +/* Info for issue 1771: + * Some compilers do not automatically use 32 bit for 16x16bit products. The code "Word32 c = (Word16) a * (Word16) b;" creates then a 16-bit result, sign-extending the + * lower 16-bit of the product, any upper bits are omitted. Example: Product 0x0100 * 0x0100 results in 0x0001.0000, gets truncated to its lower bits and return 0x0000. + * The issue is fixed by simply casting one of the product operands to Word32 in lib_com/basop32.c + */ +#define FIX_ISSUE_1771_USE_W32_FOR_MPY_W16xW16 /* FhG: (QA-FIX) Use doubled data width for 16x16 product, some compilers keep 16-bit format also for products */ +#define FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION /* FhG: (NON-BE) improve precision of multiplications with factor 0.1f, avoids overflow with up-rounded value */ + #endif diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 679e206e0..3432b7c70 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -2723,7 +2723,15 @@ void swb_tbe_dec_fx( } FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { + +#ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION + temp = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); +#else temp = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ +#endif + + + L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp ); /* Q31-exp */ temp = sub( 32767 /*1.0f Q15*/, temp ); Lscale = L_add( Mult_32_16( Lscale, temp ), L_tmp1 ); @@ -6285,7 +6293,12 @@ void ivas_swb_tbe_dec_fx( } FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { +#ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION + temp_fx = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); +#else temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ +#endif + L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ temp_fx = sub( 32767 /*1.0f Q15*/, temp_fx ); Lscale = L_add( Mult_32_16( Lscale, temp_fx ), L_tmp1 ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 6b65f9afa..a98f60b4b 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -2537,12 +2537,17 @@ void swb_tbe_enc_fx( } FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { +#ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION + tmp = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); +#else tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ +#endif L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ tmp = sub( 32767 /*1.0f Q15*/, tmp ); Lscale = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ + //printf("i_mult_o: tmp = 0x%04X (a=%d) Lscale = 0x%08X L_tmp = 0x%08X exc[%d] = 0x%04X\n", tmp&0xFFFF, i - 19, Lscale, L_tmp, i, shaped_shb_excitation_fx[i]); move16(); } @@ -3833,7 +3838,11 @@ void swb_tbe_enc_ivas_fx( } FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { +#ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION + tmp = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); +#else tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ +#endif L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ tmp = sub( 32767 /*1.0f Q15*/, tmp ); L_tmp = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); -- GitLab From 44b942d4579856a21e1f3c7a8f18365b43d315db Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 27 Jun 2025 23:48:41 +0200 Subject: [PATCH 03/12] fix clanf format issues --- lib_com/basop32.h | 76 ++++++++++++++++++++-------------------- lib_dec/swb_tbe_dec_fx.c | 7 ++-- lib_enc/swb_tbe_enc_fx.c | 10 +++--- 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 672ea3095..f7d5cfd62 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -106,7 +106,7 @@ extern Flag BASOP_Carry; #define BASOP_WATCH_i_mult #define BASOP_WATCH_i_mult_o #define BASOP_WATCH_i_mult_sat -#define INLINE __attribute__((always_inline)) +#define INLINE __attribute__( ( always_inline ) ) #include #define MAX_32 (Word32) 0x7fffffffL @@ -181,36 +181,36 @@ Word32 L_sat( Word32 L_var1 ); /* Long saturation, 4 */ /* * Additional G.723.1 operators */ -Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ -Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ -//Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ +Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ +// Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ #ifdef BASOP_WATCH_i_mult -#define i_mult(a,b) i_mult_watch(a,b, __FILE__, __LINE__) -static INLINE Word16 i_mult_watch( Word16 a, Word16 b , const char *fname, int linenumber) /* Weight FFS: currently assigned 3 */ +#define i_mult( a, b ) i_mult_watch( a, b, __FILE__, __LINE__ ) +static INLINE Word16 i_mult_watch( Word16 a, Word16 b, const char *fname, int linenumber ) /* Weight FFS: currently assigned 3 */ #else -static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FFS: currently assigned 3 */ -#endif /* BASOP_WATCH_i_mult */ +static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FFS: currently assigned 3 */ +#endif /* BASOP_WATCH_i_mult */ { Word32 c = (Word32) a * b; #ifdef BASOP_WATCH_i_mult static Word32 BASOP_WATCH_i_mult_Cnt = 0; - if (BASOP_WATCH_i_mult_Cnt == 0) + if ( BASOP_WATCH_i_mult_Cnt == 0 ) { Word16 c1 = a * b; - if ((Word32) c1 != c) + if ( (Word32) c1 != c ) { - printf( "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber); + printf( "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_Cnt++; } } #endif - if (c > MAX_16) + if ( c > MAX_16 ) { - c = MAX_16; + c = MAX_16; } - else if (c < MIN_16) + else if ( c < MIN_16 ) { - c = MIN_16; + c = MIN_16; } return (Word16) c; } @@ -226,12 +226,12 @@ Word32 L_msu0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Msu w/o shift 1 * /* * Overflowing operators */ -//Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ); +// Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ); #ifdef BASOP_WATCH_i_mult_o #define i_mult_o( a, b, c ) i_mult_o_watch( a, b, c, __FILE__, __LINE__ ) static INLINE Word16 i_mult_o_watch( Word16 a, Word16 b, Flag *Overflow, const char *fname, int linenumber ) #else -static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer Mpy with ovl ? */ +static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer Mpy with ovl ? */ #endif /* BASOP_WATCH_i_mult_o */ { #ifdef ORIGINAL_G7231 @@ -240,31 +240,31 @@ static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) Word32 c = (Word32) a * b; #ifdef BASOP_WATCH_i_mult_o static Word32 BASOP_WATCH_i_mult_o_Cnt = 0; - if (BASOP_WATCH_i_mult_o_Cnt == 0) + if ( BASOP_WATCH_i_mult_o_Cnt == 0 ) { Word16 c1 = a * b; if ( (Word32) c1 != c ) { printf( "BASOP WATCH i_mult_o: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X) <= 16 bit Overflow File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); - if (Overflow == (Flag *) NULL) - printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber); - BASOP_WATCH_i_mult_o_Cnt++; - //return (Word16) c1; // Legacy return value to bypass Crash due to NULL pointer + if ( Overflow == (Flag *) NULL ) + printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber ); + BASOP_WATCH_i_mult_o_Cnt++; + // return (Word16) c1; // Legacy return value to bypass Crash due to NULL pointer } } - + #endif /* BASOP_WATCH_i_mult_o */ - if (c > MAX_16) + if ( c > MAX_16 ) { - c = MAX_16; - if (Overflow) - *Overflow = 1; + c = MAX_16; + if ( Overflow ) + *Overflow = 1; } - else if (c < MIN_16) + else if ( c < MIN_16 ) { - c = MIN_16; - if (Overflow) - *Overflow = 1; + c = MIN_16; + if ( Overflow ) + *Overflow = 1; } return (Word16) c; #endif /* ORIGINAL_G7231 */ @@ -298,7 +298,7 @@ Word32 L_msuNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *O /* * Saturating operators */ -//Word16 i_mult_sat( Word16 a, Word16 b ); +// Word16 i_mult_sat( Word16 a, Word16 b ); #ifdef BASOP_WATCH_i_mult_sat #define i_mult_sat( a, b ) i_mult_sat_watch( a, b, __FILE__, __LINE__ ) static INLINE Word16 i_mult_sat_watch( Word16 a, Word16 b, const char *fname, int linenumber ) @@ -310,9 +310,9 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura #ifdef BASOP_WATCH_i_mult_sat static Word32 BASOP_WATCH_i_mult_sat_Cnt = 0; - if (BASOP_WATCH_i_mult_sat_Cnt == 0) + if ( BASOP_WATCH_i_mult_sat_Cnt == 0 ) { - Word16 c1 = a * b; /* emulate strange behaviour interpreting product as 16-bit */ + Word16 c1 = a * b; /* emulate strange behaviour interpreting product as 16-bit */ if ( (Word32) c1 != c ) { printf( "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); @@ -320,10 +320,10 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura } } #endif /* BASOP_WATCH_i_mult_sat */ - if (c > MAX_16) - c = MAX_16; - else if (c < MIN_16) - c = MIN_16; + if ( c > MAX_16 ) + c = MAX_16; + else if ( c < MIN_16 ) + c = MIN_16; return (Word16) c; } Word16 add_sat( Word16 var1, Word16 var2 ); diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 3432b7c70..888735d77 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -2725,13 +2725,12 @@ void swb_tbe_dec_fx( { #ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION - temp = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); + temp = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); #else temp = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ #endif - L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp ); /* Q31-exp */ temp = sub( 32767 /*1.0f Q15*/, temp ); Lscale = L_add( Mult_32_16( Lscale, temp ), L_tmp1 ); @@ -6294,9 +6293,9 @@ void ivas_swb_tbe_dec_fx( FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { #ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION - temp_fx = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); + temp_fx = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); #else - temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ #endif L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index a98f60b4b..a7422d77f 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -2538,16 +2538,16 @@ void swb_tbe_enc_fx( FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { #ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION - tmp = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); + tmp = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); #else - tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ + tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ #endif L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ tmp = sub( 32767 /*1.0f Q15*/, tmp ); Lscale = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ - //printf("i_mult_o: tmp = 0x%04X (a=%d) Lscale = 0x%08X L_tmp = 0x%08X exc[%d] = 0x%04X\n", tmp&0xFFFF, i - 19, Lscale, L_tmp, i, shaped_shb_excitation_fx[i]); + // printf("i_mult_o: tmp = 0x%04X (a=%d) Lscale = 0x%08X L_tmp = 0x%08X exc[%d] = 0x%04X\n", tmp&0xFFFF, i - 19, Lscale, L_tmp, i, shaped_shb_excitation_fx[i]); move16(); } @@ -3839,9 +3839,9 @@ void swb_tbe_enc_ivas_fx( FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { #ifdef FIX_ISSUE_1771_IMPROVE_MPY_ZERO_DOT_1_PRECISION - tmp = round_fx_sat(L_shl(L_mult(0x6666 /* 0.1 in Q12 */, shl(sub( i, 19 ), 11 ) ), 1)); + tmp = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); #else - tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ + tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ #endif L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ tmp = sub( 32767 /*1.0f Q15*/, tmp ); -- GitLab From 3e51437f38865c7f9bb3d13649f249d380789433 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 28 Jun 2025 13:08:17 +0200 Subject: [PATCH 04/12] added asserts in all i_mult BASOP watches, if critical condition (overflow) is true --- lib_com/basop32.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index f7d5cfd62..ce21f933b 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -201,6 +201,7 @@ static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FF { printf( "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_Cnt++; + assert(0); } } #endif @@ -250,6 +251,7 @@ static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer M printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber ); BASOP_WATCH_i_mult_o_Cnt++; // return (Word16) c1; // Legacy return value to bypass Crash due to NULL pointer + assert(0); } } @@ -317,6 +319,7 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura { printf( "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_sat_Cnt++; + assert(0); } } #endif /* BASOP_WATCH_i_mult_sat */ -- GitLab From 2f5a51b9c36ebe830390f6e4cea9c94fd0aa3e82 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 28 Jun 2025 13:12:26 +0200 Subject: [PATCH 05/12] fix clang-format --- lib_com/basop32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index ce21f933b..139db96ab 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -201,7 +201,7 @@ static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FF { printf( "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_Cnt++; - assert(0); + assert( 0 ); } } #endif @@ -251,7 +251,7 @@ static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer M printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber ); BASOP_WATCH_i_mult_o_Cnt++; // return (Word16) c1; // Legacy return value to bypass Crash due to NULL pointer - assert(0); + assert( 0 ); } } @@ -319,7 +319,7 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura { printf( "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_sat_Cnt++; - assert(0); + assert( 0 ); } } #endif /* BASOP_WATCH_i_mult_sat */ -- GitLab From aeae2035a6b0c20bb23100f0fe95ebf4093f4484 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 28 Jun 2025 13:17:51 +0200 Subject: [PATCH 06/12] added missing include for assert --- lib_com/basop32.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 139db96ab..817846cad 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -108,6 +108,7 @@ extern Flag BASOP_Carry; #define BASOP_WATCH_i_mult_sat #define INLINE __attribute__( ( always_inline ) ) #include +#include #define MAX_32 (Word32) 0x7fffffffL #define MIN_32 (Word32) 0x80000000L -- GitLab From d67277b36befdfe7ee9274bf4754875d01d56568 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 28 Jun 2025 15:40:53 +0200 Subject: [PATCH 07/12] used stderr for BASOP WATCHES for i_mult --- lib_com/basop32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 817846cad..90e53e97a 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -200,7 +200,7 @@ static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FF Word16 c1 = a * b; if ( (Word32) c1 != c ) { - printf( "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + fprintf(stderr, "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_Cnt++; assert( 0 ); } @@ -247,7 +247,7 @@ static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer M Word16 c1 = a * b; if ( (Word32) c1 != c ) { - printf( "BASOP WATCH i_mult_o: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X) <= 16 bit Overflow File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + fprintf(stderr, "BASOP WATCH i_mult_o: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X) <= 16 bit Overflow File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); if ( Overflow == (Flag *) NULL ) printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber ); BASOP_WATCH_i_mult_o_Cnt++; @@ -318,7 +318,7 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura Word16 c1 = a * b; /* emulate strange behaviour interpreting product as 16-bit */ if ( (Word32) c1 != c ) { - printf( "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + fprintf(stderr, "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_sat_Cnt++; assert( 0 ); } -- GitLab From 2a00f47d74f520aeac718003c19470962695f5d7 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 28 Jun 2025 15:44:22 +0200 Subject: [PATCH 08/12] fix clang-format --- lib_com/basop32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 90e53e97a..8c3eccea3 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -200,7 +200,7 @@ static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FF Word16 c1 = a * b; if ( (Word32) c1 != c ) { - fprintf(stderr, "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + fprintf( stderr, "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_Cnt++; assert( 0 ); } @@ -247,7 +247,7 @@ static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer M Word16 c1 = a * b; if ( (Word32) c1 != c ) { - fprintf(stderr, "BASOP WATCH i_mult_o: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X) <= 16 bit Overflow File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + fprintf( stderr, "BASOP WATCH i_mult_o: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X) <= 16 bit Overflow File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); if ( Overflow == (Flag *) NULL ) printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber ); BASOP_WATCH_i_mult_o_Cnt++; @@ -318,7 +318,7 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura Word16 c1 = a * b; /* emulate strange behaviour interpreting product as 16-bit */ if ( (Word32) c1 != c ) { - fprintf(stderr, "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); + fprintf( stderr, "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_sat_Cnt++; assert( 0 ); } -- GitLab From 62b4fe983951adc31c96009efa5614f15f6b91cc Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 29 Jun 2025 08:58:33 +0200 Subject: [PATCH 09/12] i_mult returns now result of buggy compiler --- lib_com/basop32.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 8c3eccea3..02ac70d01 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -202,7 +202,8 @@ static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FF { fprintf( stderr, "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_Cnt++; - assert( 0 ); + //assert( 0 ); + return c1; } } #endif @@ -251,8 +252,8 @@ static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer M if ( Overflow == (Flag *) NULL ) printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber ); BASOP_WATCH_i_mult_o_Cnt++; - // return (Word16) c1; // Legacy return value to bypass Crash due to NULL pointer - assert( 0 ); + // assert( 0 ); + return c1; // Legacy return value to bypass Crash due to NULL pointer } } @@ -320,7 +321,8 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura { fprintf( stderr, "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_sat_Cnt++; - assert( 0 ); + //assert( 0 ); + return c1; } } #endif /* BASOP_WATCH_i_mult_sat */ -- GitLab From a1945146198293b6aeb24f0ff6a7f676f654b5ab Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 29 Jun 2025 09:04:26 +0200 Subject: [PATCH 10/12] fix clang-format --- lib_com/basop32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 02ac70d01..6f4466338 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -202,7 +202,7 @@ static INLINE Word16 i_mult( Word16 a, Word16 b ) /* Weight FF { fprintf( stderr, "BASOP WATCH i_mult: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow in File: %s, line: %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_Cnt++; - //assert( 0 ); + // assert( 0 ); return c1; } } @@ -253,7 +253,7 @@ static INLINE Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) /* integer M printf( "BASOP WATCH i_mult_o: Overflow == NULL File: %s, line: %d\n", fname, linenumber ); BASOP_WATCH_i_mult_o_Cnt++; // assert( 0 ); - return c1; // Legacy return value to bypass Crash due to NULL pointer + return c1; // Legacy return value to bypass Crash due to NULL pointer } } @@ -321,7 +321,7 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura { fprintf( stderr, "BASOP WATCH i_mult_sat: 0x%08X = 0x%04X * 0x%04X (legacy: 0x%08X <= 16 bit overflow File: %s line %d\n", c, a & 0xFFFF, b & 0xFFFF, (Word32) c1, fname, linenumber ); BASOP_WATCH_i_mult_sat_Cnt++; - //assert( 0 ); + // assert( 0 ); return c1; } } -- GitLab From 43e927f7c66bcf9f4fa3dd6ca0393e69944431ba Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 1 Jul 2025 22:16:11 +0200 Subject: [PATCH 11/12] only for test: print critical i_mult use always --- lib_com/basop32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 6f4466338..9ac031606 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -314,7 +314,7 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura #ifdef BASOP_WATCH_i_mult_sat static Word32 BASOP_WATCH_i_mult_sat_Cnt = 0; - if ( BASOP_WATCH_i_mult_sat_Cnt == 0 ) + if (( BASOP_WATCH_i_mult_sat_Cnt == 0 ) || 1) { Word16 c1 = a * b; /* emulate strange behaviour interpreting product as 16-bit */ if ( (Word32) c1 != c ) -- GitLab From 4b4169b2fb02e75761ecebc9cae2428288f864d0 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 2 Jul 2025 08:24:37 +0200 Subject: [PATCH 12/12] fix clang-format --- lib_com/basop32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 9ac031606..b74b14fb7 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -314,7 +314,7 @@ static INLINE Word16 i_mult_sat( Word16 a, Word16 b ) /* integer Mpy with satura #ifdef BASOP_WATCH_i_mult_sat static Word32 BASOP_WATCH_i_mult_sat_Cnt = 0; - if (( BASOP_WATCH_i_mult_sat_Cnt == 0 ) || 1) + if ( ( BASOP_WATCH_i_mult_sat_Cnt == 0 ) || 1 ) { Word16 c1 = a * b; /* emulate strange behaviour interpreting product as 16-bit */ if ( (Word32) c1 != c ) -- GitLab