diff --git a/lib_com/options.h b/lib_com/options.h index 44ebea512895c0fb67488b0d0a2ad787561cb770..dbe71e39f142d2918d9527e0b18e9efaa8cc078f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -157,6 +157,7 @@ #define FIX_578_PARAMMC_ILD_BS /* FhG: Issue 578: transmitt also center ILD in band 0 when LFE is active in 3TC ParamMC */ #define FIX_UNCLR_ISSUE /* VoiceAge: issue 574: Fix UNCLR mis-classifications in noisy speech stereo */ #define FIX_TCX_LOWRATE_LIMITATION /* VA: issue 577: TCX bitrate limitation only when DEBUGGING is active */ +#define FIX_575_LOW_OVERLAP_PLC_RECOVERY /* FhG: Issue 575 fix for PLC and transistion to TCX5*/ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index bc10986256c13b76a1acd56240dacd8423bdaa59..dd10cef29324326de7e73a828b35889ae317853a 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -377,7 +377,11 @@ void IMDCT( TCX_MDCT_Inverse( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode ); } +#ifndef FIX_575_LOW_OVERLAP_PLC_RECOVERY tcx_windowing_synthesis_current_frame( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core_bfi, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale ); +#else + tcx_windowing_synthesis_current_frame( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale ); +#endif if ( w > 0 ) { @@ -393,6 +397,14 @@ void IMDCT( /* To assure that no garbage values are passed to overlap */ set_zero( xn_buf + L_frame + tcx_offset + ( L_ola >> 1 ), overlap - tcx_offset - ( L_ola >> 1 ) ); + +#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY + if ( st->prev_bfi && frame_cnt == 0 && st->last_core != st->last_core_bfi && st->last_core_bfi == ACELP_CORE ) + { + tcx_windowing_synthesis_past_frame( old_syn_overl, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_last_overlap_mode ); + v_add( xn_buf, old_syn_overl, xn_buf, overlap ); + } +#endif } else if ( !bfi && ( frame_cnt == 0 ) && ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) @@ -1240,27 +1252,80 @@ void decoder_tcx_noisefilling( if ( ( frame_cnt == 0 ) && ( L_frameTCX == hTcxDec->L_frameTCX >> 1 ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( st->nbLostCmpt == 1 ) && ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) { E_2ndlast = E_last = EPSILON; +#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY + if ( st->element_mode > EVS_MONO ) + { + for ( i = 0; i < L_frameTCX; i = i + 2 ) + { + E_2ndlast += st->hTonalMDCTConc->lastBlockData.spectralData[i] * st->hTonalMDCTConc->lastBlockData.spectralData[i]; + E_last += st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] * st->hTonalMDCTConc->lastBlockData.spectralData[i + 1]; + } + } + else + { + for ( i = 0; i < infoIGFStartLine; i = i + 2 ) + { + E_2ndlast += st->hTonalMDCTConc->lastBlockData.spectralData[i] * st->hTonalMDCTConc->lastBlockData.spectralData[i]; + E_last += st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] * st->hTonalMDCTConc->lastBlockData.spectralData[i + 1]; + } + } +#else for ( i = 0; i < infoIGFStartLine; i = i + 2 ) { E_2ndlast += st->hTonalMDCTConc->lastBlockData.spectralData[i] * st->hTonalMDCTConc->lastBlockData.spectralData[i]; E_last += st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] * st->hTonalMDCTConc->lastBlockData.spectralData[i + 1]; } +#endif tmp2 = E_2ndlast / E_last; /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */ if ( tmp2 > 2 ) { +#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY + if ( st->element_mode > EVS_MONO ) + { + for ( i = 0; i < L_frameTCX; i = i + 2 ) + { + st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1]; + } + } + else + { + for ( i = 0; i < infoIGFStartLine; i = i + 2 ) + { + st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1]; + } + } +#else for ( i = 0; i < infoIGFStartLine; i = i + 2 ) { st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1]; } +#endif } else if ( tmp2 < 0.5 ) { +#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY + if ( st->element_mode > EVS_MONO ) + { + for ( i = 0; i < L_frameTCX; i = i + 2 ) + { + st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i]; + } + } + else + { + for ( i = 0; i < infoIGFStartLine; i = i + 2 ) + { + st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i]; + } + } +#else for ( i = 0; i < infoIGFStartLine; i = i + 2 ) { st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i]; } +#endif } }