diff --git a/lib_com/options.h b/lib_com/options.h index 2345dd6a6b4f35ffd7cd1a569a9d59b660e7ed5a..d49cf2670b854568b383e0e2e17ed3ea23a45909 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -181,6 +181,8 @@ #define FIX_871_REMOVE_UNNECESSARY_CONDITION /* VA: remove a condition that is not needed and prevented correct frame classification of the secondary channel of the TD stereo */ #define FIX_875_SATURATION_DURING_ROUNDING /* VA: fix a possible saturation when rounding */ +#define FIX_882_LOW_LEVEL_DISCONTINUITIES /* VA: Fix 882, discontinuities for low level signal by adding a scaling function that uses rounding, this function is more complex than normal one, has to be used only when necessary*/ + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 93723ad4816a2b62e045afd676aaf4f8137c7e9c..ff6fd5bacfc9ef42577fea507fe6723d2c76a51c 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1373,7 +1373,13 @@ void scale_sig32( const Word16 lg, /* i : size of x[] Q0 */ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx xx exp */ ); - +#ifdef FIX_882_LOW_LEVEL_DISCONTINUITIES +void scale_sig32_r( + Word32 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx exp */ +); +#endif Word16 rescale_mem( const Word16 *Q_exc, /* i : current excitation scaling (>=0) */ Word16 *prev_Q_syn, /* i/o : scaling factor of previous frame */ diff --git a/lib_com/scale_mem_fx.c b/lib_com/scale_mem_fx.c index 2e61cb93851f6c4ecd3d80bc635244242a40b630..c02eff2a512d205ab069ba0e9004a0c11fb074ba 100644 --- a/lib_com/scale_mem_fx.c +++ b/lib_com/scale_mem_fx.c @@ -309,7 +309,23 @@ void scale_sig32( move32(); } } +#ifdef FIX_882_LOW_LEVEL_DISCONTINUITIES +void scale_sig32_r( + Word32 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx exp */ +) +{ + Word16 i; + FOR( i = 0; i < lg; i++ ) + { + /* saturation can occur here */ + x[i] = L_shl_r( x[i], exp0 ); + move32(); + } +} +#endif /*-------------------------------------------------------------------* * Rescale_mem: diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 1db6d1dd19372195e0254ac875f204581d6ce954..ef8670388ba9cb29199ca589b244e93c60934b6a 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1887,7 +1887,11 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_imag ); } - scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) +#ifdef FIX_882_LOW_LEVEL_DISCONTINUITIES + scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) +#else + scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) +#endif st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); Scale_sig32( save_hb_synth_fx, L_FRAME48k, sub( Q_real, 1 ) ); @@ -1966,7 +1970,11 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); } - scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#ifdef FIX_882_LOW_LEVEL_DISCONTINUITIES + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#else + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#endif st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); #ifndef MSAN_FIX @@ -2069,7 +2077,11 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); } +#ifdef FIX_882_LOW_LEVEL_DISCONTINUITIES + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#else scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#endif #ifndef MSAN_FIX Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); #endif