LCOV - code coverage report
Current view: top level - lib_dec - er_dec_tcx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 216 247 87.4 %
Date: 2025-05-23 08:37:30 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include "cnst.h"
      38             : #include "ivas_cnst.h"
      39             : #include <assert.h>
      40             : #include <stdint.h>
      41             : #include "options.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include <math.h>
      46             : #include "prot.h"
      47             : #include "rom_dec.h"
      48             : #include "wmc_auto.h"
      49             : 
      50             : /*-----------------------------------------------------------------*
      51             :  * con_tcx()
      52             :  *
      53             :  *
      54             :  *-----------------------------------------------------------------*/
      55             : 
      56       16731 : void con_tcx(
      57             :     Decoder_State *st,       /* i/o: coder memory state          */
      58             :     float synth[],           /* i/o: synth[]                     */
      59             :     const float coh,         /* i  : coherence of stereo signal  */
      60             :     int16_t *noise_seed,     /* i/o: noise seed for stereo       */
      61             :     const int16_t only_left, /* i  : TD-PLC only in left channel */
      62             :     const float A_cng[]      /* i  : CNG LP filter coefficients  */
      63             : )
      64             : {
      65             :     int16_t i, n, L_frame, L_subfr, fLowPassFilter, T0;
      66       16731 :     int16_t offset = 0;
      67             :     int16_t mem_syn_r_size_old, mem_syn_r_size_new;
      68             :     float *noise;
      69             :     float mem_syn[M], *syn;
      70             :     float *exc, buf[OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2];
      71             :     float pre_emph_buf;
      72             :     float pitch_buf[NB_SUBFR16k], hp_filt[L_FIR_FER2];
      73       16731 :     float predPitchLag, alpha = 0.0f;
      74             :     float tmp_deemph, step, gain, gainCNG, gain_inov, ftmp;
      75             :     float *pt_exc, *pt1_exc;
      76             :     int16_t Tc, tmpSeed;
      77       16731 :     int16_t fUseExtrapolatedPitch = 0;
      78             :     float *ana_window;
      79             :     float r[M + 1], A_local[M + 1], mem;
      80             :     float *w;
      81             :     int16_t W1, W2;
      82       16731 :     int16_t extrapolationFailed = 1;
      83             :     float gainSynthDeemph;
      84       16731 :     float tmp = 0.f;
      85             :     float old_pitch_buf[2 * NB_SUBFR16k + 2];
      86       16731 :     TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
      87       16731 :     TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
      88             : 
      89             :     /* Framing parameters */
      90       16731 :     L_frame = hTcxDec->L_frameTCX;
      91       16731 :     L_subfr = hTcxDec->L_frameTCX / st->nb_subfr;
      92       16731 :     w = st->hTcxCfg->tcx_mdct_windowFB;
      93       16731 :     W1 = st->hTcxCfg->tcx_mdct_window_lengthFB;
      94       16731 :     W2 = st->hTcxCfg->tcx_mdct_window_lengthFB / 2;
      95             : 
      96             :     /* take the previous frame last pitch */
      97       16731 :     Tc = (int16_t) ( st->old_fpitchFB + 0.5f );
      98             : 
      99       16731 :     set_zero( buf, OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2 );
     100             : 
     101       16731 :     v_multc( st->old_pitch_buf, (float) L_frame / st->L_frame, old_pitch_buf, 2 * NB_SUBFR16k + 2 );
     102             : 
     103             :     /* set excitation memory*/
     104       16731 :     exc = buf + OLD_EXC_SIZE_DEC;
     105             : 
     106       16731 :     tmp_deemph = synth[-1];
     107       16731 :     pre_emph_buf = synth[-1];
     108             : 
     109       16731 :     if ( st->nbLostCmpt == 1 || hTcxDec->tcxConceal_recalc_exc )
     110             :     {
     111             :         /* apply pre-emphasis to the signal */
     112        9159 :         mem = synth[-( L_frame / 2 + hTcxDec->pit_max_TCX + 2 * M ) - 1];
     113             : 
     114        9159 :         preemph( &synth[-( L_frame / 2 + hTcxDec->pit_max_TCX + 2 * M )], st->preemph_fac, L_frame / 2 + hTcxDec->pit_max_TCX + 2 * M, &mem );
     115        9159 :         st->lp_gainc = 0.0f;
     116             : 
     117        9159 :         st->lp_gainp = get_gain( synth - 2 * L_subfr, synth - 2 * L_subfr - Tc, 2 * L_subfr, NULL );
     118             : 
     119        9159 :         if ( st->lp_gainp < 0.0f )
     120             :         {
     121          60 :             st->lp_gainp = 0.0f;
     122             :         }
     123             : 
     124        9159 :         if ( st->lp_gainp > 1.0f )
     125             :         {
     126         906 :             st->lp_gainp = 1.0f;
     127             :         }
     128        9159 :         ana_window = buf;
     129        9159 :         ham_cos_window( ana_window, 3 * L_frame / 4, L_frame / 4 );
     130             : 
     131             :         /* Autocorrelation */
     132        9159 :         autocorr( &( synth[-L_frame - 1] ), r, M, L_frame, ana_window, 0, 0, 0 );
     133             : 
     134             :         /* Lag windowing */
     135        9159 :         lag_wind( r, M, st->output_Fs, LAGW_STRONG );
     136             : 
     137             :         /* Levinson Durbin */
     138        9159 :         lev_dur( A_local, r, M, NULL );
     139             : 
     140             :         /* copy for multiple frame loss */
     141        9159 :         mvr2r( A_local, st->old_Aq_12_8, M + 1 );
     142             : 
     143             :         /* Residu */
     144        9159 :         assert( ( 2 * L_subfr + Tc + 1 + M ) <= st->hTcxDec->old_synth_lenFB );
     145        9159 :         residu( A_local, M, &( synth[-( 2 * L_subfr + Tc + 1 + M )] ), &( exc[-( 2 * L_subfr + Tc + 1 + M )] ), 2 * L_subfr + Tc + 1 + M );
     146             :     }
     147             :     else
     148             :     {
     149             :         /* apply pre-emphasis to the signal */
     150        7572 :         mem = synth[-L_frame - 1];
     151             : 
     152        7572 :         preemph( &synth[-L_frame], st->preemph_fac, L_frame, &mem );
     153        7572 :         mvr2r( st->old_Aq_12_8, A_local, M + 1 );
     154        7572 :         offset = L_frame / 2;
     155             : 
     156        7572 :         if ( st->last_good >= UNVOICED_TRANSITION )
     157             :         {
     158        7572 :             i = max( Tc - L_frame / 2, 0 );
     159        7572 :             mvr2r( st->hTcxDec->old_excFB, &( exc[-i] ), offset + i );
     160             :         }
     161             :         else
     162             :         {
     163           0 :             mvr2r( st->hTcxDec->old_excFB, &( exc[-2 * L_subfr] ), 2 * L_subfr + offset );
     164             :         }
     165             :     }
     166             : 
     167             :     /*-----------------------------------------------------------------*
     168             :      * PLC: Construct the harmonic part of excitation
     169             :      *-----------------------------------------------------------------*/
     170             : 
     171       16731 :     if ( st->last_good != UNVOICED_CLAS && !( ( st->last_good == UNVOICED_TRANSITION ) && ( st->core_ext_mode == GENERIC ) ) )
     172             :     {
     173       16731 :         if ( st->nbLostCmpt == 1 || hTcxDec->tcxConceal_recalc_exc )
     174             :         {
     175        9159 :             st->lp_gainc = 0.0f;
     176             : 
     177     3029511 :             for ( i = 0; i < 2 * L_subfr; i++ )
     178             :             {
     179     3020352 :                 st->lp_gainc += ( exc[i - 2 * L_subfr] - st->lp_gainp * exc[i - 2 * L_subfr - Tc] ) * ( exc[i - 2 * L_subfr] - st->lp_gainp * exc[i - 2 * L_subfr - Tc] );
     180             :             }
     181        9159 :             st->lp_gainc = (float) sqrt( st->lp_gainc / ( 2.0f * L_subfr ) );
     182             :         }
     183       16731 :         if ( ( st->nbLostCmpt == 1 ) && st->rf_frame_type >= RF_TCXFD && st->rf_frame_type <= RF_TCXTD2 && st->use_partial_copy )
     184             :         {
     185           0 :             predPitchLag = ( hTcxLtpDec->tcxltp_pitch_int + hTcxLtpDec->tcxltp_pitch_fr / (float) st->pit_res_max ) * (float) hTcxDec->L_frameTCX / (float) st->L_frame;
     186           0 :             T0 = (int16_t) ( predPitchLag + 0.5f );
     187             : 
     188           0 :             if ( ( T0 > 0 ) && ( T0 != Tc ) && ( (float) abs( T0 - Tc ) < 0.15f * Tc ) )
     189             :             {
     190           0 :                 fUseExtrapolatedPitch = 1;
     191             :             }
     192             :         }
     193             :         else
     194             :         {
     195       16731 :             pitch_pred_linear_fit( st->nbLostCmpt, st->last_good, old_pitch_buf, &( st->old_fpitchFB ), &predPitchLag, hTcxDec->pit_min_TCX, hTcxDec->pit_max_TCX, st->mem_pitch_gain, st->output_Fs > 25600, st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr );
     196             : 
     197       16731 :             T0 = (int16_t) ( predPitchLag + 0.5f );
     198             : 
     199       16731 :             if ( ( T0 > 0 ) && ( T0 != Tc ) && ( (float) abs( T0 - Tc ) < 0.15f * Tc ) && extrapolationFailed == 0 )
     200             :             {
     201        3738 :                 fUseExtrapolatedPitch = 1;
     202             :             }
     203             :         }
     204             : 
     205       16731 :         fLowPassFilter = 0;
     206       16731 :         pt_exc = exc + offset;
     207             : 
     208       16731 :         pt1_exc = pt_exc - Tc;
     209             : 
     210       16731 :         if ( fUseExtrapolatedPitch != 0 )
     211             :         {
     212        3738 :             pt_exc = buf;
     213             :         }
     214             : 
     215       16731 :         if ( st->stab_fac < 1 && st->nbLostCmpt == 1 )
     216             :         {
     217             :             /* pitch cycle is first low-pass filtered */
     218      687606 :             for ( i = 0; i < Tc; i++ )
     219             :             {
     220      684990 :                 if ( st->output_Fs <= 16000 )
     221             :                 {
     222       37227 :                     *pt_exc++ = ( 0.0053f * pt1_exc[-5] + 0.0000f * pt1_exc[-4] + -0.0440f * pt1_exc[-3] + 0.0000f * pt1_exc[-2] + 0.2637f * pt1_exc[-1] + 0.5500f * pt1_exc[0] + 0.2637f * pt1_exc[1] + 0.0000f * pt1_exc[2] + -0.0440f * pt1_exc[3] + 0.0000f * pt1_exc[4] + 0.0053f * pt1_exc[5] );
     223             :                 }
     224             :                 else /*(st->output_Fs >= 32000)*/
     225             :                 {
     226      647763 :                     *pt_exc++ = ( -0.0053f * pt1_exc[-5] + -0.0037f * pt1_exc[-4] + -0.0140f * pt1_exc[-3] + 0.0180f * pt1_exc[-2] + 0.2668f * pt1_exc[-1] + 0.4991f * pt1_exc[0] + 0.2668f * pt1_exc[1] + 0.0180f * pt1_exc[2] + -0.0140f * pt1_exc[3] + -0.0037f * pt1_exc[4] + -0.0053f * pt1_exc[5] );
     227             :                 }
     228      684990 :                 pt1_exc++;
     229             :             }
     230        2616 :             fLowPassFilter = 1;
     231             :         }
     232             :         else
     233             :         {
     234             :             /* copy the first pitch cycle without low-pass filtering */
     235     3395745 :             for ( i = 0; i < Tc; i++ )
     236             :             {
     237     3381630 :                 *pt_exc++ = *pt1_exc++;
     238             :             }
     239       14115 :             fLowPassFilter = 1;
     240             :         }
     241             : 
     242       16731 :         if ( fUseExtrapolatedPitch != 0 )
     243             :         {
     244        3738 :             pt1_exc = buf;
     245             :         }
     246             : 
     247    10603551 :         for ( i = 0; i < L_frame - fLowPassFilter * Tc + L_subfr; i++ )
     248             :         {
     249    10586820 :             *pt_exc++ = *pt1_exc++;
     250             :         }
     251             : 
     252       16731 :         if ( fUseExtrapolatedPitch != 0 )
     253             :         {
     254        3738 :             get_subframe_pitch( st->nb_subfr, st->old_fpitch, predPitchLag * st->L_frame / L_frame, pitch_buf );
     255             : 
     256        3738 :             PulseResynchronization( buf, exc, L_frame, st->nb_subfr, st->old_fpitchFB, predPitchLag );
     257             :         }
     258             :         else
     259             :         {
     260       12993 :             set_f( pitch_buf, st->old_fpitch, st->nb_subfr );
     261             :         }
     262             : 
     263       16731 :         if ( st->nbLostCmpt == 1 )
     264             :         {
     265        9159 :             pt_exc = exc + L_frame;
     266        9159 :             pt1_exc = pt_exc - ( ( T0 == 0 ) ? Tc : T0 );
     267             : 
     268     3443079 :             for ( i = 0; i < L_frame / 2; i++ )
     269             :             {
     270     3433920 :                 *pt_exc++ = *pt1_exc++;
     271             :             }
     272             :         }
     273             : 
     274       16731 :         if ( fUseExtrapolatedPitch != 0 )
     275             :         {
     276        3738 :             st->old_fpitchFB = predPitchLag;
     277             :         }
     278       16731 :         st->bpf_gain_param = 0;
     279             : 
     280             :         /* PLC: calculate damping factor */
     281       16731 :         alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE );
     282             : 
     283       16731 :         if ( st->nbLostCmpt == 1 )
     284             :         {
     285        9159 :             st->cummulative_damping = 1;
     286             :         }
     287             :         else
     288             :         {
     289        7572 :             st->cummulative_damping *= alpha;
     290             :         }
     291             : 
     292       16731 :         gain = 1.0f;
     293       16731 :         if ( st->rf_frame_type == RF_TCXTD1 && st->use_partial_copy == 1 )
     294             :         {
     295           0 :             gain = 0.5f;
     296             :         }
     297             : 
     298       16731 :         step = ( 1.0f / ( L_frame + ( L_frame / 2 ) ) ) * ( gain - alpha );
     299             : 
     300             :         /* PLC: Apply fade out */
     301    15454491 :         for ( i = offset; i < L_frame + ( L_frame / 2 ); i++ )
     302             :         {
     303    15437760 :             exc[i] *= gain;
     304    15437760 :             gain -= step;
     305             :         }
     306             : 
     307       16731 :         offset = max( ( (int16_t) ( st->old_fpitchFB + 0.5f ) ) - L_frame / 2, 0 );
     308       16731 :         mvr2r( exc + L_frame - offset, st->hTcxDec->old_excFB, L_frame / 2 + offset );
     309             : 
     310             :         /* copy old_exc as 16kHz for acelp decoding */
     311       16731 :         if ( st->nbLostCmpt == 1 )
     312             :         {
     313        9159 :             lerp( exc - L_frame / 2, st->old_exc, L_EXC_MEM_DEC, L_frame + L_frame / 2 );
     314             :         }
     315             :         else
     316             :         {
     317        7572 :             mvr2r( st->old_exc + L_FRAME16k, st->old_exc, L_FRAME16k / 2 );
     318        7572 :             lerp( exc, st->old_exc + L_FRAME16k / 2, L_FRAME16k, L_frame );
     319             :         }
     320             :     }
     321             :     else
     322             :     {
     323             :         /* No harmonic part */
     324           0 :         set_zero( &exc[0], L_frame + L_frame / 2 );
     325             : 
     326           0 :         if ( st->nbLostCmpt == 1 )
     327             :         {
     328           0 :             st->lp_gainc = 0.0f;
     329             : 
     330           0 :             for ( i = 0; i < 2 * L_subfr; i++ )
     331             :             {
     332           0 :                 st->lp_gainc += ( exc[i - 2 * L_subfr] ) * ( exc[i - 2 * L_subfr] );
     333             :             }
     334           0 :             st->lp_gainc = (float) sqrt( st->lp_gainc / ( 2.0f * L_subfr ) );
     335             :         }
     336             : 
     337           0 :         set_f( pitch_buf, (float) L_SUBFR, st->nb_subfr );
     338             : 
     339             :         /* PLC: calculate damping factor */
     340           0 :         alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE );
     341             :     }
     342             : 
     343             :     /*-----------------------------------------------------------------*
     344             :      * Construct the random part of excitation
     345             :      *-----------------------------------------------------------------*/
     346             : 
     347       16731 :     if ( coh != -1.f )
     348             :     {
     349             :         int16_t tmpSeed1;
     350             :         float alpha_coh;
     351             :         float random1, random2;
     352             : 
     353        3291 :         tmpSeed1 = *noise_seed;
     354        3291 :         noise = buf;
     355             : 
     356        3291 :         alpha_coh = sqrtf( ( 1 - coh ) / ( 1 + coh ) );
     357        3291 :         if ( st->idchan == 1 )
     358             :         {
     359        1521 :             alpha_coh = -alpha_coh;
     360             :         }
     361             : 
     362     2140521 :         for ( i = 0; i < L_frame + L_FIR_FER2 - 1; i++ )
     363             :         {
     364     2137230 :             random1 = (float) own_random( &tmpSeed1 );
     365     2137230 :             random2 = (float) own_random( &tmpSeed1 );
     366     2137230 :             noise[i] = random1 + alpha_coh * random2;
     367             :         }
     368             : 
     369        3291 :         if ( st->idchan == 1 || only_left )
     370             :         {
     371        1911 :             *noise_seed = tmpSeed1;
     372             :         }
     373             : 
     374     1094943 :         for ( ; i < L_frame + ( L_frame / 2 ) + 2 * L_FIR_FER2; i++ )
     375             :         {
     376     1091652 :             random1 = (float) own_random( &tmpSeed1 );
     377     1091652 :             random2 = (float) own_random( &tmpSeed1 );
     378     1091652 :             noise[i] = random1 + alpha_coh * random2;
     379             :         }
     380             :     }
     381             :     else
     382             :     {
     383       13440 :         tmpSeed = st->seed_acelp;
     384       13440 :         noise = buf;
     385             : 
     386    10047360 :         for ( i = 0; i < L_frame + L_FIR_FER2 - 1; i++ )
     387             :         {
     388    10033920 :             noise[i] = (float) own_random( &tmpSeed );
     389             :         }
     390       13440 :         st->seed_acelp = tmpSeed;
     391             : 
     392     5124480 :         for ( ; i < L_frame + ( L_frame / 2 ) + 2 * L_FIR_FER2; i++ )
     393             :         {
     394     5111040 :             noise[i] = (float) own_random( &tmpSeed );
     395             :         }
     396             :     }
     397             : 
     398       16731 :     if ( st->last_good == VOICED_CLAS || st->last_good == ONSET )
     399             :     {
     400       16482 :         mem = noise[0];
     401       16482 :         preemph( &noise[1], st->output_Fs <= 16000 ? 0.2f : 0.6f, L_frame + ( L_frame / 2 ) + L_FIR_FER2, &mem );
     402             :     }
     403             : 
     404             :     /* high rate filter tuning */
     405       16731 :     if ( st->output_Fs <= 16000 )
     406             :     {
     407       48528 :         for ( i = 0; i < L_FIR_FER2; i++ )
     408             :         {
     409       44484 :             hp_filt[i] = h_high3_16[i];
     410             :         }
     411             :     }
     412             :     else /*(st->output_Fs==32000)*/
     413             :     {
     414      152244 :         for ( i = 0; i < L_FIR_FER2; i++ )
     415             :         {
     416      139557 :             hp_filt[i] = h_high3_32[i];
     417             :         }
     418             :     }
     419             : 
     420       16731 :     if ( st->nbLostCmpt == 1 )
     421             :     {
     422        9159 :         highPassFiltering( st->last_good, L_frame + L_frame / 2 + L_FIR_FER2, noise, hp_filt, L_FIR_FER2 );
     423             :     }
     424             :     else
     425             :     {
     426        7572 :         if ( st->last_good > UNVOICED_TRANSITION )
     427             :         {
     428     7794864 :             for ( i = 0; i < L_frame + L_frame / 2 + L_FIR_FER2; i++ )
     429             :             {
     430     7787292 :                 noise[i] = ( 1 - st->cummulative_damping ) * noise[i] + st->cummulative_damping * dotp( &noise[i], hp_filt, L_FIR_FER2 );
     431             :             }
     432             :         }
     433             :     }
     434             : 
     435             :     /* PLC: [TCX: Fade-out] retrieve background level */
     436       16731 :     tmp = 1.0f;
     437       16731 :     if ( A_cng != NULL )
     438             :     {
     439        3291 :         gainSynthDeemph = getLevelSynDeemph( &( tmp ), A_cng, L_frame / 4, st->preemph_fac, 1 ) / 4.f;
     440             :     }
     441             :     else
     442             :     {
     443       13440 :         gainSynthDeemph = getLevelSynDeemph( &( tmp ), A_local, L_frame / 4, st->preemph_fac, 1 );
     444             :     }
     445       16731 :     if ( st->tcxonly )
     446             :     {
     447       13527 :         gainCNG = hTcxDec->CngLevelBackgroundTrace_bfi / gainSynthDeemph;
     448             : 
     449       13527 :         if ( st->element_mode == IVAS_CPE_MDCT && A_cng != NULL )
     450             :         {
     451        3291 :             if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN )
     452             :             {
     453           0 :                 gainCNG = 0.f;
     454             :             }
     455        3291 :             else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME )
     456             :             {
     457           0 :                 gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN;
     458             :             }
     459             :         }
     460             :     }
     461             :     else
     462             :     {
     463        3204 :         gainCNG = st->cngTDLevel / gainSynthDeemph;
     464             :     }
     465       16731 :     gain = st->lp_gainc; /* start-of-the-frame gain */
     466             : 
     467       16731 :     if ( st->rf_frame_type == RF_TCXTD1 && st->use_partial_copy == 1 )
     468             :     {
     469           0 :         gain *= 0.7f;
     470             :     }
     471             : 
     472       16731 :     ftmp = 2.0f * gain;
     473             : 
     474       16731 :     if ( gainCNG > ftmp )
     475             :     {
     476          84 :         gainCNG = ftmp;
     477             :     }
     478             : 
     479       16731 :     st->lp_gainc = alpha * st->lp_gainc + ( 1.0f - alpha ) * gainCNG; /* end-of-the-frame gain */
     480             : 
     481             :     /* PLC: [TCX: Fade-out] Linearly attenuate the gain through the frame */
     482       16731 :     step = ( 1.0f / L_frame ) * ( gain - st->lp_gainc );
     483       16731 :     pt_exc = noise + L_FIR_FER2 / 2;
     484             : 
     485       16731 :     gain_inov = 1.0f / (float) sqrt( dotp( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f ); /* normalize energy */
     486             : 
     487       16731 :     if ( ( st->last_good == UNVOICED_CLAS ) && ( st->core_ext_mode != UNVOICED ) )
     488             :     {
     489           0 :         gain_inov *= 0.8f;
     490             :     }
     491       16731 :     else if ( !( ( st->last_good == UNVOICED_CLAS ) || ( st->last_good == UNVOICED_TRANSITION ) ) )
     492             :     {
     493       16731 :         gain_inov *= ( 1.1f - 0.75f * st->lp_gainp );
     494             :     }
     495       16731 :     st->lp_gainp = alpha;
     496       16731 :     pt_exc = noise; /* non-causal ringing of the FIR filter   */
     497             : 
     498      100386 :     for ( i = 0; i < L_FIR_FER2 / 2; i++ )
     499             :     {
     500       83655 :         *pt_exc++ *= ( gain_inov * gain );
     501             :     }
     502             : 
     503    12104226 :     for ( i = 0; i < L_frame + L_FIR_FER2 / 2; i++ ) /* Actual filtered random part of excitation */
     504             :     {
     505    12087495 :         *pt_exc++ *= ( gain_inov * gain );
     506    12087495 :         gain -= step;
     507             :     }
     508             : 
     509     6018651 :     for ( i = 0; i < ( L_frame / 2 ); i++ ) /* causal ringing of the FIR filter */
     510             :     {
     511     6001920 :         *pt_exc++ *= ( gain_inov * gain );
     512             :     }
     513             : 
     514             :     /*-----------------------------------------------------------------*
     515             :      * Construct the total excitation
     516             :      *-----------------------------------------------------------------*/
     517             : 
     518       16731 :     if ( st->last_good >= UNVOICED_TRANSITION )
     519             :     {
     520    18022491 :         for ( i = 0; i < ( L_frame + L_frame / 2 ); i++ )
     521             :         {
     522    18005760 :             exc[i] += noise[i + ( L_FIR_FER2 / 2 )];
     523             :         }
     524             :     }
     525             :     else
     526             :     {
     527           0 :         mvr2r( noise + L_FIR_FER2 / 2, exc, L_frame + L_frame / 2 );
     528           0 :         mvr2r( exc + L_frame - 2 * L_subfr, st->hTcxDec->old_excFB, 2 * L_subfr + L_frame / 2 );
     529             : 
     530             :         /* copy old_exc as 16kHz for acelp decoding */
     531           0 :         if ( st->nbLostCmpt == 1 )
     532             :         {
     533           0 :             lerp( exc, st->old_exc, L_EXC_MEM_DEC, L_frame + L_frame / 2 );
     534             :         }
     535             :         else
     536             :         {
     537           0 :             mvr2r( st->old_exc + L_FRAME16k, st->old_exc, L_FRAME16k / 2 );
     538           0 :             lerp( exc, st->old_exc + L_FRAME16k / 2, L_FRAME16k, L_frame );
     539             :         }
     540             :     }
     541             : 
     542             :     /* Update Pitch Lag memory */
     543       16731 :     mvr2r( &st->old_pitch_buf[st->nb_subfr], st->old_pitch_buf, st->nb_subfr );
     544       16731 :     mvr2r( pitch_buf, &st->old_pitch_buf[st->nb_subfr], st->nb_subfr );
     545             : 
     546             :     /*----------------------------------------------------------*
     547             :      * - compute the synthesis speech                           *
     548             :      *----------------------------------------------------------*/
     549             : 
     550       16731 :     syn = buf + M;
     551       16731 :     mvr2r( synth - M, buf, M );
     552       16731 :     mvr2r( buf, mem_syn, M );
     553             : 
     554       16731 :     if ( A_cng != NULL )
     555             :     {
     556             :         float alpha_delayed;
     557             : 
     558        3291 :         alpha_delayed = 1.0f;
     559        3291 :         if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE )
     560             :         {
     561         882 :             alpha_delayed = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE );
     562             :         }
     563             : 
     564        3291 :         if ( st->plcBackgroundNoiseUpdated && alpha_delayed != 1.0f )
     565             :         {
     566             :             float lsp_local[M], lsp_fade[M], alpha_inv;
     567             : 
     568           0 :             alpha_inv = 1.0f - alpha_delayed;
     569             : 
     570           0 :             a2lsp_stab( A_local, lsp_local, st->lspold_cng );
     571             : 
     572           0 :             for ( i = 0; i < M; i++ )
     573             :             {
     574           0 :                 lsp_fade[i] = alpha_delayed * lsp_local[i] + alpha_inv * st->lspold_cng[i];
     575             :             }
     576             : 
     577           0 :             lsp2a_stab( lsp_fade, A_local, M );
     578             :         }
     579             :     }
     580             : 
     581       16731 :     syn_filt( A_local, M, &exc[0], &syn[0], L_frame + ( L_frame / 2 ), mem_syn, 1 );
     582             : 
     583       16731 :     n = (int16_t) ( (float) L_frame * N_ZERO_MDCT_NS / FRAME_SIZE_NS );
     584             : 
     585             :     /* update ACELP synthesis memory */
     586       16731 :     mem_syn_r_size_old = (int16_t) ( 1.25 * L_frame / 20.f );
     587             : 
     588             :     /* copy mem_syn as 16kHz */
     589       16731 :     mem_syn_r_size_new = (int16_t) ( 1.25 * L_FRAME16k / 20.f );
     590       16731 :     mvr2r( syn + L_frame - L_SYN_MEM, st->mem_syn_r, L_SYN_MEM );
     591       16731 :     lerp( st->mem_syn_r + L_SYN_MEM - mem_syn_r_size_old, st->mem_syn_r + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old );
     592       16731 :     mvr2r( st->mem_syn_r + L_SYN_MEM - M, st->mem_syn2, M );
     593             : 
     594             :     /* Deemphasis and output synth and ZIR */
     595       16731 :     deemph( syn, st->preemph_fac, L_frame + L_frame / 2, &tmp_deemph );
     596       16731 :     mvr2r( syn + L_frame - M - 1, st->syn, 1 + M );
     597             : 
     598             : 
     599       16731 :     lerp( syn + L_frame - L_frame / 2, st->hTcxDec->old_syn_Overl, st->L_frame / 2, L_frame / 2 );
     600       16731 :     mvr2r( syn + L_frame - n, st->hHQ_core->old_out, L_frame - n );
     601             : 
     602     5268411 :     for ( i = 0; i < W1; i++ )
     603             :     {
     604     5251680 :         st->hHQ_core->old_out[i + n] *= w[W1 - 1 - i] * w[W1 - 1 - i];
     605             :     }
     606       16731 :     set_zero( &st->hHQ_core->old_out[W1 + n], n );
     607             : 
     608       16731 :     mvr2r( syn, synth, L_frame );
     609             : 
     610       16731 :     mvr2r( syn + L_frame, st->hTcxDec->syn_OverlFB, L_frame / 2 );
     611             : 
     612             :     /* copy total excitation exc2 as 16kHz for ACELP MODE1 decoding */
     613       16731 :     if ( st->hWIDec != NULL )
     614             :     {
     615           0 :         lerp( exc, st->hWIDec->old_exc2, L_EXC_MEM, L_frame );
     616           0 :         lerp( syn, st->hWIDec->old_syn2, L_EXC_MEM, L_frame );
     617             :     }
     618       16731 :     st->bfi_pitch = pitch_buf[st->nb_subfr - 1];
     619       16731 :     st->bfi_pitch_frame = st->L_frame;
     620             : 
     621             :     /* create aliasing and windowing need for transition to TCX10/5 */
     622       16731 :     mvr2r( syn + L_frame, st->hTcxDec->syn_Overl_TDACFB, L_frame / 2 );
     623             : 
     624     5268411 :     for ( i = 0; i < W1; i++ )
     625             :     {
     626     5251680 :         buf[i] = st->hTcxDec->syn_Overl_TDACFB[i] * w[W1 - 1 - i];
     627             :     }
     628             : 
     629     2642571 :     for ( i = 0; i < W2; i++ )
     630             :     {
     631     2625840 :         st->hTcxDec->syn_Overl_TDACFB[i] = buf[i] + buf[W1 - 1 - i]; /* A-D */
     632             :     }
     633             : 
     634     2642571 :     for ( i = 0; i < W2; i++ )
     635             :     {
     636     2625840 :         st->hTcxDec->syn_Overl_TDACFB[W2 + i] = buf[W2 + i] + buf[W1 - 1 - W2 - i]; /* B-C */
     637             :     }
     638             : 
     639     5268411 :     for ( i = 0; i < W1; i++ )
     640             :     {
     641     5251680 :         st->hTcxDec->syn_Overl_TDACFB[i] *= w[W1 - 1 - i];
     642             :     }
     643             : 
     644       16731 :     st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP;
     645       16731 :     synth[-1] = pre_emph_buf;
     646             : 
     647             :     /* update memory for low band */
     648       16731 :     lerp( st->hTcxDec->syn_OverlFB, st->hTcxDec->syn_Overl, st->L_frame / 2, L_frame / 2 );
     649       16731 :     lerp( st->hTcxDec->syn_Overl_TDACFB, st->hTcxDec->syn_Overl_TDAC, st->L_frame / 2, L_frame / 2 );
     650       16731 :     lerp( st->hHQ_core->old_out, st->hHQ_core->old_outLB, st->L_frame, L_frame );
     651             : 
     652       16731 :     st->old_enr_LP = enr_1_Az( A_local, L_SUBFR );
     653             : 
     654       16731 :     return;
     655             : }

Generated by: LCOV version 1.14