diff --git a/lib_com/options.h b/lib_com/options.h index be4d83b0519d523ecc2822c6db6cf2a292d7acd5..d53b7d6a30590f91df7352489242629fa278a15a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -84,6 +84,7 @@ #define FIX_BASOP_ASSERT_IN_TONAL_MDCT_PLC /* FhG: fix for issue 2165 - using saturating addition in tonal MDCT PLC function */ #define OPT_2146_BASOP_UTIL_ADD_MANT32EXP /* Dlb: optimized version of BASOP_Util_Add_Mant32Exp() */ +#define FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE /* FhG: Use dynamic Q factor for synth_fx and synthFB_fx to prevent overflow */ /* ################### End FIXES switches ########################### */ /* #################### Start BASOP porting switches ############################ */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 32b8a00ee5d5457391c29147ac2dbdce9bcbde59..85984d53d3fad418a929f2f4be27ce08936c17ee 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9101,6 +9101,9 @@ void decoder_tcx_ivas_fx( Word16 Aind[], Word16 synth_fx[], Word16 synthFB_fx[], +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Word16 *synth_q, +#endif const Word16 bfi, const Word16 frame_cnt, const Word16 sba_dirac_stereo_flag ); diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index ee8273a7b1b169da8679322e3ec9942974edaadd..a8db9f9cc43b08f7499839611e2dac97a8589c12 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -3970,10 +3970,16 @@ void decoder_tcx_IGF_stereo_fx( void decoder_tcx_ivas_fx( Decoder_State *st, Word16 prm[], - Word16 A_fx[], // Q: 14 - norm_s(A_fx[0]) - Word16 Aind[], // Q: 14 - norm_s(Aind[0]) + Word16 A_fx[], // Q: 14 - norm_s(A_fx[0]) + Word16 Aind[], // Q: 14 - norm_s(Aind[0]) +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Word16 synth_fx[], + Word16 synthFB_fx[], + Word16 *synth_q, +#else Word16 synth_fx[], // Q_syn Word16 synthFB_fx[], // Q_syn +#endif const Word16 bfi, const Word16 frame_cnt, const Word16 sba_dirac_stereo_flag ) @@ -4063,8 +4069,9 @@ void decoder_tcx_ivas_fx( move16(); q_winFB = st->Q_syn; move16(); - +#ifndef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE assert( q_win == 0 ); +#endif Scale_sig( synth_fx, L_frame_glob, sub( q_win, st->Q_syn ) ); // Scaling to Q_syn Scale_sig( synthFB_fx, L_frameTCX_glob, sub( q_winFB, st->Q_syn ) ); // Scaling to Q_syn @@ -4073,8 +4080,18 @@ void decoder_tcx_ivas_fx( fUseTns, &synth_fx[0], &synthFB_fx[0], bfi, frame_cnt, sba_dirac_stereo_flag ); /* Scaling up again */ +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Word16 q_min = s_min( add( q_win, getScaleFactor16( synth_fx, L_frame_glob ) ), + add( q_winFB, getScaleFactor16( synthFB_fx, L_frameTCX_glob ) ) ); + q_min = s_min( q_min, st->Q_syn ); + Scale_sig( synth_fx, L_frame_glob, sub( q_min, q_win ) ); + Scale_sig( synthFB_fx, L_frameTCX_glob, sub( q_min, q_winFB ) ); + *synth_q = q_min; +#else Scale_sig( synth_fx, L_frame_glob, sub( st->Q_syn, q_win ) ); Scale_sig( synthFB_fx, L_frameTCX_glob, sub( st->Q_syn, q_winFB ) ); +#endif + // Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, 1 ); Scale_sig( st->hTcxDec->old_syn_Overl, 320, ( -2 - st->hTcxDec->Q_old_syn_Overl ) ); // Scaling to Q-2 diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 7cb4f897b24cc393f5589f14aaf2d0530ee9de4c..2c197d23d2645f71fe02088996c11b3beef14b04 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -105,7 +105,11 @@ void con_tcx_fx( Word16 pre_emph_buf; Word16 hp_filt[L_FIR_FER2]; Word16 alpha; +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Word16 tmp_deemph, gain, gainCNG, gain_inov, scf; +#else Word16 tmp_deemph, gain, gainCNG, gain_inov; +#endif Word16 *pt_exc, *pt1_exc; Word16 Tc, tmpSeed; Word16 fUseExtrapolatedPitch; @@ -190,9 +194,16 @@ void con_tcx_fx( IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc ) { /* apply pre-emphasis to the signal */ +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + mem = shl( synth[( -( ( ( shr( L_frame, 1 ) + hTcxDec->pit_max_TCX ) + M + M ) ) - 1 )], st->Q_syn_factor ); /*Q0*/ +#else mem = synth[( -( ( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) ) - 1 )]; /*Q0*/ +#endif move16(); Q_exc = E_UTIL_f_preemph3( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 ); +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Scale_sig( &( synth[-( ( shr( L_frame, 1 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), negate( st->Q_syn_factor ) ); /*Q0, Setting back to Q0, as the following calculations are implemented assuming synth is in Q0 */ +#endif st->Mode2_lp_gainc = L_deposit_l( 0 ); st->Mode2_lp_gainp = get_gain2( synth - shl( L_subfr, 1 ), synth - add( shl( L_subfr, 1 ), Tc ), shl( L_subfr, 1 ) ); /*Q16*/ @@ -231,9 +242,16 @@ void con_tcx_fx( ELSE { /* apply pre-emphasis to the signal */ - mem = synth[( -L_frame - 1 )]; /*Q0*/ +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + mem = shl( synth[( -L_frame - 1 )], st->Q_syn_factor ); /*Q0*/ +#else + mem = synth[( -L_frame - 1 )]; /*Q0*/ +#endif move16(); Q_exc = E_UTIL_f_preemph3( &( synth[-L_frame] ), st->preemph_fac, L_frame, &mem, 1 ); +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Scale_sig( &synth[-L_frame], L_frame, negate( st->Q_syn_factor ) ); /*Q0, Setting back to Q0, as the following calculations are implemented assuming synth is in Q0 */ +#endif Copy( st->old_Aq_12_8_fx, A_local, M + 1 ); /*Q12*/ offset = shr( L_frame, 1 ); @@ -766,9 +784,26 @@ void con_tcx_fx( syn = buf + M; /*Q_syn*/ Copy( synth - M, buf, M ); /*Q_syn*/ +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + IF( NE_32( st->element_mode, EVS_MONO ) ) // to keep evs bit-exactness + { + scf = norm_s( tmp_deemph ); + new_Q = sub( Q_exc, 4 ); + new_Q = s_max( new_Q, -1 ); + new_Q = s_min( new_Q, scf ); + } + ELSE + { + new_Q = sub( Q_exc, 3 ); + new_Q = s_max( new_Q, -1 ); + scf = 0; + move16(); + } +#else new_Q = sub( Q_exc, 3 ); new_Q = s_max( new_Q, -1 ); +#endif tmp16 = s_min( new_Q, st->prev_Q_syn ); st->prev_Q_syn = new_Q; @@ -779,8 +814,24 @@ void con_tcx_fx( move16(); Copy_Scale_sig( buf, mem_syn, M, exp_scale ); /*Q: tmp16*/ - +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + IF( NE_32( st->element_mode, EVS_MONO ) ) // to keep evs bit-exactness + { + if ( GT_16( sub( Q_syn, st->Q_syn_factor ), scf ) ) + { + Q_syn = add( scf, st->Q_syn_factor ); // so that (Q_syn - st->Q_syn_factor) = scf; + } + tmp_deemph = shl( tmp_deemph, sub( Q_syn, st->Q_syn_factor ) ); + } + ELSE + { + tmp_deemph = shl_sat( tmp_deemph, Q_syn ); /*Q_syn*/ + } + st->Q_syn_factor = 0; + move16(); +#else tmp_deemph = shl_sat( tmp_deemph, Q_syn ); /*Q_syn*/ +#endif st->Q_syn = Q_syn; move16(); diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index f3020662b8c87fd826cc41db8c9b65487b673b13..1fd7cb0f321f0433359b5e141c513ee0cf3e72b2 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -522,6 +522,16 @@ ivas_error ivas_core_dec_fx( Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, add( M, 1 ), sub( norm_s( sub( st->hFdCngDec->hFdCngCom->A_cng[0], 1 ) ), 3 ) ); // Qx } +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + IF( ( EQ_32( st->last_core, TCX_10_CORE ) || EQ_32( st->last_core, TCX_20_CORE ) ) || // st->Q_syn_factor is set in TCX mode; otherwise, it may be uninitialized + ( hCPE != NULL && ( GT_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && ( ( EQ_32( sts[0]->last_core, TCX_10_CORE ) || EQ_32( sts[0]->last_core, TCX_20_CORE ) ) ) ) ) ) // In this case, sts[1] gets its value from sts[0]. + { + Scale_sig( st->old_exc_fx, L_EXC_MEM_DEC, negate( st->Q_syn_factor ) ); + st->Q_syn = add( st->Q_syn, st->Q_syn_factor ); + } + st->Q_syn_factor = 0; + move16(); +#endif IF( NE_32( ( error = acelp_core_dec_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hStereoCng, read_sid_info ) ), IVAS_ERR_OK ) ) { return error; @@ -597,8 +607,11 @@ ivas_error ivas_core_dec_fx( } stereo_tcx_core_dec_fx( st, frameMode[n], output_16_fx[n], synth_16_fx[n], pitch_buf_fx[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hStereoCng, nchan_out, ivas_format ); - +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], output_frame, sub( Q11, st->Q_syn_factor ) ); // Q11 +#else Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], output_frame, Q11 ); // Q11 +#endif IF( st->hTcxDec ) { @@ -622,6 +635,10 @@ ivas_error ivas_core_dec_fx( move16(); Q_synth = 0; move16(); +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + st->Q_syn_factor = 0; + move16(); +#endif ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); @@ -805,7 +822,11 @@ ivas_error ivas_core_dec_fx( *---------------------------------------------------------------------*/ /*core_switching_post_dec*/ +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Q_synth = add( sub( 15, e_sig[0] ), st->Q_syn_factor ); +#else Q_synth = sub( 15, e_sig[0] ); +#endif /*------------------fix-to-fix-end-----------------------*/ diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c index da6adcf338b516d34c97671912252022e0075d3e..76041da3972c25556d65eb30efb00b2fc0fc9bb1 100644 --- a/lib_dec/ivas_stereo_switching_dec_fx.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -1951,6 +1951,10 @@ void stereo_switching_dec( Copy( sts[0]->old_exc_fx, sts[1]->old_exc_fx, L_EXC_MEM_DEC ); /* Q_exc */ sts[1]->Q_exc = sts[0]->Q_exc; move16(); +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + sts[1]->Q_syn_factor = sts[0]->Q_syn_factor; + move16(); +#endif sts[1]->Q_exc_cng = sts[0]->Q_exc_cng; move16(); sts[1]->prev_Q_exc = sts[0]->prev_Q_exc; diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index b36aad0c187920f8cfcb38dd974b11b18415b28a..6ee4bfe1899b36e77e6d4878d8e367ee5d6aaacf 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -234,7 +234,9 @@ void stereo_tcx_core_dec_fx( Word16 *synth_fx; Word16 synth_bufFB_fx[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; Word16 *synthFB_fx; - +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Word16 synth_q[2]; +#endif Word32 psd_fx[L_FRAME16k]; Word32 psd_part_fx[NPART_SHAPING]; Word16 psd_part_e; @@ -335,7 +337,13 @@ void stereo_tcx_core_dec_fx( st->core = GetPLCModeDecision_ivas_fx( st ); /* Q0 */ move16(); } - +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + IF( st->core != ACELP_CORE ) + { + st->Q_syn_factor = 0; + move16(); + } +#endif /*--------------------------------------------------------------------------------* * LPC envelope decoding *--------------------------------------------------------------------------------*/ @@ -596,7 +604,13 @@ void stereo_tcx_core_dec_fx( } /* TCX decoder */ +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + decoder_tcx_ivas_fx( st, prm, Aq_fx, Aind, &synth_fx[0], &synthFB_fx[0], &synth_q[0], bfi, 0, sba_dirac_stereo_flag ); + st->Q_syn_factor = sub( synth_q[0], st->Q_syn ); + st->Q_syn = synth_q[0]; +#else decoder_tcx_ivas_fx( st, prm, Aq_fx, Aind, &synth_fx[0], &synthFB_fx[0], bfi, 0, sba_dirac_stereo_flag ); +#endif } /*--------------------------------------------------------------------------------* @@ -625,8 +639,27 @@ void stereo_tcx_core_dec_fx( } /* TCX decoder */ +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + decoder_tcx_ivas_fx( st, prm, Aq_fx, Aind, &synth_fx[k * st->L_frame / 2], &synthFB_fx[k * ( hTcxDec->L_frameTCX / 2 )], &synth_q[k], bfi, k, sba_dirac_stereo_flag ); + } + + Word16 q_min, q_shift; + + q_min = s_min( synth_q[0], synth_q[1] ); + st->Q_syn_factor = sub( q_min, st->Q_syn ); + st->Q_syn = q_min; + + q_shift = sub( q_min, synth_q[0] ); + scale_sig( &synth_fx[0], shr( st->L_frame, 1 ), q_shift ); + scale_sig( &synthFB_fx[0], shr( hTcxDec->L_frameTCX, 1 ), q_shift ); + + q_shift = sub( q_min, synth_q[1] ); + scale_sig( &synth_fx[shr( st->L_frame, 1 )], shr( st->L_frame, 1 ), q_shift ); + scale_sig( &synthFB_fx[shr( hTcxDec->L_frameTCX, 1 )], shr( hTcxDec->L_frameTCX, 1 ), q_shift ); +#else decoder_tcx_ivas_fx( st, prm, Aq_fx, Aind, &synth_fx[k * st->L_frame / 2], &synthFB_fx[k * ( hTcxDec->L_frameTCX / 2 )], bfi, k, sba_dirac_stereo_flag ); } +#endif } /*--------------------------------------------------------------------------------* @@ -670,10 +703,17 @@ void stereo_tcx_core_dec_fx( #endif IF( !bfi && st->hTonalMDCTConc != NULL ) { +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + TonalMDCTConceal_SaveTimeSignal_ivas_fx( st->hTonalMDCTConc, synthFB_fx, st->Q_syn, hTcxDec->L_frameTCX ); +#else TonalMDCTConceal_SaveTimeSignal_ivas_fx( st->hTonalMDCTConc, synthFB_fx, 0, hTcxDec->L_frameTCX ); +#endif } - +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + decoder_tcx_post_ivas_fx( st, synth_fx, synthFB_fx, st->Q_syn, Aq_fx, bfi, 0 ); +#else decoder_tcx_post_ivas_fx( st, synth_fx, synthFB_fx, 0, Aq_fx, bfi, 0 ); +#endif IF( EQ_16( st->core, TCX_20_CORE ) ) { diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 81951104e50e56c21b9ff1dd41da427e29760e3a..8a8d6b09398d2b46219b6a3f740db980b33a879b 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1310,7 +1310,11 @@ typedef struct Decoder_State Word16 Q_syn; Word16 Q_syn2; Word16 Q_syn_cng; +#ifdef FIX_1793_DEC_MC_TO_MONO_SCALING_ISSUE + Word16 Q_syn_factor; // This q_factor is used to avoid using fix Q0 for synth[] at the output of con_tcx_ivas_fx() and ivas_core_dec_fx(). For con_tcx_ivas_fx, it is used for two consecutive TCX concealment processes and It cannot be greater than 0. +#else Word16 Q_syn_factor; // This q_factor is used to avoid using fixed Q0 for synth[] at the output of con_tcx_ivas_fx(). It is then used for two consecutive TCX concealment processes. It cannot be greater than 0. +#endif Word16 prev_Q_syn; Word16 prev_Q_bwe_exc;