diff --git a/lib_com/options.h b/lib_com/options.h index 7b4934a4de3a0a6823d7dab7d07c2a711f9b575e..064ddf797303903c7c48b1ee5dab66c7dcf50c63 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -93,6 +93,8 @@ #define FIX_1996_MASKING_NOISE /* Dlb: Heavy precision loss in ola buffers causing discontinuity*/ #define FIX1998_APA_EXEC_SCALING /* FhG: fix scaling of apa_exec_ivas_fx(); avoid continuously worse scaling with previous data */ +#define FIX_1962_FORMAT_CONV_SPECTRAL_DIFF /* FhG: Improved precision of targetEnergy in ivas_ls_setup_conversion_process_mdct_fx() */ +#define FIX_2003_CON_TCX_OVERFLOW /* FhG: Use a dynamic scaling factor for the synth buffer at the output of con_tcx_ivas_fx() */ /* #################### Start BASOP porting switches ############################ */ #define NONBE_1244_FIX_SWB_BWE_MEMORY /* VA: issue 1244: fix to SWB BWE memory in case of switching from FB coding - pending a review by Huawei */ diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 091b5ee5d50ffe52b44d87150452e7a04b675441..2b112c00e752b8cfa234884ed4e9e4eec964bb9d 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -1007,7 +1007,11 @@ void con_tcx_ivas_fx( Word16 pre_emph_buf; Word16 hp_filt[L_FIR_FER2]; Word16 alpha; +#ifdef FIX_2003_CON_TCX_OVERFLOW + 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; @@ -1082,18 +1086,33 @@ void con_tcx_ivas_fx( /* set excitation memory*/ exc = buf + OLD_EXC_SIZE_DEC; - tmp_deemph = synth[-1]; /*Q0*/ +#ifdef FIX_2003_CON_TCX_OVERFLOW + tmp_deemph = synth[-1]; /*st->Q_syn_factor*/ move16(); - pre_emph_buf = synth[-1]; /*Q0*/ + pre_emph_buf = synth[-1]; /*st->Q_syn_factor*/ + move16(); +#else + tmp_deemph = synth[-1]; /*Q0*/ move16(); + pre_emph_buf = synth[-1]; /*Q0*/ +#endif test(); IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc ) { /* apply pre-emphasis to the signal */ +#ifdef FIX_2003_CON_TCX_OVERFLOW + mem = shl( synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )], st->Q_syn_factor ); +#else mem = synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )]; /*Q0*/ +#endif move16(); Q_exc = E_UTIL_f_preemph3_ivas_fx( &( 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_2003_CON_TCX_OVERFLOW + scale_sig( &( synth[-( ( ( L_frame / 2 ) + 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 ) ); @@ -1136,9 +1155,16 @@ void con_tcx_ivas_fx( ELSE { /* apply pre-emphasis to the signal */ - mem = synth[( -L_frame - 1 )]; /*Q0*/ +#ifdef FIX_2003_CON_TCX_OVERFLOW + mem = shl( synth[( -L_frame - 1 )], st->Q_syn_factor ); /*hTcxDec->Q_synth_factor_old*/ +#else + mem = synth[( -L_frame - 1 )]; /*Q0*/ +#endif move16(); Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-L_frame] ), st->preemph_fac, L_frame, &mem, 1 ); +#ifdef FIX_2003_CON_TCX_OVERFLOW + 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 ); /*Q14*/ offset = shr( L_frame, 1 ); @@ -1754,9 +1780,18 @@ void con_tcx_ivas_fx( syn = buf + M; /*Q_syn*/ Copy( synth - M, buf, M ); /*Q_syn*/ +#ifdef FIX_2003_CON_TCX_OVERFLOW + scf = norm_s( tmp_deemph ); + new_Q = sub( Q_exc, 4 ); // deemph_fx filter gain can be up to 10 (~2^3.32), so 4 bits of headroom are needed to avoid overflow +#else new_Q = sub( Q_exc, 3 ); +#endif new_Q = s_max( new_Q, -1 ); +#ifdef FIX_2003_CON_TCX_OVERFLOW + new_Q = s_min( new_Q, scf ); +#else new_Q = s_min( new_Q, norm_s( tmp_deemph ) ); +#endif tmp16 = s_min( new_Q, st->prev_Q_syn ); st->prev_Q_syn = new_Q; @@ -1767,8 +1802,15 @@ void con_tcx_ivas_fx( move16(); Copy_Scale_sig( buf, mem_syn, M, exp_scale ); /* Q: tmp16 */ - +#ifdef FIX_2003_CON_TCX_OVERFLOW + 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 ); +#endif st->Q_syn = Q_syn; move16(); @@ -1833,8 +1875,9 @@ void con_tcx_ivas_fx( /* Deemphasis and output synth and ZIR */ deemph_fx( syn, st->preemph_fac, add( L_frame, shr( L_frame, 1 ) ), &tmp_deemph ); +#ifndef FIX_2003_CON_TCX_OVERFLOW bufferCopyFx( syn + sub( L_frame, M + 1 ), st->syn, 1 + M, Q_syn, 0, 0, 0 ); /*Q_syn*/ - +#endif lerp( syn + sub( L_frame, shr( L_frame, 1 ) ), hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) ); hTcxDec->Q_old_syn_Overl = Q_syn; @@ -1857,6 +1900,24 @@ void con_tcx_ivas_fx( hHQ_core->Q_old_wtda = Q_syn; move16(); +#ifdef FIX_2003_CON_TCX_OVERFLOW + scf = add( getScaleFactor16( syn, L_frame ), Q_syn ); + IF( LT_16( scf, 0 ) ) // Only avoid left shift in bufferCopyFX when overflow could occur + { + st->Q_syn_factor = scf; + } + ELSE + { + st->Q_syn_factor = 0; + move16(); + } + bufferCopyFx( syn, synth, L_frame, Q_syn, st->Q_syn_factor, 0, 0 ); + + bufferCopyFx( syn + sub( L_frame, M + 1 ), st->syn, 1 + M, Q_syn, st->Q_syn_factor, 0, 0 ); + + Copy_Scale_sig( syn + L_frame, hTcxDec->syn_OverlFB, shr( L_frame, 1 ), sub( st->Q_syn_factor, Q_syn ) ); + hTcxDec->Q_syn_OverlFB = st->Q_syn_factor; +#else /* As long as there is no synth scaling factor introduced, which is given to the outside, there might occur overflows here */ BASOP_SATURATE_WARNING_OFF_EVS @@ -1866,6 +1927,7 @@ void con_tcx_ivas_fx( Copy_Scale_sig( syn + L_frame, hTcxDec->syn_OverlFB, shr( L_frame, 1 ), sub( 0, Q_syn ) ); /*Q0*/ hTcxDec->Q_syn_OverlFB = 0; move16(); +#endif /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */ IF( st->hWIDec != NULL ) diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 532ab471864dc4bfb959f1ecff028b722888d565..8e94b2c6aa8f7982510c3748631894c9a2aff54f 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1184,6 +1184,10 @@ void ivas_mdct_core_reconstruct_fx( set16_fx( synthFB_fx, 0, L_FRAME_PLUS + M ); IF( st->core != ACELP_CORE ) { +#ifdef FIX_2003_CON_TCX_OVERFLOW + st->Q_syn_factor = 0; + move16(); +#endif Word16 q_win0 = Q15; move16(); Word16 q_winFB0 = Q15; @@ -1305,10 +1309,6 @@ void ivas_mdct_core_reconstruct_fx( Copy( st->hTcxDec->old_synth, synth_buf_fx, st->hTcxDec->old_synth_len ); // Q = st->hTcxDec->q_old_synth Copy_Scale_sig( st->hTcxDec->old_synthFB_fx, synth_bufFB_fx, st->hTcxDec->old_synth_lenFB, sub( st->hTcxDec->q_old_synth, st->Q_syn ) ); // Q = st->hTcxDec->q_old_synth - // Temporary workaround: con_tcx_ivas_fx() should be analyzed for potential issues. - // Scale_sig( synth_bufFB_fx, st->hTcxDec->old_synth_lenFB, -2 ); - // Scale_sig( synth_bufFB_fx, st->hTcxDec->old_synth_lenFB, +2 ); - /////////////////////////////////////////////////////////////////////////////////// assert( EQ_16( st->bfi, 1 ) ); /* PLC: [TCX: TD PLC] */ IF( MCT_flag != 0 ) @@ -1423,7 +1423,11 @@ void ivas_mdct_core_reconstruct_fx( IF( signal_outFB_fx[ch] != NULL ) { Copy( synthFB_fx, signal_outFB_fx[ch], st->hTcxDec->L_frameTCX ); +#ifdef FIX_2003_CON_TCX_OVERFLOW + e_sig[ch] = sub( 15, q_syn + st->Q_syn_factor ); +#else e_sig[ch] = sub( 15, q_syn ); +#endif move16(); } diff --git a/lib_dec/ivas_out_setup_conversion_fx.c b/lib_dec/ivas_out_setup_conversion_fx.c index fde543e96e2c1b0289dd050e7735ea03521dc3dc..3842b0f6b608ec976a1187437f1c27b8e0603bcb 100644 --- a/lib_dec/ivas_out_setup_conversion_fx.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -662,8 +662,13 @@ void ivas_ls_setup_conversion_process_mdct_fx( Word16 inChannels, outChannels, num_CPE; Word16 transform_type[MAX_CICP_CHANNELS][2]; Word16 frameSize; +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + Word64 targetEnergy64[MAX_SFB + 2], dmxEnergy64[MAX_SFB + 2]; + Word16 scf1, scf2; +#else Word32 targetEnergy[MAX_SFB + 2], dmxEnergy[MAX_SFB + 2]; Word16 dmxEnergy_exp[MAX_SFB + 2], dmxEnergy_exp_temp; +#endif Word32 dmxCoeff; Word32 dmxSignalReal[L_FRAME48k], dmxSignalImag[L_FRAME48k]; Word32 eqGain; @@ -748,12 +753,20 @@ void ivas_ls_setup_conversion_process_mdct_fx( /* set overall frequency resolution of (sub)frame to maximum of (sub)frame, requires conversion if both channels are not the same */ frameSize = hLsSetUpConversion->sfbOffset[hLsSetUpConversion->sfbCnt]; move16(); - +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + set64_fx( targetEnergy64, 0, MAX_SFB + 2 ); + set64_fx( dmxEnergy64, 0, MAX_SFB + 2 ); + scf1 = 63; + scf2 = 63; + move16(); + move16(); +#else set32_fx( targetEnergy, 0, MAX_SFB + 2 ); set32_fx( dmxEnergy, 0, MAX_SFB + 2 ); set16_fx( dmxEnergy_exp, 0, MAX_SFB + 2 ); dmxEnergy_exp_temp = 0; move16(); +#endif FOR( chOutIdx = 0; chOutIdx < outChannels; chOutIdx++ ) { @@ -772,8 +785,12 @@ void ivas_ls_setup_conversion_process_mdct_fx( /* Step 1: Compute the target energy and DMX signal (possible since we have all signals in TCX20 resolution) */ IF( dmxCoeff ) { +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + Word64 targetEne64; + Word32 tmpDMXSig; +#else Word32 tmpDMXSig, targetEne; - +#endif /* Convert the signal resolution to TCX20 */ /* initially, set pointers to input; if conversion occurs in (sub)frame, set to convertRes */ pTmp[0] = x[chInIdx][0]; // Q(q_output) @@ -816,8 +833,13 @@ void ivas_ls_setup_conversion_process_mdct_fx( stop = hLsSetUpConversion->sfbOffset[bandIdx + 1]; move16(); +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + targetEne64 = 0; + move64(); +#else targetEne = 0; move32(); +#endif /* Loop over all the bins in the band */ FOR( binIdx = start; binIdx < stop; binIdx++ ) @@ -825,15 +847,30 @@ void ivas_ls_setup_conversion_process_mdct_fx( tmpDMXSig = Mpy_32_32( L_shl_sat( dmxCoeff, 1 ), sig[0][binIdx] ); dmxSignalReal[binIdx] = L_add( dmxSignalReal[binIdx], tmpDMXSig ); move32(); +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + targetEne64 = W_mac_32_32( targetEne64, tmpDMXSig, tmpDMXSig ); +#else targetEne = L_add( targetEne, Mpy_32_32( tmpDMXSig, tmpDMXSig ) ); - +#endif tmpDMXSig = Mpy_32_32( L_shl_sat( dmxCoeff, 1 ), mdst[binIdx] ); dmxSignalImag[binIdx] = L_add( dmxSignalImag[binIdx], tmpDMXSig ); move32(); +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + targetEne64 = W_mac_32_32( targetEne64, tmpDMXSig, tmpDMXSig ); +#else targetEne = L_add( targetEne, Mpy_32_32( tmpDMXSig, tmpDMXSig ) ); +#endif + } +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + targetEnergy64[bandIdx] = W_add( targetEnergy64[bandIdx], W_shr( targetEne64, 1 ) ); + if ( NE_64( targetEnergy64[bandIdx], 0 ) ) + { + scf1 = s_min( scf1, W_norm( targetEnergy64[bandIdx] ) ); } +#else targetEnergy[bandIdx] = L_add( targetEnergy[bandIdx], targetEne ); move32(); +#endif } /* end of band loop */ } } @@ -841,52 +878,101 @@ void ivas_ls_setup_conversion_process_mdct_fx( FOR( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) { +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + Word32 tmpReal, tmpImag; + Word64 DMXEne64; +#else Word32 tmpReal, tmpImag, DMXEne; Word16 DMXEne_exp; - +#endif start = hLsSetUpConversion->sfbOffset[bandIdx]; move16(); stop = hLsSetUpConversion->sfbOffset[bandIdx + 1]; move16(); /* Loop over all the bins in the band */ +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + DMXEne64 = 0; + move64(); +#else DMXEne = 0; move32(); DMXEne_exp = 0; move16(); +#endif + FOR( binIdx = start; binIdx < stop; binIdx++ ) { tmpReal = dmxSignalReal[binIdx]; move32(); tmpImag = dmxSignalImag[binIdx]; move32(); - +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + DMXEne64 = W_mac_32_32( DMXEne64, tmpReal, tmpReal ); + DMXEne64 = W_mac_32_32( DMXEne64, tmpImag, tmpImag ); +#else DMXEne = BASOP_Util_Add_Mant32Exp( DMXEne, DMXEne_exp, L_add( Mpy_32_32( tmpReal, tmpReal ), Mpy_32_32( tmpImag, tmpImag ) ), sub( 40, shl( q_output, 1 ) ), &DMXEne_exp ); +#endif + } +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + dmxEnergy64[bandIdx] = W_add( dmxEnergy64[bandIdx], W_shr( DMXEne64, 1 ) ); + if ( NE_64( dmxEnergy64[bandIdx], 0 ) ) + { + scf2 = s_min( scf2, W_norm( dmxEnergy64[bandIdx] ) ); } +#else dmxEnergy[bandIdx] = BASOP_Util_Add_Mant32Exp( dmxEnergy[bandIdx], dmxEnergy_exp[bandIdx], DMXEne, DMXEne_exp, &dmxEnergy_exp[bandIdx] ); move32(); dmxEnergy_exp_temp = s_max( dmxEnergy_exp_temp, dmxEnergy_exp[bandIdx] ); +#endif } } /* end of out channel loop */ - +#ifndef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF /* Scaling to common exponent */ FOR( bandIdx = 0; bandIdx < MAX_SFB + 2; bandIdx++ ) { dmxEnergy[bandIdx] = L_shl( dmxEnergy[bandIdx], sub( dmxEnergy_exp[bandIdx], dmxEnergy_exp_temp ) ); move32(); } +#endif /* Step 3: Peform energy smoothing */ - Word16 te_scale = getScaleFactor32( hLsSetUpConversion->targetEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt ); scale_sig32( hLsSetUpConversion->targetEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt, te_scale ); + +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + Word16 dmx_scale = getScaleFactor32( hLsSetUpConversion->dmxEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt ); + scale_sig32( hLsSetUpConversion->dmxEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt, dmx_scale ); + + Word16 targetEnergy_e = sub( add( sub( 40, shl( q_output, 1 ) ), 1 ), scf1 ); + Word16 te_max_e = s_max( targetEnergy_e, sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ); + + Word16 dmxEnergy_e = sub( add( sub( 40, shl( q_output, 1 ) ), 1 ), scf2 ); + Word16 dmx_max_e = s_max( dmxEnergy_e, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_scale ) ); +#else Word16 dmx_sacle = getScaleFactor32( hLsSetUpConversion->dmxEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt ); scale_sig32( hLsSetUpConversion->dmxEnergyPrev_fx[0], hLsSetUpConversion->sfbCnt, dmx_sacle ); Word16 te_max_e = s_max( sub( 40, shl( q_output, 1 ) ), sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ); Word16 dmx_max_e = s_max( dmxEnergy_exp_temp, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ); +#endif FOR( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) { +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + Word32 targetEnergy, dmxEnergy; + + targetEnergy = W_extract_h( W_shl( targetEnergy64[bandIdx], scf1 ) ); + targetEnergy = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( targetEnergy, sub( te_max_e, targetEnergy_e ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx], sub( te_max_e, sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ) ) ) ); + move32(); + hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx] = targetEnergy; + move32(); + + dmxEnergy = W_extract_h( W_shl( dmxEnergy64[bandIdx], scf2 ) ); + dmxEnergy = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( dmxEnergy, sub( dmx_max_e, dmxEnergy_e ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], sub( dmx_max_e, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_scale ) ) ) ) ); + move32(); + hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx] = dmxEnergy; + move32(); +#else targetEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( targetEnergy[bandIdx], sub( te_max_e, sub( 40, shl( q_output, 1 ) ) ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx], sub( te_max_e, sub( hLsSetUpConversion->te_prev_exp[0], te_scale ) ) ) ) ); move32(); dmxEnergy[bandIdx] = L_add( Mpy_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, L_shr( dmxEnergy[bandIdx], sub( dmx_max_e, dmxEnergy_exp_temp ) ) ), Mpy_32_32( ( ONE_IN_Q31 - LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], sub( dmx_max_e, sub( hLsSetUpConversion->dmx_prev_exp[0], dmx_sacle ) ) ) ) ); @@ -895,6 +981,7 @@ void ivas_ls_setup_conversion_process_mdct_fx( move32(); hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx] = dmxEnergy[bandIdx]; /* dmx_prev_exp = 40 - 2*q_output */ move32(); +#endif } hLsSetUpConversion->te_prev_exp[0] = te_max_e; /* te_prev_exp = 40 - 2*q_output */ @@ -928,7 +1015,13 @@ void ivas_ls_setup_conversion_process_mdct_fx( move16(); /* Compute Eq gains */ +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + ivas_lssetupconversion_computeEQFactor_fx( &hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx], hLsSetUpConversion->te_prev_exp[0], + &hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], hLsSetUpConversion->dmx_prev_exp[0], + &eqGain ); // Q(eqGain) = 30 +#else ivas_lssetupconversion_computeEQFactor_fx( &targetEnergy[bandIdx], hLsSetUpConversion->te_prev_exp[0], &dmxEnergy[bandIdx], hLsSetUpConversion->dmx_prev_exp[0], &eqGain ); // Q(eqGain) = 30 +#endif FOR( binIdx = start; binIdx < stop; binIdx++ ) { x[chInIdx][0][binIdx] = Mpy_32_32( L_shl( x[chInIdx][0][binIdx], 1 ), eqGain ); // Q - 1 @@ -948,8 +1041,13 @@ void ivas_ls_setup_conversion_process_mdct_fx( move16(); /* Compute Eq gains */ +#ifdef FIX_1962_FORMAT_CONV_SPECTRAL_DIFF + ivas_lssetupconversion_computeEQFactor_fx( &hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx], hLsSetUpConversion->te_prev_exp[0], + &hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], hLsSetUpConversion->dmx_prev_exp[0], + &eqGain ); +#else ivas_lssetupconversion_computeEQFactor_fx( &targetEnergy[bandIdx], hLsSetUpConversion->te_prev_exp[0], &dmxEnergy[bandIdx], hLsSetUpConversion->dmx_prev_exp[0], &eqGain ); - +#endif FOR( subFrameIdx = 0; subFrameIdx < NB_DIV; subFrameIdx++ ) { IF( EQ_16( transform_type[chInIdx][subFrameIdx], TCX_10 ) ) diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 0c5f7db856a0aa4c08b357ef7f76a5997f97811a..a1e9af4289e4a1ffd656cb8e22540421ec65da85 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1310,6 +1310,9 @@ typedef struct Decoder_State Word16 Q_syn; Word16 Q_syn2; Word16 Q_syn_cng; +#ifdef FIX_2003_CON_TCX_OVERFLOW + 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;