diff --git a/lib_com/options.h b/lib_com/options.h index 0feca9ea2db460ac7b1da407e9eeddff353972a1..4394a02bea2828bc7d909527ee8a673ab2fdaebe 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -91,7 +91,7 @@ #define HARM_2456_APPLY_SCALE /* FhG basop issue 2456: Harmonize apply_scale_ind(), apply_scale_ivas_fx() */ #define HARM_2454_TCX_RES_Q_SPEC /* FhG: harmonization of tcx_res_Q_spec_fx() and tcx_res_Q_spec_ivas_fx() */ #define FIX_FLOAT_1535_ARI_RES_Q_CLEANUP /* FhG: remove dead code from tcx_ari_res_Q_spec() */ - +#define HARMONIZE_2446_CON_TCX_FX /* #################### End BE switches ################################## */ /* #################### Start NON-BE switches ############################ */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index f32d05534d06517f2b9e81dca1a40013fb058929..2ad859bf95ba75a0d288e47b473c00c62ff4acf8 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -8409,10 +8409,12 @@ void modify_lsf( const Word16 reset_q /* Q0 */ ); +#ifndef HARMONIZE_2446_CON_TCX_FX void con_tcx_fx( Decoder_State *st, /* i/o: coder memory state */ Word16 synth[] /* i/o: synth[] Q0 */ ); +#endif // !HARMONIZE_2446_CON_TCX_FX /* o : damping factor Q14*/ Word16 Damping_fact_fx( @@ -8927,6 +8929,7 @@ void decoder_tcx_post_ivas_fx( Word16 bfi, Word16 MCT_flag ); +#ifndef HARMONIZE_2446_CON_TCX_FX void con_tcx_ivas_fx( Decoder_State *st, /* i/o: coder memory state */ Word16 synth[], /* i/o: synth[] Q0 */ @@ -8935,6 +8938,16 @@ void con_tcx_ivas_fx( const Word16 only_left, /* i : TD-PLC only in left channel */ const Word16 *A_cng /* i : CNG LP filter coefficients */ ); +#else +void con_tcx_ivas_fx( + Decoder_State *st, /* i/o: coder memory state */ + Word16 synth[], /* i/o: synth[] Q0 */ + const Word16 coh, /* i : coherence of stereo signal */ + Word16 *noise_seed, /* i/o: noise seed for stereo */ + const Word16 only_left, /* i : TD-PLC only in left channel */ + const Word16 *A_cng, /* i : CNG LP filter coefficients */ + const Word16 leg_flag ); +#endif // !HARMONIZE_2446_CON_TCX_FX void ivas_mdct_core_reconstruct_fx( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index 4cafdfed749b2120f56ac0721731e29b78be8eec..00102e2977d57bb41cbcb4538fdc69c1f2d77cae 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -570,7 +570,11 @@ void decoder_LPD_fx( IF( bfi != 0 && ( st->last_core != ACELP_CORE ) ) { /* PLC: [TCX: TD PLC] */ +#ifndef HARMONIZE_2446_CON_TCX_FX con_tcx_fx( st, &synthFB[0] ); +#else + con_tcx_ivas_fx( st, &synthFB[0], -16384, NULL, 0, NULL, (Word16) 1 ); +#endif lerp( synthFB, synth, st->L_frame, hTcxDec->L_frameTCX ); st->con_tcx = 1; move16(); diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 9c73fcdf621c51f911ec6caad69db369dac2e119..1002f10a4f1e4f1f3e9179aaca00d6f3ddcb3075 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -87,6 +87,7 @@ con_tcx \brief main function in time domain TCX concealment *******************************************************/ +#ifndef HARMONIZE_2446_CON_TCX_FX void con_tcx_fx( Decoder_State *st, /* i/o: coder memory state */ @@ -945,6 +946,18 @@ void con_tcx_fx( return; } +#endif // !HARMONIZE_2446_CON_TCX_FX + +#ifdef HARMONIZE_2446_CON_TCX_FX +void con_tcx_ivas_fx( + Decoder_State *st, /* i/o: coder memory state */ + Word16 synth[], /* i/o: synth[] Q0 */ + const Word16 coh, /* i : coherence of stereo signal Q14*/ + Word16 *noise_seed, /* i/o: noise seed for stereo Q0 */ + const Word16 only_left, /* i : TD-PLC only in left channel Q0 */ + const Word16 *A_cng, /* i : CNG LP filter coefficients Q14*/ + const Word16 leg_flag ) +#else void con_tcx_ivas_fx( Decoder_State *st, /* i/o: coder memory state */ Word16 synth[], /* i/o: synth[] Q0 */ @@ -953,6 +966,8 @@ void con_tcx_ivas_fx( const Word16 only_left, /* i : TD-PLC only in left channel Q0 */ const Word16 *A_cng /* i : CNG LP filter coefficients Q14*/ ) +#endif // HARMONIZE_2446_CON_TCX_FX + { Word16 i, s, c, L_frame, L_subfr, fLowPassFilter, T0; Word16 n, mem_syn_r_size_old, mem_syn_r_size_new; @@ -1046,15 +1061,46 @@ void con_tcx_ivas_fx( IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc ) { /* apply pre-emphasis to the signal */ +#ifndef HARMONIZE_2446_CON_TCX_FX mem = shl( synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )], st->Q_syn_factor ); +#else + mem = shl_sat( synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )], st->Q_syn_factor ); +#endif // !HARMONIZE_2446_CON_TCX_FX move16(); +#ifndef HARMONIZE_2446_CON_TCX_FX 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 ); - 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 */ +#else + IF( !leg_flag ) + { + 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_sat( M, 1 ) ), &mem, 1 ); + } + ELSE + { + 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_sat( M, 1 ) ), &mem, 1 ); + } +#endif // !HARMONIZE_2446_CON_TCX_FX + +#ifndef HARMONIZE_2446_CON_TCX_FX + scale_sig( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl_sat( M, 1 ) ), negate( st->Q_syn_factor ) ); /*Q0, Setting back to Q0, as the following calculations are implemented assuming synth is in Q0 */ +#else + IF( !leg_flag ) + { + scale_sig( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl_sat( M, 1 ) ), negate( st->Q_syn_factor ) ); /*Q0, Setting back to Q0, as the following calculations are implemented assuming synth is in Q0 */ + } + ELSE + { + Scale_sig( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl_sat( M, 1 ) ), negate( st->Q_syn_factor ) ); /*Q0, Setting back to Q0, as the following calculations are implemented assuming synth is in Q0 */ + } +#endif // !HARMONIZE_2446_CON_TCX_FX 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 ) ); +#ifndef HARMONIZE_2446_CON_TCX_FX + st->Mode2_lp_gainp = get_gain2(synth - shl(L_subfr, 1), synth - add(shl(L_subfr, 1), Tc), shl(L_subfr, 1)); +#else + st->Mode2_lp_gainp = get_gain2(synth - shl_sat(L_subfr, 1), synth - add(shl_sat(L_subfr, 1), Tc), shl_sat(L_subfr, 1)); +#endif // !HARMONIZE_2446_CON_TCX_FX + move32(); st->Mode2_lp_gainp = L_max( st->Mode2_lp_gainp, 0 ); /*Q16*/ @@ -1074,8 +1120,21 @@ void con_tcx_ivas_fx( lag_wind( r_h, r_l, M, st->output_Fs, LAGW_STRONG ); /* Levinson Durbin */ +#ifndef HARMONIZE_2446_CON_TCX_FX E_LPC_lev_dur_ivas_fx( r_h, r_l, A_local, NULL, M, NULL ); +#else + IF( !leg_flag ) + { + E_LPC_lev_dur_ivas_fx( r_h, r_l, A_local, NULL, M, NULL ); + } + ELSE + { + E_LPC_lev_dur_fx( r_h, r_l, A_local, NULL, M, NULL ); + } +#endif // !HARMONIZE_2446_CON_TCX_FX + + /* copy for multiple frame loss */ Copy( A_local, st->old_Aq_12_8_fx, M + 1 ); /*Q14*/ @@ -1083,32 +1142,64 @@ void con_tcx_ivas_fx( assert( ( 2 * L_subfr + Tc + 1 + M ) <= hTcxDec->old_synth_lenFB ); BASOP_SATURATE_WARNING_OFF_EVS /*saturation possible in case of spiky synthesis*/ +#ifndef HARMONIZE_2446_CON_TCX_FX Residu3_fx( A_local, &( synth[-add( add( add( shl( L_subfr, 1 ), Tc ), 1 ), M )] ), /*Qx = Q0*/ &( exc[-add( add( add( shl( L_subfr, 1 ), Tc ), 1 ), M )] ), /*Qx+1 = Q1*/ add( add( add( shl( L_subfr, 1 ), Tc ), 1 ), M ), 1 ); +#else + Residu3_fx( + A_local, + &( synth[-add( add( add( shl_sat( L_subfr, 1 ), Tc ), 1 ), M )] ), /*Qx = Q0*/ + &( exc[-add( add( add( shl_sat( L_subfr, 1 ), Tc ), 1 ), M )] ), /*Qx+1 = Q1*/ + add( add( add( shl_sat( L_subfr, 1 ), Tc ), 1 ), M ), + 1 ); +#endif // !HARMONIZE_2446_CON_TCX_FX BASOP_SATURATE_WARNING_ON_EVS } ELSE { /* apply pre-emphasis to the signal */ - mem = shl( synth[( -L_frame - 1 )], st->Q_syn_factor ); /*hTcxDec->Q_synth_factor_old*/ + mem = shl_sat( synth[( -L_frame - 1 )], st->Q_syn_factor ); /*hTcxDec->Q_synth_factor_old*/ move16(); +#ifndef HARMONIZE_2446_CON_TCX_FX Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-L_frame] ), st->preemph_fac, L_frame, &mem, 1 ); 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 */ - Copy( st->old_Aq_12_8_fx, A_local, M + 1 ); /*Q14*/ + +#else + IF( !leg_flag ) + { + Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-L_frame] ), st->preemph_fac, L_frame, &mem, 1 ); + 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 */ + } + ELSE + { + Q_exc = E_UTIL_f_preemph3( &( synth[-L_frame] ), st->preemph_fac, L_frame, &mem, 1 ); + 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 // !HARMONIZE_2446_CON_TCX_FX + Copy( st->old_Aq_12_8_fx, A_local, M + 1 ); /*Q14*/ offset = shr( L_frame, 1 ); IF( GE_16( st->last_good, UNVOICED_TRANSITION ) ) { +#ifndef HARMONIZE_2446_CON_TCX_FX tmp16 = s_max( Tc - shr( L_frame, 1 ), 0 ); +#else + tmp16 = s_max( sub( Tc, shr( L_frame, 1 ) ), 0 ); +#endif // !HARMONIZE_2446_CON_TCX_FX + Copy_Scale_sig( hTcxDec->old_excFB_fx, &( exc[-tmp16] ), add( offset, tmp16 ), sub( Q_exc, st->Q_exc ) ); /*Q_exc*/ } ELSE { +#ifndef HARMONIZE_2446_CON_TCX_FX Copy_Scale_sig( hTcxDec->old_excFB_fx, &( exc[-( L_subfr * 2 )] ), add( shl( L_subfr, 1 ), offset ), sub( Q_exc, st->Q_exc ) ); /*Q_exc*/ +#else + Copy_Scale_sig( hTcxDec->old_excFB_fx, &( exc[-( L_subfr * 2 )] ), add( shl_sat( L_subfr, 1 ), offset ), sub( Q_exc, st->Q_exc ) ); /*Q_exc*/ +#endif // !HARMONIZE_2446_CON_TCX_FX } } @@ -1146,8 +1237,12 @@ void con_tcx_ivas_fx( tcxltp_pitch_tmp = L_add( L_deposit_h( hTcxLtpDec->tcxltp_pitch_int ), L_shl( L_deposit_l( div_s( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max ) ), 1 ) ); /*15Q16*/ scale_tmp = mult_r( hTcxDec->L_frameTCX, getInvFrameLen( st->L_frame ) ); /*getInvFrameLen()->9Q6*/ tmp_shift = norm_s( scale_tmp ); - +#ifndef HARMONIZE_2446_CON_TCX_FX predPitchLag = L_shl( Mpy_32_16_1( tcxltp_pitch_tmp, shl( scale_tmp, tmp_shift ) ), sub( 9, tmp_shift ) ); /*Q16*/ +#else + predPitchLag = L_shl( Mpy_32_16_1( tcxltp_pitch_tmp, shl_sat( scale_tmp, tmp_shift ) ), sub( 9, tmp_shift ) ); /*Q16*/ +#endif // !HARMONIZE_2446_CON_TCX_FX + T0 = round_fx( predPitchLag ); /*Q0*/ @@ -1206,6 +1301,7 @@ void con_tcx_ivas_fx( { FOR( i = 0; i < Tc; i++ ) { +#ifndef HARMONIZE_2446_CON_TCX_FX *pt_exc++ = mac_r( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mult( 174 /* 0.0053f Q15*/, pt1_exc[-5] ), 0 /* 0.0000f Q15*/, pt1_exc[-4] ), @@ -1218,6 +1314,22 @@ void con_tcx_ivas_fx( -1442 /*-0.0440f Q15*/, pt1_exc[3] ), 0 /* 0.0000f Q15*/, pt1_exc[4] ), 174 /* 0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/ +#else + *pt_exc++ = mac_r_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( + L_mult( 174 /* 0.0053f Q15*/, pt1_exc[-5] ), + 0 /* 0.0000f Q15*/, pt1_exc[-4] ), + -1442 /*-0.0440f Q15*/, pt1_exc[-3] ), + 0 /* 0.0000f Q15*/, pt1_exc[-2] ), + 8641 /* 0.2637f Q15*/, pt1_exc[-1] ), + 18022 /* 0.5500f Q15*/, pt1_exc[0] ), + 8641 /* 0.2637f Q15*/, pt1_exc[1] ), + 0 /* 0.0000f Q15*/, pt1_exc[2] ), + -1442 /*-0.0440f Q15*/, pt1_exc[3] ), + 0 /* 0.0000f Q15*/, pt1_exc[4] ), + 174 /* 0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/ + + +#endif // !HARMONIZE_2446_CON_TCX_FX move16(); pt1_exc++; } @@ -1226,6 +1338,7 @@ void con_tcx_ivas_fx( { FOR( i = 0; i < Tc; i++ ) { +#ifndef HARMONIZE_2446_CON_TCX_FX *pt_exc++ = mac_r( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mult( -174 /*-0.0053f Q15*/, pt1_exc[-5] ), -121 /*-0.0037f Q15*/, pt1_exc[-4] ), @@ -1238,6 +1351,22 @@ void con_tcx_ivas_fx( -459 /*-0.0140f Q15*/, pt1_exc[3] ), -121 /*-0.0037f Q15*/, pt1_exc[4] ), -174 /*-0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/ +#else + *pt_exc++ = mac_r_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( + L_mult( -174 /*-0.0053f Q15*/, pt1_exc[-5] ), + -121 /*-0.0037f Q15*/, pt1_exc[-4] ), + -459 /*-0.0140f Q15*/, pt1_exc[-3] ), + 590 /* 0.0180f Q15*/, pt1_exc[-2] ), + 8743 /* 0.2668f Q15*/, pt1_exc[-1] ), + 16355 /* 0.4991f Q15*/, pt1_exc[0] ), + 8743 /* 0.2668f Q15*/, pt1_exc[1] ), + 590 /* 0.0180f Q15*/, pt1_exc[2] ), + -459 /*-0.0140f Q15*/, pt1_exc[3] ), + -121 /*-0.0037f Q15*/, pt1_exc[4] ), + -174 /*-0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/ + + +#endif // !HARMONIZE_2446_CON_TCX_FX move16(); pt1_exc++; } @@ -1345,11 +1474,19 @@ void con_tcx_ivas_fx( /*step = (1.0f/(L_frame+(L_frame/2))) * (gain - alpha);*/ tmp16 = shr( imult1616( 3, L_frame ), 1 ); tmp_e = norm_s( tmp16 ); +#ifndef HARMONIZE_2446_CON_TCX_FX tmp16 = shl( tmp16, tmp_e ); +#else + tmp16 = shl_sat( tmp16, tmp_e ); +#endif // !HARMONIZE_2446_CON_TCX_FX + tmp16 = div_s( 16384 /*1.f Q14*/, tmp16 ); /*Q15,1+tmp_e-15*/ tmp16_2 = sub( shr( gain, 1 ), alpha ) /*Q14*/; +#ifndef HARMONIZE_2446_CON_TCX_FX step32 = L_shl( L_mult( tmp16, tmp16_2 ) /*Q30, 1+tmp_e-15*/, add( 1 - 14, tmp_e ) ) /*Q31*/; - +#else + step32 = L_shl_sat( L_mult( tmp16, tmp16_2 ) /*Q30, 1+tmp_e-15*/, add( 1 - 14, tmp_e ) ) /*Q31*/; +#endif // HARMONIZE_2446_CON_TCX_FX /* PLC: Apply fade out */ tmp_loop = shr( imult1616( L_frame, 3 ), 1 ); FOR( i = offset; i < tmp_loop; i++ ) @@ -1391,8 +1528,11 @@ void con_tcx_ivas_fx( /*-----------------------------------------------------------------* * Construct the random part of excitation *-----------------------------------------------------------------*/ - +#ifndef HARMONIZE_2446_CON_TCX_FX IF( NE_16( coh, -16384 ) ) +#else + IF( NE_16( coh, -16384 ) && !leg_flag ) +#endif // !HARMONIZE_2446_CON_TCX_FX { Word16 tmpSeed1; Word16 alpha_coh; @@ -1457,8 +1597,12 @@ void con_tcx_ivas_fx( } st->seed_acelp = tmpSeed; move16(); - - tmp_loop = add( add( L_frame, shr( L_frame, 1 ) ), shl( L_FIR_FER2, 1 ) ); +#ifndef HARMONIZE_2446_CON_TCX_FX + tmp_loop = add(add(L_frame, shr(L_frame, 1)), shl((L_FIR_FER2, 1)); +#else + tmp_loop = add( add( L_frame, shr( L_frame, 1 ) ), shl_sat( L_FIR_FER2, 1 ) ); +#endif // !HARMONIZE_2446_CON_TCX_FX + FOR( ; i < tmp_loop; i++ ) { Random( &tmpSeed ); @@ -1515,7 +1659,11 @@ void con_tcx_ivas_fx( move32(); FOR( j = 11; j > 0; j-- ) { +#ifndef HARMONIZE_2446_CON_TCX_FX L_tmp2 = L_mac( L_tmp2, noise[( i + ( L_FIR_FER2 - j ) )], hp_filt[sub( L_FIR_FER2, j )] ); +#else + L_tmp2 = L_mac( L_tmp2, noise[add( i, ( sub( L_FIR_FER2, j ) ) )], hp_filt[sub( L_FIR_FER2, j )] ); +#endif // !HARMONIZE_2446_CON_TCX_FX } L_tmp2 = Mpy_32_16_1( L_tmp2, st->cummulative_damping /*Q15*/ ); /*Q0, noise_e*/ noise[i] = mac_r( L_tmp2, gain_tmp, noise[i] ); /*Q15, noise_e*/ @@ -1572,7 +1720,11 @@ void con_tcx_ivas_fx( { gain32 = Mpy_32_16_1( gain32, 22938 /*0.7f Q15*/ ); /*Q16*/ } +#ifndef HARMONIZE_2446_CON_TCX_FX L_tmp = L_shl( gain32, 1 ); /*Q16*/ +#else + L_tmp = L_shl_sat( gain32, 1 ); /*Q16*/ +#endif // !HARMONIZE_2446_CON_TCX_FX IF( GT_32( L_shl( L_deposit_h( gainCNG ), sub( gainCNG_e, 31 - 16 ) /*Q16*/ ), L_tmp ) ) { @@ -1598,12 +1750,25 @@ void con_tcx_ivas_fx( step32 = Mpy_32_16_1( L_tmp /*Q16,-tmp_e*/, getInvFrameLen( L_frame ) /*W16Q21*/ ); /*Q22,-tmp_e*/ step32 = L_shl( step32, sub( 25 - 22, tmp_e ) ); /*Q25*/ +#ifndef HARMONIZE_2446_CON_TCX_FX pt_exc = noise + shr( L_FIR_FER2, 1 ); +#else + pt_exc = noise + L_FIR_FER2 / 2; +#endif // !HARMONIZE_2446_CON_TCX_FX /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f );*/ /* normalize energy */ L_tmp = Dot_productSq16HQ( 0, pt_exc /*Q0,15+1*/, L_frame, &tmp_e ) /*Q31,tmp_e+16+16*/; +#ifndef HARMONIZE_2446_CON_TCX_FX tmp_e = sub( add( tmp_e, shl( noise_e, 1 ) ), 1 ); // actual multiplier! +#else + IF( !leg_flag ) + { + tmp_e = sub( add( tmp_e, shl_sat( noise_e, 1 ) ), 1 ); // actual multiplier! + } +#endif // !HARMONIZE_2446_CON_TCX_FX + L_tmp = Mpy_32_16_1( L_tmp, getInvFrameLen( L_frame ) /*W16Q21*/ ) /*W32Q37,tmp_e+16+16*/ /*Q5,tmp_e*/; +#ifndef HARMONIZE_2446_CON_TCX_FX tmp_e = add( tmp_e, 31 - 6 ); /*-->Q31*/ gain_inov = 0; move16(); @@ -1615,6 +1780,32 @@ void con_tcx_ivas_fx( gain_inov_e = tmp_e; move16(); } +#else + IF( !leg_flag ) + { + tmp_e = add( tmp_e, 31 - 6 ); /*-->Q31*/ + gain_inov = 0; + move16(); + gain_inov_e = 0; + move16(); + IF( NE_32( L_tmp, 0 ) ) + { + gain_inov = round_fx( ISqrt32( L_tmp, &tmp_e ) ); /*Q15,tmp_e*/ + gain_inov_e = tmp_e; + move16(); + } + } + ELSE + { + tmp_e = add( tmp_e, 31 - 5 ); /*-->Q31*/ + gain_inov = round_fx( ISqrt32( L_tmp, &tmp_e ) ); /*Q15,tmp_e*/ + gain_inov_e = tmp_e; + move16(); + } + +#endif // !HARMONIZE_2446_CON_TCX_FX + + test(); test(); IF( EQ_16( st->last_good, UNVOICED_CLAS ) && NE_16( st->core_ext_mode, UNVOICED ) ) @@ -1685,7 +1876,12 @@ void con_tcx_ivas_fx( ELSE { bufferCopyFx( noise + L_FIR_FER2 / 2, exc, add( L_frame, shr( L_frame, 1 ) ), 0 /*Q_noise*/, noise_e, Q_exc, 0 /*exc_e*/ ); +#ifndef HARMONIZE_2446_CON_TCX_FX Copy( exc + sub( L_frame, shl( L_subfr, 1 ) ), hTcxDec->old_excFB_fx, add( shl( L_subfr, 1 ), shr( L_frame, 1 ) ) ); /*Q_exc*/ +#else + Copy( exc + sub( L_frame, shl_sat( L_subfr, 1 ) ), hTcxDec->old_excFB_fx, add( shl_sat( L_subfr, 1 ), shr( L_frame, 1 ) ) ); /*Q_exc*/ +#endif // !HARMONIZE_2446_CON_TCX_FX + /* copy old_exc as 16kHz for acelp decoding */ IF( EQ_16( st->nbLostCmpt, 1 ) ) { @@ -1712,11 +1908,29 @@ void con_tcx_ivas_fx( syn = buf + M; /*Q_syn*/ Copy( synth - M, buf, M ); /*Q_syn*/ - +#ifndef HARMONIZE_2446_CON_TCX_FX 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 new_Q = s_max( new_Q, -1 ); new_Q = s_min( new_Q, scf ); +#else + IF( !leg_flag || NE_32( st->element_mode, EVS_MONO ) ) + { + 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 + 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(); + } +#endif // !HARMONIZE_2446_CON_TCX_FX + tmp16 = s_min( new_Q, st->prev_Q_syn ); st->prev_Q_syn = new_Q; @@ -1727,17 +1941,57 @@ void con_tcx_ivas_fx( move16(); Copy_Scale_sig( buf, mem_syn, M, exp_scale ); /* Q: tmp16 */ +#ifndef HARMONIZE_2446_CON_TCX_FX + 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 ) ); + st->Q_syn = Q_syn; move16(); +#else + IF( !leg_flag ) + { + + 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_sat( tmp_deemph, sub( Q_syn, st->Q_syn_factor ) ); + + st->Q_syn = Q_syn; + move16(); + } + ELSE + { + 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_sat( 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(); + st->Q_syn = Q_syn; + move16(); + } +#endif // !HARMONIZE_2446_CON_TCX_FX /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1: exc*/ /*buf[0;M] Q0: mem_syn*/ +#ifndef HARMONIZE_2446_CON_TCX_FX IF( A_cng != NULL ) +#else + IF( ( A_cng != NULL ) && !leg_flag ) +#endif // !HARMONIZE_2446_CON_TCX_FX { Word16 alpha_delayed; @@ -1797,6 +2051,13 @@ 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 ); +#ifdef HARMONIZE_2446_CON_TCX_FX + IF( leg_flag ) + { + bufferCopyFx( syn + sub( L_frame, M + 1 ), st->syn, 1 + M, Q_syn, 0, 0, 0 ); /*Q_syn*/ + } +#endif // HARMONIZE_2446_CON_TCX_FX + 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; move16(); @@ -1818,6 +2079,7 @@ void con_tcx_ivas_fx( hHQ_core->Q_old_wtda = Q_syn; move16(); +#ifndef HARMONIZE_2446_CON_TCX_FX scf = add( getScaleFactor16( syn, L_frame ), Q_syn ); IF( LT_16( scf, 0 ) ) // Only avoid left shift in bufferCopyFX when overflow could occur { @@ -1834,6 +2096,39 @@ void con_tcx_ivas_fx( 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 + IF( !leg_flag ) + { + 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 + bufferCopyFx( syn, synth, L_frame, Q_syn, 0, 0, 0 ); /*Q_syn*/ + BASOP_SATURATE_WARNING_ON_EVS + + 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 // !HARMONIZE_2446_CON_TCX_FX /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */ IF( st->hWIDec != NULL ) @@ -1848,8 +2143,24 @@ void con_tcx_ivas_fx( move16(); /* create aliasing and windowing need for transition to TCX10/5 */ +#ifndef HARMONIZE_2446_CON_TCX_FX Copy( syn + L_frame, hTcxDec->syn_Overl_TDACFB, shr( L_frame, 1 ) ); hTcxDec->Q_syn_Overl_TDACFB = Q_syn; + +#else + IF( !leg_flag ) + { + Copy( syn + L_frame, hTcxDec->syn_Overl_TDACFB, shr( L_frame, 1 ) ); + hTcxDec->Q_syn_Overl_TDACFB = Q_syn; + } + ELSE + { + bufferCopyFx( syn + L_frame, hTcxDec->syn_Overl_TDACFB, shr( L_frame, 1 ), Q_syn, 0, -1, 0 ); + hTcxDec->Q_syn_Overl_TDACFB = add( st->Q_syn, sub( st->Q_syn, -1 ) ); + } +#endif // HARMONIZE_2446_CON_TCX_FX + + move16(); FOR( i = 0; i < W12; i++ ) @@ -1894,7 +2205,20 @@ void con_tcx_ivas_fx( move16(); /* update memory for low band */ +#ifndef HARMONIZE_2446_CON_TCX_FX st->Q_syn = Q_syn; +#else + IF( !leg_flag ) + { + st->Q_syn = Q_syn; + } + ELSE + { + Scale_sig( hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), sub( -1, Q_syn ) ); /*Q_syn*/ + hTcxDec->Q_old_syn_Overl = -1; + } +#endif // !HARMONIZE_2446_CON_TCX_FX + move16(); lerp( hTcxDec->syn_OverlFB, hTcxDec->syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) ); hTcxDec->Q_syn_Overl = hTcxDec->Q_syn_OverlFB; @@ -1903,7 +2227,15 @@ void con_tcx_ivas_fx( hTcxDec->Q_syn_Overl_TDAC = hTcxDec->Q_syn_Overl_TDACFB; move16(); lerp( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_LB_fx, st->L_frame, L_frame ); - st->hHQ_core->Q_old_wtda_LB = Q_syn; // st->hHQ_core->Q_old_wtda +#ifndef HARMONIZE_2446_CON_TCX_FX + st->hHQ_core->Q_old_wtda_LB = Q_syn; // st->hHQ_core->Q_old_wtda +#else + IF( !leg_flag ) + { + st->hHQ_core->Q_old_wtda_LB = Q_syn; // st->hHQ_core->Q_old_wtda + } +#endif // !HARMONIZE_2446_CON_TCX_FX + st->old_enr_LP = Enr_1_Az_fx( A_local, L_SUBFR ); /*Q3*/ move16(); diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index 65479c7a1b584968e0b38d739c9030223952f17a..df3600130cf1b6b2c4322da79903343a68f9d76f 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1297,17 +1297,29 @@ void ivas_mdct_core_reconstruct_fx( /* PLC: [TCX: TD PLC] */ IF( MCT_flag != 0 ) { +#ifndef HARMONIZE_2446_CON_TCX_FX con_tcx_ivas_fx( st, &synthFB_fx[0], -16384, NULL, 0, NULL ); //-1.Q14 = -16384 +#else + con_tcx_ivas_fx( st, &synthFB_fx[0], -16384, NULL, 0, NULL, (Word16) 0 ); //-1.Q14 = -16384 +#endif // !HARMONIZE_2446_CON_TCX_FX } ELSE { IF( sts[1]->core != ACELP_CORE ) { +#ifndef HARMONIZE_2446_CON_TCX_FX con_tcx_ivas_fx( st, &synthFB_fx[0], hCPE->hStereoMdct->lastCoh_fx, &sts[0]->seed_acelp, 1, &st->hFdCngDec->hFdCngCom->A_cng[0] ); +#else + con_tcx_ivas_fx( st, &synthFB_fx[0], hCPE->hStereoMdct->lastCoh_fx, &sts[0]->seed_acelp, 1, &st->hFdCngDec->hFdCngCom->A_cng[0], (Word16) 0 ); +#endif // !HARMONIZE_2446_CON_TCX_FX } ELSE { +#ifndef HARMONIZE_2446_CON_TCX_FX con_tcx_ivas_fx( st, &synthFB_fx[0], hCPE->hStereoMdct->lastCoh_fx, &sts[0]->seed_acelp, 0, &st->hFdCngDec->hFdCngCom->A_cng[0] ); +#else + con_tcx_ivas_fx( st, &synthFB_fx[0], hCPE->hStereoMdct->lastCoh_fx, &sts[0]->seed_acelp, 0, &st->hFdCngDec->hFdCngCom->A_cng[0], (Word16) 0 ); +#endif // !HARMONIZE_2446_CON_TCX_FX } } st->hHQ_core->Q_old_wtda = add( st->hHQ_core->Q_old_wtda, q_syn ); diff --git a/lib_dec/ivas_tcx_core_dec_fx.c b/lib_dec/ivas_tcx_core_dec_fx.c index cdb2b6061fb3b35c2067d3e7dcc799a8ce62ce62..6def7b519b24aaf86eab5a33bba27097b6e8a5aa 100644 --- a/lib_dec/ivas_tcx_core_dec_fx.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -489,7 +489,11 @@ void stereo_tcx_core_dec_fx( } /* PLC: [TCX: TD PLC] */ +#ifndef HARMONIZE_2446_CON_TCX_FX con_tcx_fx( st, &synthFB_fx[0] /*, -1.f, NULL, 0, NULL */ ); +#else + con_tcx_ivas_fx( st, &synthFB_fx[0], -16384, NULL, 0, NULL, (Word16) 1 ); +#endif // !HARMONIZE_2446_CON_TCX_FX test(); IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc ) {