diff --git a/lib_com/options.h b/lib_com/options.h index 0f464530e07c877e3d207bfb6a183a8827c79fcf..56282bb4a7e4c5f2769e2ea451eb2b5e519a66ce 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -123,6 +123,14 @@ #define FIX_1735_W_SHL_SAT_L /* FhG: Usage of W_shl_sat_l() */ #define FIX_ISSUE_1792 /* FhG: fix noise bursts in binaural rendering */ +/* Info for issue 1816: + * 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_1816_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_1816_IMPROVE_MPY_ZERO_DOT_1_PRECISION /* FhG: (NON-BE) improve precision of multiplications with factor 0.1f, avoids overflow with up-rounded value */ + #define FIX_ISSUE_1795_Q3_OVERFLOW /* FhG: Q3 overflow in function WB_BWE_gain_pred_fx (EVS legacy code) BE, MR1855 */ #define NONBE_FIX_1748_SPAR_DIV_OPT /*Dlb: issue 1748: SPAR common div optimizations*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 61dc3d0c56749685434360b3a72d0e8d6498a914..3ed08633c76d6e135dda5df6ae2f2b069adddf94 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -2723,6 +2723,38 @@ void swb_tbe_dec_fx( exp = 0; move16(); } +#ifdef FIX_ISSUE_1816_IMPROVE_MPY_ZERO_DOT_1_PRECISION + /* + code for EVS and IVAS are basically identical with the exception of i_mult_sat() which has precision issues + thus is was replaced for IVAS and kept for EVS, in order to keep EVS BE to test sequences and legacy implementations + */ + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + 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 ); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + } + ELSE + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); + 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 ); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + } +#else FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { temp = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ @@ -2733,6 +2765,7 @@ void swb_tbe_dec_fx( shaped_shb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ move16(); } +#endif /* Update SHB excitation */ Copy( shaped_shb_excitation + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ @@ -6285,6 +6318,38 @@ void ivas_swb_tbe_dec_fx( exp = 0; move16(); } +#ifdef FIX_ISSUE_1816_IMPROVE_MPY_ZERO_DOT_1_PRECISION + /* + code for EVS and IVAS are basically identical with the exception of i_mult_sat() which has precision issues + thus is was replaced for IVAS and kept for EVS, in order to keep EVS BE to test sequences and legacy implementations + */ + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + 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 ); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + } + ELSE + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp_fx = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); + 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 ); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + } +#else FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ @@ -6295,6 +6360,7 @@ void ivas_swb_tbe_dec_fx( shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ move16(); } +#endif } ELSE { diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index d016cd7216d58c7d8fcaccee58ea5994442c9f01..e1bbd3e19207c57baccfd7570c1cb54340112e0f 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -2535,6 +2535,38 @@ void swb_tbe_enc_fx( exp = 0; move16(); } +#ifdef FIX_ISSUE_1816_IMPROVE_MPY_ZERO_DOT_1_PRECISION + /* + code for EVS and IVAS are basically identical with the exception of i_mult_sat() which has precision issues + thus is was replaced for IVAS and kept for EVS, in order to keep EVS BE to test sequences and legacy implementations + */ + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + tmp = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + 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 */ + move16(); + } + } + ELSE + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + tmp = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); + 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 */ + move16(); + } + } +#else FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ @@ -2545,6 +2577,7 @@ void swb_tbe_enc_fx( shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ move16(); } +#endif /* Update SHB excitation */ Copy( shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ @@ -3831,6 +3864,38 @@ void swb_tbe_enc_ivas_fx( exp = 0; move16(); } +#ifdef FIX_ISSUE_1816_IMPROVE_MPY_ZERO_DOT_1_PRECISION + /* + code for EVS and IVAS are basically identical with the exception of i_mult_sat() which has precision issues + thus is was replaced for IVAS and kept for EVS, in order to keep EVS BE to test sequences and legacy implementations + */ + IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + tmp = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + 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 ); + L_tmp = Mult_32_16( L_tmp, 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 */ + move16(); + } + } + ELSE + { + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + tmp = round_fx_sat( L_shl( L_mult( 0x6666 /* 0.1 in Q12 */, shl( sub( i, 19 ), 11 ) ), 1 ) ); + 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 ); + L_tmp = Mult_32_16( L_tmp, 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 */ + move16(); + } + } +#else FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ @@ -3841,6 +3906,7 @@ void swb_tbe_enc_ivas_fx( shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ move16(); } +#endif } ELSE {