diff --git a/lib_com/options.h b/lib_com/options.h index 31c7862787b352ef04818c31775912fb439ab44d..92c5871eb0bf1c38039df9d2680804147f121880 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -99,6 +99,7 @@ #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 */ +#define FIX_2010_PREP_TBE_EXC /* FhG: fix issues with varying Q-values for code_preQ_fx[] */ /* #################### Start BASOP porting switches ############################ */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index ddd0bfdcc51c73c5048c67f73151a6456d451501..92512d3497c4975ba23271f621131aae5c86196a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3192,15 +3192,18 @@ void prep_tbe_exc_fx( Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - const Word16 T0, /* i : integer pitch variables Q0 */ - const Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +#ifdef FIX_2010_PREP_TBE_EXC + const Word16 Q_code_preQ, /* i : Q, prequantizer excitation */ +#endif + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + const Word16 T0, /* i : integer pitch variables Q0 */ + const Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ ); /*! r: Formant filter strength [0,1] */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c old mode 100755 new mode 100644 index be3d1f29c583a321f6326304e3dff866e8a09d6a..9f6b3f93b0a692f170c9a83577260b30fbc6b1bd --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7203,15 +7203,18 @@ void prep_tbe_exc_fx( Word16 bwe_exc_fx[], /* i/o: excitation for TBE Q_exc*/ const Word16 gain_preQ_fx, /* i : prequantizer excitation gain */ const Word16 code_preQ_fx[], /* i : prequantizer excitation */ - const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ - const Word16 T0, /* i : integer pitch variables Q0 */ - const Word16 T0_frac, /* i : Fractional pitch variables Q0*/ - const Word16 coder_type, /* i : coding type */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 element_mode, /* i : element mode */ - const Word16 idchan, /* i : channel ID */ - const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ +#ifdef FIX_2010_PREP_TBE_EXC + const Word16 Q_code_preQ, /* i : Q, prequantizer excitation */ +#endif + const Word16 Q_exc, /* i : Excitation, bwe_exc Q-factor */ + const Word16 T0, /* i : integer pitch variables Q0 */ + const Word16 T0_frac, /* i : Fractional pitch variables Q0*/ + const Word16 coder_type, /* i : coding type */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 element_mode, /* i : element mode */ + const Word16 idchan, /* i : channel ID */ + const Word16 flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ ) { @@ -7307,14 +7310,32 @@ void prep_tbe_exc_fx( ELSE { Word16 shift = 4; +#ifdef FIX_2010_PREP_TBE_EXC + /* multrus 2025-09-15 + TODO: + - leave shift = 4, since this is legacy code from EVS; + - check with vaillancourt, whether we really have a different scaling of code_preQ_fx[] for IVAS + - if the different scalings are confirmed, this condition could be simplified + */ + IF( NE_16( element_mode, EVS_MONO ) ) + { + /* shift of 4 assumes code_preQ_fx[] in Q10 - this is however not always given */ + shift = add( 2 + 1 - 1, Q_code_preQ ); /* gain_preQ_fx in Q2, code_preQ_fx[] in Q_code_preQ, 1 additional left-shift by L_mult() - factor of 2 (from "2 * gain_preQ * code_preQ[i]") */ + shift = sub( 16, shift ); + } +#endif move16(); IF( gain_preQ_fx != 0 ) { FOR( i = 0; i < L_subfr; i++ ) { /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ - Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ + Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ +#ifdef FIX_2010_PREP_TBE_EXC + Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q_code_preQ */ +#else + Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ +#endif #ifdef ISSUE_1836_replace_overflow_libcom Ltemp1 = L_shl_sat( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/ ); /*Q_exc+16 */ diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index d7f8f7ab073952d8407f89fb35dacecbe5995f59..b6554e02c7343616afa751b98551660230abc8bf 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -532,8 +532,13 @@ void decoder_acelp_fx( move16(); IF( st->igf != 0 ) { +#ifdef FIX_2010_PREP_TBE_EXC + prep_tbe_exc_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, + gain_preQ, code_preQ, Q10, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 ); +#else prep_tbe_exc_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc, gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 ); +#endif } /*---------------------------------------------------------* diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index ac1df74b23ec19152873c6464a294100f5ad86a0..39412a22e85a936a91905ce3689b58f7f82658ea 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -100,6 +100,10 @@ ivas_error decod_gen_voic_fx( Word16 pf_temp[MAXLAG_WI]; Word16 pf_n2[MAXLAG_WI]; MUSIC_POSTFILT_HANDLE hMusicPF; +#ifdef FIX_2010_PREP_TBE_EXC + Word16 Q_code_preQ; +#endif + gain_pit_fx = 0; gain_code_fx = 0; norm_gain_code_fx = 0; @@ -322,10 +326,33 @@ ivas_error decod_gen_voic_fx( idx = idiv1616( i_subfr_fx, L_SUBFR ); } +#ifdef FIX_2010_PREP_TBE_EXC + /* + 2025-09-15 multrus: + TODO: + check with vaillancourt + - where this difference between EVS and IVAS comes from + - where Q_code_preQ could be derived + - whether any of the above calculations need to be adjusted + */ + Q_code_preQ = Q6; + move16(); + if ( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + Q_code_preQ = Q10; + move16(); + } + + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[idx], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_code_preQ, + st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[idx], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, st_fx->Q_exc, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#endif /*----------------------------------------------------------------* diff --git a/lib_dec/dec_tran_fx.c b/lib_dec/dec_tran_fx.c index de3a1ff3fb8f8521004f0d0cb1d3dd1260e57e19..b30b1a8c066576225a9db240ba71d830c1e00e21 100644 --- a/lib_dec/dec_tran_fx.c +++ b/lib_dec/dec_tran_fx.c @@ -71,6 +71,9 @@ void decod_tran_fx( Word16 gain_code16; Word32 L_tmp; Word16 tmp16, tmp1_fx, tmp_fx; +#ifdef FIX_2010_PREP_TBE_EXC + Word16 Q_code_preQ; +#endif GSC_DEC_HANDLE hGSCDec; hGSCDec = st_fx->hGSCDec; MUSIC_POSTFILT_HANDLE hMusicPF; @@ -254,10 +257,33 @@ void decod_tran_fx( tmp_idx_2 = idiv1616( i_subfr, L_SUBFR ); } +#ifdef FIX_2010_PREP_TBE_EXC + /* + 2025-09-15 multrus: + TODO: + check with vaillancourt + - where this difference between EVS and IVAS comes from + - where Q_code_preQ could be derived + - whether any of the above calculations need to be adjusted + */ + Q_code_preQ = Q6; + move16(); + if ( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + Q_code_preQ = Q10; + move16(); + } + + prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_code_preQ, + st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#endif /*----------------------------------------------------------------* * Excitation enhancements (update of total excitation signal) diff --git a/lib_dec/ivas_td_low_rate_dec_fx.c b/lib_dec/ivas_td_low_rate_dec_fx.c index fb984f11fc32947a3a8f9867e28386c7438d0a0e..385096ba6d6d860d73dc06b7895167afe855b42e 100644 --- a/lib_dec/ivas_td_low_rate_dec_fx.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -326,7 +326,11 @@ void decod_gen_2sbfr_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef FIX_2010_PREP_TBE_EXC + prep_tbe_exc_fx( L_frame, 2 * L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR /*i_subfr / L_SUBFR*/], bwe_exc, 0, NULL, Q10, st->Q_exc, T0, T0_frac, GENERIC, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, 2 * L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR /*i_subfr / L_SUBFR*/], bwe_exc, 0, NULL, st->Q_exc, T0, T0_frac, GENERIC, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); +#endif voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR /*i_subfr / L_SUBFR*/]; /* Q15 */ move16(); diff --git a/lib_enc/cod_ace_fx.c b/lib_enc/cod_ace_fx.c index 5dae2f7f09fcecaa0f02f51d065e9c24b32a09f3..dc139873ad53da9cfcfcfdc1cb8851228ee454bc 100644 --- a/lib_enc/cod_ace_fx.c +++ b/lib_enc/cod_ace_fx.c @@ -377,9 +377,15 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * IF( st->igf != 0 ) { +#ifdef FIX_2010_PREP_TBE_EXC + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc, gain_preQ, code_preQ, Q10, Q_new, T0, T0_frac, st->coder_type, st->core_brate, + st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); +#endif } /*---------------------------------------------------------* diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index b425b2c28ebe2cfeb794cf147fcc93419d17d789..d0d293f704fd557ebcef5ea9afb2f29795411181 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -441,10 +441,22 @@ void encod_gen_voic_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef FIX_2010_PREP_TBE_EXC + /* multrus 2025-09-15 + TODO: + - check with vaillancourt, whether Q10 is the correct scaling - it contradicts comments above, where it's rather indicated as Q6 + - comparing againt float, Q10 seems to be correct + */ + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q10, Q_new, + T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. @@ -745,7 +757,7 @@ void encod_gen_voic_ivas_fx( Lgcode = L_shl_sat( gain_code_fx, Q_new ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_sat( Lgcode ); #else - Lgcode = L_shl_o( gain_code_fx, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ + Lgcode = L_shl_o( gain_code_fx, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_o( Lgcode, &Overflow ); #endif @@ -859,10 +871,17 @@ void encod_gen_voic_ivas_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef FIX_2010_PREP_TBE_EXC + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_AVQ_OUT_DEC, Q_new, + T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index e04d42331a9bb71b35bf1fa0bf2d67c5c29bab01..b355d540c3174ef338193168e5f8274ffcf4b0c0 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -330,8 +330,13 @@ Word16 encod_tran_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef FIX_2010_PREP_TBE_EXC + prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc_fx, gain_preQ, code_preQ, Q10, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. @@ -735,9 +740,15 @@ Word16 encod_tran_ivas_fx( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef FIX_2010_PREP_TBE_EXC + prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc_fx, gain_preQ, code_preQ, Q10, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); +#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. diff --git a/lib_enc/ivas_td_low_rate_enc_fx.c b/lib_enc/ivas_td_low_rate_enc_fx.c index 82bfcbd2f12c30884efa46f6a2c39db8bfaf8bc0..8832af43c6514cd37d29c9b7b1c5336fff71cbb5 100644 --- a/lib_enc/ivas_td_low_rate_enc_fx.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -376,7 +376,11 @@ void encod_gen_2sbfr( * Prepare TBE excitation *-----------------------------------------------------------------*/ +#ifdef FIX_2010_PREP_TBE_EXC + prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q10, Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); +#else prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); +#endif voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; /* Q15 */ move16();