LCOV - code coverage report
Current view: top level - lib_dec - dec_tcx_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 8c2c66c735e1c8ef166473ecb3aee5dd03cf9eca Lines: 2064 2706 76.3 %
Date: 2025-09-19 03:28:21 Functions: 20 21 95.2 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include <stdio.h>
       7             : #include <assert.h>
       8             : #include "prot_fx.h"
       9             : #include "options.h"
      10             : #include "basop_util.h"
      11             : #include "stl.h"
      12             : #include "math.h"
      13             : #include "ivas_prot_fx.h"
      14             : #include "rom_com.h"
      15             : #include "ivas_rom_com.h"
      16             : 
      17             : 
      18             : extern const Word16 T_DIV_L_Frame[]; /*0Q15 * 2^-7 */
      19             : 
      20             : /* o : normalized result              Q31 */
      21             : static Word32 CalculateAbsEnergy_fx(
      22             :     const Word32 L_off, /* i : initial sum value               Qn */
      23             :     const Word16 x[],   /* i : x vector                        Qn */
      24             :     const Word16 lg,    /* i : vector length, range [0..7FFF]  Q0 */
      25             :     Word16 *exp         /* o : exponent of result in [-32,31]  Q0 */
      26             : );
      27             : 
      28         634 : void decoder_tcx_fx(
      29             :     TCX_CONFIG_HANDLE hTcxCfg,
      30             :     Word16 prm[],        /* input:  parameters                        */
      31             :     Word16 A[],          /* input:  coefficients NxAz[M+1]            */
      32             :     Word16 Aind[],       /* input: frame-independent coefficients Az[M+1] */
      33             :     Word16 L_frame_glob, /* input:  frame length                      */
      34             :     Word16 L_frameTCX_glob,
      35             :     Word16 L_spec,
      36             :     Word16 synth[], /* in/out: synth[-M-LFAC..L_frame]          */
      37             :     Word16 synthFB[],
      38             :     Decoder_State *st,
      39             :     Word16 coder_type, /* input : coder type                      */
      40             :     Word16 bfi,        /* input:  Bad frame indicator             */
      41             :     Word16 frame_cnt,  /* input: frame counter in the super frame */
      42             :     Word16 stab_fac    /* input: stability of isf (1Q14)          */
      43             : )
      44             : {
      45             :     Word16 i, index, L_frame, tcx_offset;
      46             :     Word16 L_frameTCX, tcx_offsetFB;
      47             :     Word16 firstLine;
      48             :     Word16 gain_tcx, gain_tcx_e, fac_ns;
      49             :     Word16 Ap[M + 2];
      50             :     Word32 x[N_MAX];
      51             :     Word16 x_e;
      52             :     Word16 *xn_buf;
      53             :     Word16 xn_bufFB[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
      54             :     Word32 xn_buf32[N_MAX];
      55             :     Word16 overlap;
      56             :     Word16 overlapFB;
      57             :     Word16 noiseFillingSize;
      58             :     Word16 noiseTransWidth;
      59             :     Word16 tnsSize; /* number of tns parameters put into prm   */
      60             :     Word8 fUseTns;  /* flag that is set if TNS data is present */
      61             :     STnsData tnsData;
      62             :     Word16 left_rect;
      63             :     Word16 gainlpc2[FDNS_NPTS];
      64             :     Word16 gainlpc2_e[FDNS_NPTS];
      65             :     Word16 noiseTiltFactor;
      66             :     Word16 nf_seed;
      67             :     Word16 tmp1, tmp2, s, *tmpP16;
      68             :     Word8 tmp8;
      69             :     Word32 tmp32;
      70             :     Word16 gamma1;
      71             :     Word16 gamma;
      72             :     Word16 gainCompensate, gainCompensate_e;
      73             :     Word16 h1[L_FRAME_MAX / 4 + 1];
      74             :     Word16 mem[M];
      75             :     Word16 temp_concealment_method;
      76             :     Word16 arith_bits, signaling_bits;
      77             :     Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_sqQ, *prm_target;
      78             :     Word16 *pInfoTCXNoise;
      79             :     Word16 acelp_zir[L_FRAME_MAX / 2];
      80             :     Word16 noise_filling_index;
      81             :     Word16 infoIGFStartLine;
      82             :     Word16 L_spec_con;
      83             :     TCX_LTP_DEC_HANDLE hTcxLtpDec;
      84             :     TCX_DEC_HANDLE hTcxDec;
      85             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      86         634 :     Flag Overflow = 0;
      87         634 :     Flag Carry = 0;
      88         634 :     move32();
      89         634 :     move32();
      90             : #endif
      91         634 :     temp_concealment_method = 0;
      92         634 :     move16();
      93             : 
      94         634 :     hTcxLtpDec = st->hTcxLtpDec;
      95         634 :     hTcxDec = st->hTcxDec;
      96             : 
      97         634 :     prm_target = NULL; /* just to suppress MSVC warnigs */
      98             : 
      99             : 
     100         634 :     x_e = 0; /* to avoid compilation warnings */
     101         634 :     move16();
     102         634 :     nf_seed = 0; /* to avoid compilation warnings */
     103         634 :     move16();
     104             : 
     105             :     /* Overlay xn_buf32 with xn_buf */
     106         634 :     xn_buf = (Word16 *) xn_buf32;
     107             : 
     108         634 :     noiseTransWidth = MIN_NOISE_FILLING_HOLE;
     109         634 :     move16();
     110         634 :     tnsSize = 0;
     111         634 :     move16();
     112         634 :     fUseTns = 0;
     113         634 :     move16();
     114         634 :     gainCompensate = 32768 / 2;
     115         634 :     move16();
     116         634 :     gainCompensate_e = 1;
     117         634 :     move16();
     118      647314 :     FOR( i = 0; i < ( L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2; i++ )
     119             :     {
     120      646680 :         xn_buf32[i] = L_deposit_l( 0 );
     121      646680 :         move32();
     122             :     }
     123             : 
     124             : 
     125             :     /* Init lengths */
     126             : 
     127         634 :     overlap = hTcxCfg->tcx_mdct_window_length;
     128         634 :     move16();
     129         634 :     overlapFB = hTcxCfg->tcx_mdct_window_lengthFB;
     130         634 :     move16();
     131             :     /* Modified the overlap to the delay in case of short blocks*/
     132         634 :     tcx_offset = hTcxCfg->tcx_offset;
     133         634 :     move16();
     134         634 :     tcx_offsetFB = hTcxCfg->tcx_offsetFB;
     135         634 :     move16();
     136         634 :     L_spec_con = L_spec;
     137         634 :     move16();
     138         634 :     gamma1 = st->gamma;
     139         634 :     move16();
     140             : 
     141         634 :     if ( hTcxDec->enableTcxLpc != 0 )
     142             :     {
     143           0 :         gamma1 = 0x7FFF;
     144           0 :         move16();
     145             :     }
     146             : 
     147         634 :     IF( bfi != 0 )
     148             :     {
     149             :         /* PLC: [TCX: Memory update]
     150             :          * PLC: Init buffers */
     151             : 
     152           0 :         assert( st->L_frame_past > 0 );
     153           0 :         L_frame = st->L_frame_past;
     154           0 :         move16();
     155           0 :         L_frameTCX = st->L_frameTCX_past;
     156           0 :         move16();
     157             : 
     158           0 :         left_rect = hTcxDec->prev_widow_left_rect;
     159           0 :         move16();
     160             : 
     161           0 :         IF( left_rect != 0 )
     162             :         {
     163           0 :             tcx_offset = hTcxCfg->lfacNext;
     164           0 :             move16();
     165           0 :             tcx_offsetFB = hTcxCfg->lfacNextFB;
     166           0 :             move16();
     167           0 :             L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
     168           0 :             L_spec_con = add( L_spec_con, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
     169             :         }
     170             :     }
     171             :     ELSE
     172             :     {
     173         634 :         test();
     174         634 :         IF( frame_cnt == 0 && st->last_core == ACELP_CORE )
     175             :         {
     176          38 :             if ( st->prev_bfi == 0 )
     177             :             {
     178          38 :                 hTcxCfg->last_aldo = 0;
     179          38 :                 move16();
     180             :             }
     181             : 
     182             :             /* if past frame is ACELP */
     183          38 :             L_frame = add( L_frame_glob, tcx_offset );
     184          38 :             L_frameTCX = add( L_frameTCX_glob, tcx_offsetFB );
     185          38 :             L_spec_con = add( L_spec_con, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
     186          38 :             assert( hTcxCfg->lfacNext <= 0 );
     187          38 :             L_frame = sub( L_frame, hTcxCfg->lfacNext );
     188          38 :             L_frameTCX = sub( L_frameTCX, hTcxCfg->lfacNextFB );
     189          38 :             tcx_offset = hTcxCfg->lfacNext;
     190          38 :             move16();
     191          38 :             tcx_offsetFB = hTcxCfg->lfacNextFB;
     192          38 :             move16();
     193          38 :             left_rect = 1;
     194          38 :             move16();
     195          38 :             hTcxDec->prev_widow_left_rect = 1;
     196          38 :             move16();
     197             :         }
     198             :         ELSE
     199             :         {
     200             : 
     201         596 :             L_frame = L_frame_glob;
     202         596 :             move16();
     203         596 :             L_frameTCX = L_frameTCX_glob;
     204         596 :             move16();
     205         596 :             left_rect = 0;
     206         596 :             move16();
     207         596 :             hTcxDec->prev_widow_left_rect = 0;
     208         596 :             move16();
     209             :         }
     210             : 
     211         634 :         IF( frame_cnt == 0 && EQ_16( st->last_core_from_bs, ACELP_CORE ) )
     212             :         {
     213          38 :             L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
     214             :         }
     215             : 
     216         634 :         st->L_frame_past = L_frame;
     217         634 :         move16();
     218         634 :         st->L_frameTCX_past = L_frameTCX;
     219         634 :         move16();
     220             :     }
     221             : 
     222         634 :     test();
     223         634 :     IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) )
     224             :     {
     225           0 :         IGFDecUpdateInfo( st->hIGFDec, IGF_GRID_LB_SHORT );
     226             :     }
     227             :     ELSE
     228             :     {
     229         634 :         test();
     230         634 :         test();
     231         634 :         IF( ( EQ_16( st->last_core, ACELP_CORE ) ) || ( left_rect && st->bfi ) )
     232             :         {
     233          38 :             IGFDecUpdateInfo( st->hIGFDec, IGF_GRID_LB_TRAN );
     234             :         }
     235             :         ELSE
     236             :         {
     237         596 :             IGFDecUpdateInfo( st->hIGFDec, IGF_GRID_LB_NORM );
     238             :         }
     239             :     }
     240             : 
     241         634 :     IF( 0 == st->igf )
     242             :     {
     243           0 :         IF( st->narrowBand == 0 )
     244             :         {
     245             :             /* minimum needed for output with sampling rates lower then the
     246             :                nominal sampling rate */
     247           0 :             infoIGFStartLine = s_min( L_frameTCX, L_frame );
     248             :         }
     249             :         ELSE
     250             :         {
     251           0 :             infoIGFStartLine = L_frameTCX;
     252           0 :             move16();
     253             :         }
     254             :     }
     255             :     ELSE
     256             :     {
     257         634 :         infoIGFStartLine = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX );
     258             :     }
     259             : 
     260         634 :     noiseFillingSize = L_spec;
     261         634 :     move16();
     262         634 :     if ( st->igf != 0 )
     263             :     {
     264         634 :         noiseFillingSize = st->hIGFDec->infoIGFStartLine;
     265         634 :         move16();
     266             :     }
     267             : 
     268             : 
     269         634 :     prm_ltp = &prm[1 + NOISE_FILL_RANGES];
     270         634 :     prm_tns = prm_ltp + LTPSIZE;
     271             : 
     272             :     /*-----------------------------------------------------------*
     273             :      * Read TCX parameters                                       *
     274             :      *-----------------------------------------------------------*/
     275             : 
     276         634 :     index = 0;
     277         634 :     move16();
     278             : 
     279         634 :     IF( bfi == 0 )
     280             :     {
     281             : 
     282         634 :         index = prm[0];
     283         634 :         move16();
     284             : 
     285             :         /* read noise level (fac_ns) */
     286             : 
     287         634 :         noise_filling_index = prm[1];
     288         634 :         move16();
     289             : 
     290         634 :         fac_ns = extract_l( L_shr( L_mult0( noise_filling_index, 0x6000 ), NBITS_NOISE_FILL_LEVEL ) );
     291             :     }
     292             :     ELSE
     293             :     {
     294           0 :         fac_ns = 0;
     295           0 :         move16();
     296             :     }
     297             : 
     298             :     /* read TNS data */
     299         634 :     test();
     300         634 :     IF( ( bfi == 0 ) && ( hTcxCfg->fIsTNSAllowed != 0 ) )
     301             :     {
     302         372 :         cast16();
     303             : 
     304         372 :         fUseTns = (Word8) DecodeTnsData( hTcxCfg->pCurrentTnsConfig,
     305             :                                          prm_tns,
     306             :                                          &tnsSize,
     307             :                                          &tnsData );
     308             :     }
     309             :     ELSE
     310             :     {
     311         262 :         fUseTns = 0;
     312         262 :         move16();
     313             :     }
     314             : 
     315         634 :     prm_hm = prm_tns + tnsSize;
     316         634 :     prm_sqQ = prm_hm + NPRM_CTX_HM;
     317             : 
     318             :     /*-----------------------------------------------------------*
     319             :      * Spectrum data                                             *
     320             :      *-----------------------------------------------------------*/
     321             : 
     322         634 :     IF( bfi == 0 )
     323             :     {
     324             : 
     325             :         /*-----------------------------------------------------------*
     326             :          * Context HM                                        *
     327             :          *-----------------------------------------------------------*/
     328         634 :         test();
     329         634 :         test();
     330         634 :         IF( hTcxCfg->ctx_hm != 0 && ( ( st->last_core_from_bs != ACELP_CORE ) || ( frame_cnt > 0 ) ) )
     331             :         {
     332         596 :             st->last_ctx_hm_enabled = prm_hm[0];
     333         596 :             move16();
     334             :             {
     335      382036 :                 FOR( i = 0; i < L_spec; i++ ) /* no context harmonic model, copy MDCT coefficients to x */
     336             :                 {
     337             : 
     338      381440 :                     x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
     339      381440 :                     move32();
     340             :                 }
     341             :             }
     342         596 :             x_e = SPEC_EXP_DEC;
     343         596 :             move16();
     344             :         }
     345             :         ELSE /* hTcxCfg->ctx_hm == 0 */
     346             :         {
     347             : 
     348          38 :             IF( hTcxDec->tcx_lpc_shaped_ari != 0 ) /* low rates: new arithmetic coder */
     349             :             {
     350           0 :                 prm_target = prm_sqQ;
     351           0 :                 move16();
     352           0 :                 prm_sqQ = prm_target + 1;
     353           0 :                 move16();
     354             : 
     355           0 :                 tmp8 = 1;
     356           0 :                 move16();
     357           0 :                 if ( EQ_16( st->last_core_from_bs, ACELP_CORE ) )
     358             :                 {
     359           0 :                     tmp8 = 0;
     360           0 :                     move16();
     361             :                 }
     362             : 
     363           0 :                 tcx_arith_decode_envelope_fx(
     364             :                     x, &x_e,
     365             :                     L_frame,
     366             :                     L_spec,
     367             :                     st,
     368             :                     Aind,
     369           0 :                     *prm_target,
     370             :                     prm_sqQ,
     371             :                     tmp8,
     372             :                     prm_hm, /* HM parameter area */
     373           0 :                     hTcxDec->tcx_hm_LtpPitchLag,
     374             :                     &arith_bits,
     375             :                     &signaling_bits,
     376             :                     &nf_seed,
     377           0 :                     shr( st->bwidth, 1 ) /* equivalent to: (st->bwidth > WB)?1:0 */
     378             :                 );
     379             : 
     380           0 :                 hTcxDec->resQBits[frame_cnt] = sub( *prm_target, arith_bits );
     381           0 :                 move16();
     382             :             }
     383             :             ELSE /* TCX-only: old arithmetic coder */
     384             :             {
     385       30438 :                 FOR( i = 0; i < L_spec; i++ )
     386             :                 {
     387             : 
     388       30400 :                     x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
     389       30400 :                     move32();
     390             :                 }
     391             : 
     392          38 :                 set32_fx( x + L_spec, 0, sub( L_frameTCX, L_spec ) );
     393             : 
     394          38 :                 x_e = SPEC_EXP_DEC;
     395          38 :                 move16();
     396             :             }
     397             : 
     398             :         } /* else of if hTcxCfg->ctx_hm */
     399         634 :         tmp1 = s_max( L_frame, L_frameTCX );
     400         634 :         tmp1 = s_max( tmp1, L_spec_con );
     401         634 :         set32_fx( x + L_spec, 0, sub( tmp1, L_spec ) );
     402             : 
     403             : 
     404             :         /*-----------------------------------------------------------*
     405             :          * adaptive low frequency deemphasis.                        *
     406             :          *-----------------------------------------------------------*/
     407             : 
     408         634 :         weight_a_fx( A, Ap, gamma1, M );
     409             : 
     410         634 :         lpc2mdct( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS, 0 );
     411             : 
     412             : 
     413             :         /* initialize LF deemphasis factors in xn_buf */
     414         634 :         tmp1 = s_max( L_spec, L_frameTCX );
     415         634 :         set16_fx( xn_buf, 0x4000, tmp1 );
     416             : 
     417         634 :         IF( st->tcxonly == 0 )
     418             :         {
     419         634 :             AdaptLowFreqDeemph( x, x_e, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, gainlpc2_e,
     420             :                                 L_frame, xn_buf /* LF deemphasis factors */ );
     421             :         }
     422             :     }
     423             : 
     424             :     /* Global Gain */
     425         634 :     hTcxDec->damping = 0;
     426         634 :     move16();
     427         634 :     IF( bfi == 0 )
     428             :     {
     429             :         /*-----------------------------------------------------------*
     430             :          * Compute global gain                                       *
     431             :          *-----------------------------------------------------------*/
     432             : 
     433         634 :         tmp32 = L_shl( L_mult0( index, 0x797D ), 7 );           /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
     434         634 :         gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
     435         634 :         gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, (Word32) 0xFE000000 ) ) );
     436             : 
     437         634 :         tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
     438         634 :         s = 15 - 5 - 7;
     439         634 :         move16();
     440         634 :         IF( GE_16( L_spec, 1024 ) ) /*reduce precision for avoiding overflow*/
     441             :         {
     442           0 :             tmp1 = mult_r( shl( L_spec, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
     443           0 :             s = 15 - 4 - 7;
     444           0 :             move16();
     445             :         }
     446         634 :         tmp1 = ISqrt16( tmp1, &s );
     447             : 
     448         634 :         gain_tcx = mult( gain_tcx, tmp1 );
     449         634 :         gain_tcx_e = add( gain_tcx_e, s );
     450             : 
     451         634 :         hTcxDec->old_gaintcx_bfi = gain_tcx;
     452         634 :         move16();
     453         634 :         hTcxDec->old_gaintcx_bfi_e = gain_tcx_e;
     454         634 :         move16();
     455             : 
     456         634 :         hTcxDec->cummulative_damping_tcx = 32767 /*1.0f Q15*/;
     457         634 :         move16();
     458             :     }
     459             :     ELSE /* bfi = 1 */
     460             :     {
     461             :         /* PLC: [TCX: Fade-out]
     462             :          * derivation of damping factor */
     463             : 
     464             : 
     465           0 :         IF( st->use_partial_copy != 0 )
     466             :         {
     467           0 :             IF( EQ_16( st->rf_frame_type, RF_TCXFD ) )
     468             :             {
     469           0 :                 tmp32 = L_shl( L_mult0( hTcxDec->old_gaintcx_bfi, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
     470           0 :                 gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 );          /* get exponent */
     471           0 :                 gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, 0xFE000000 ) ) );
     472             : 
     473           0 :                 tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
     474           0 :                 s = 15 - 5 - 7;
     475           0 :                 move16();
     476           0 :                 tmp1 = ISqrt16( tmp1, &s );
     477             : 
     478           0 :                 gain_tcx = mult( gain_tcx, tmp1 );
     479           0 :                 gain_tcx_e = add( gain_tcx_e, s );
     480             : 
     481           0 :                 hTcxDec->old_gaintcx_bfi = gain_tcx;
     482           0 :                 move16();
     483           0 :                 hTcxDec->old_gaintcx_bfi_e = gain_tcx_e;
     484           0 :                 move16();
     485             :             }
     486             :             ELSE
     487             :             {
     488           0 :                 gain_tcx = hTcxDec->old_gaintcx_bfi;
     489           0 :                 move16();
     490           0 :                 gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
     491           0 :                 move16();
     492             :             }
     493             : 
     494           0 :             hTcxDec->damping = 16384 /*1.f Q14*/; /*Q14*/
     495           0 :             move16();
     496             :         }
     497             :         ELSE
     498             :         {
     499           0 :             hTcxDec->damping = Damping_fact_fx( coder_type, st->nbLostCmpt, st->last_good, stab_fac, &( st->Mode2_lp_gainp ), st->last_core );
     500           0 :             move16();
     501           0 :             gain_tcx = hTcxDec->old_gaintcx_bfi;
     502           0 :             move16();
     503           0 :             gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
     504           0 :             move16();
     505             :         }
     506             : 
     507           0 :         hTcxDec->cummulative_damping_tcx = shl( mult( hTcxDec->cummulative_damping_tcx, hTcxDec->damping ), 1 ); /*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/
     508           0 :         move16();
     509             :     }
     510             :     {
     511         634 :         IF( bfi )
     512             :         {
     513           0 :             gamma = gamma1;
     514           0 :             move16();
     515           0 :             if ( hTcxDec->envWeighted )
     516             :             {
     517           0 :                 gamma = st->gamma;
     518           0 :                 move16();
     519             :             }
     520             : 
     521             :             /* PLC: [TCX: Fade-out]
     522             :              * PLC: invert LPC weighting in case of PLC */
     523           0 :             IF( hTcxDec->enableTcxLpc != 0 )
     524             :             {
     525           0 :                 gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( st->gamma, 32767 /*1.0f Q15*/ ) ), 32767 /*1.0f Q15*/ );
     526             :             }
     527             :             ELSE
     528             :             {
     529           0 :                 gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( gamma1, 32767 /*1.0f Q15*/ ) ), 32767 /*1.0f Q15*/ );
     530             :             }
     531           0 :             weight_a_fx( A, Ap, gamma, M );
     532             : 
     533           0 :             lpc2mdct( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS, 0 );
     534             :         }
     535         634 :         tmp2 = 0;
     536         634 :         move16();
     537             : 
     538         634 :         set16_fx( h1, 0, add( L_SUBFR, 1 ) );
     539         634 :         set16_fx( mem, 0, M );
     540         634 :         h1[0] = 32768 / 32;
     541         634 :         move16();
     542         634 :         E_UTIL_synthesis( 0, Ap, h1, h1, L_SUBFR, mem, 0, M );
     543         634 :         deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp2 );
     544             :         /* impulse response level = gain introduced by synthesis+deemphasis */
     545         634 :         IF( bfi == 0 )
     546             :         {
     547             :             /* st->last_gain_syn_deemph = (float)sqrt(dot_product( h1, h1, L_SUBFR)); */
     548         634 :             tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e ) /*Q15, st->last_gain_syn_deemph_e*/;
     549         634 :             st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ );
     550         634 :             move16();
     551         634 :             tmp32 = Sqrt32( tmp32, &st->last_gain_syn_deemph_e );
     552         634 :             st->last_gain_syn_deemph = round_fx_sat( tmp32 );
     553         634 :             move16();
     554             :             /*for avoiding compiler warnings*/
     555         634 :             hTcxDec->gainHelper = 32768 / 2;
     556         634 :             move16();
     557         634 :             hTcxDec->gainHelper_e = 1;
     558         634 :             move16();
     559         634 :             hTcxDec->stepCompensate = 0;
     560         634 :             move16();
     561         634 :             hTcxDec->stepCompensate_e = 0;
     562         634 :             move16();
     563             :         }
     564             :         /* not instrumenting the additional test() here seems to be common practice */
     565           0 :         ELSE IF( EQ_16( TCX_20_CORE, st->core ) || EQ_16( frame_cnt, 1 ) )
     566             :         {
     567             :             /* gainCompensate = st->last_gain_syn_deemph/(float)sqrt(dot_product( h1, h1, L_SUBFR)); */
     568           0 :             tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gainCompensate_e ) /*Q15, gainCompensate_e*/;
     569           0 :             gainCompensate_e = add( gainCompensate_e, 10 /*scaling of h1[0] and E_UTIL:synthesis*/ );
     570           0 :             gainCompensate = round_fx_sat( Sqrt32( tmp32, &gainCompensate_e ) ) /*Q15, gainCompensate_e*/;
     571           0 :             BASOP_Util_Divide_MantExp( st->last_gain_syn_deemph,
     572           0 :                                        st->last_gain_syn_deemph_e,
     573             :                                        gainCompensate,
     574             :                                        gainCompensate_e,
     575             :                                        &gainCompensate,
     576             :                                        &gainCompensate_e );
     577             : 
     578           0 :             tmp1 = T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )];
     579             : 
     580           0 :             IF( EQ_16( st->nbLostCmpt, 1 ) )
     581             :             {
     582             :                 /* stepCompensate = (1.f - gainCompensate)/st->L_frame; */
     583           0 :                 hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
     584             :                     tmp1,
     585             :                     -7,
     586           0 :                     negate( mult( gainCompensate, tmp1 ) ),
     587           0 :                     add( -7, gainCompensate_e ),
     588             :                     &hTcxDec->stepCompensate );
     589           0 :                 move16();
     590             : 
     591           0 :                 hTcxDec->gainHelper = 32768 / 2;
     592           0 :                 move16();
     593           0 :                 hTcxDec->gainHelper_e = 1;
     594           0 :                 move16();
     595             :             }
     596             :             ELSE
     597             :             {
     598             :                 /* stepCompensate = (st->last_concealed_gain_syn_deemph - gainCompensate)/st->L_frame; */
     599           0 :                 hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
     600           0 :                     mult( tmp1, st->last_concealed_gain_syn_deemph ),
     601           0 :                     add( -7, st->last_concealed_gain_syn_deemph_e ),
     602           0 :                     negate( mult( tmp1, gainCompensate ) ),
     603           0 :                     add( -7, gainCompensate_e ),
     604             :                     &hTcxDec->stepCompensate );
     605           0 :                 move16();
     606           0 :                 move16();
     607           0 :                 hTcxDec->gainHelper = st->last_concealed_gain_syn_deemph;
     608           0 :                 hTcxDec->gainHelper_e = st->last_concealed_gain_syn_deemph_e;
     609           0 :                 move16();
     610             :             }
     611           0 :             move16();
     612           0 :             move16();
     613           0 :             st->last_concealed_gain_syn_deemph = gainCompensate;
     614           0 :             st->last_concealed_gain_syn_deemph_e = gainCompensate_e;
     615             :         }
     616             :     }
     617             : 
     618             : 
     619             :     /*-----------------------------------------------------------*
     620             :      * Residual inv. Q.                                          *
     621             :      *-----------------------------------------------------------*/
     622         634 :     test();
     623         634 :     IF( ( bfi == 0 ) && ( hTcxCfg->resq != 0 ) )
     624             :     {
     625             : 
     626         634 :         IF( hTcxDec->tcx_lpc_shaped_ari != 0 ) /* new arithmetic coder */
     627             :         {
     628             : 
     629             :             Word16 *prm_resq;
     630             : 
     631           0 :             prm_resq = prm_sqQ + sub( *prm_target /* = targetBits */
     632             :                                       ,
     633           0 :                                       hTcxDec->resQBits[frame_cnt] );
     634             : 
     635           0 :             i = tcx_ari_res_invQ_spec( x, x_e, L_spec,
     636             :                                        prm_resq,
     637           0 :                                        hTcxDec->resQBits[frame_cnt],
     638             :                                        0,
     639           0 :                                        hTcxCfg->sq_rounding,
     640             :                                        xn_buf /* LF deemphasis factors */ );
     641             :         }
     642             :         ELSE /* old arithmetic coder */
     643             :         {
     644         634 :             i = tcx_res_invQ_gain( &gain_tcx, &gain_tcx_e, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt] );
     645             : 
     646         634 :             tmpP16 = xn_buf;
     647         634 :             if ( st->tcxonly != 0 )
     648           0 :                 tmpP16 = NULL;
     649             : 
     650         634 :             tcx_res_invQ_spec( x, x_e, L_spec, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt], i, hTcxCfg->sq_rounding, tmpP16 /* LF deemphasis factors */ );
     651             :         }
     652             :     }
     653         634 :     test();
     654         634 :     IF( bfi == 0 && st->tcxonly != 0 )
     655             :     {
     656           0 :         test();
     657           0 :         test();
     658           0 :         IF( hTcxLtpDec->tcxltp && ( hTcxLtpDec->tcxltp_gain > 0 ) && !fUseTns )
     659             :         {
     660             : 
     661           0 :             PsychAdaptLowFreqDeemph( x, gainlpc2, gainlpc2_e, NULL );
     662             :         }
     663             :     }
     664             : 
     665             :     /* for FAC */
     666             : 
     667         634 :     test();
     668         634 :     IF( bfi == 0 && st->tcxonly == 0 )
     669             :     {
     670             :         /* Replication of ACELP formant enhancement for low rates */
     671         634 :         test();
     672         634 :         IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_flag != 0 )
     673             :         {
     674           0 :             tcxFormantEnhancement( xn_buf, gainlpc2, gainlpc2_e, x, &x_e, L_frame, L_frameTCX );
     675             :         }
     676             :     }
     677             : 
     678             :     /*-----------------------------------------------------------*
     679             :      * Add gain to the lpc gains                                 *
     680             :      *-----------------------------------------------------------*/
     681             : 
     682         634 :     IF( st->VAD == 0 )
     683             :     {
     684          10 :         gain_tcx = mult_r( gain_tcx, hTcxCfg->na_scale );
     685             :     }
     686             : 
     687         634 :     i = norm_s( gain_tcx );
     688         634 :     gain_tcx = shl( gain_tcx, i );
     689         634 :     gain_tcx_e = sub( gain_tcx_e, i );
     690       41210 :     FOR( i = 0; i < FDNS_NPTS; i++ )
     691             :     {
     692       40576 :         gainlpc2[i] = mult_r( gainlpc2[i], gain_tcx );
     693       40576 :         move16();
     694             :     }
     695             : 
     696             : 
     697             :     /*-----------------------------------------------------------*
     698             :      * Noise filling.                                            *
     699             :      *-----------------------------------------------------------*/
     700             : 
     701         634 :     test();
     702         634 :     IF( bfi == 0 && ( fac_ns > 0 ) )
     703             :     {
     704             : 
     705         634 :         tmp1 = 0;
     706         634 :         move16();
     707         634 :         test();
     708         634 :         if ( GE_16( st->bits_frame, 256 ) && st->rf_flag == 0 )
     709             :         {
     710         634 :             tmp1 = 1;
     711         634 :             move16();
     712             :         }
     713             : 
     714         634 :         firstLine = tcxGetNoiseFillingTilt( A, M, L_frame, tmp1, &noiseTiltFactor );
     715             : 
     716         634 :         IF( st->tcxonly != 0 )
     717             :         {
     718           0 :             tmp1 = 0;
     719           0 :             move16();
     720           0 :             test();
     721           0 :             test();
     722           0 :             if ( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) && ( st->last_ctx_hm_enabled != 0 ) )
     723             :             {
     724           0 :                 tmp1 = 10240 /*0.3125f Q15*/;
     725           0 :                 move16();
     726             :             }
     727           0 :             noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( hTcxLtpDec->tcxltp_gain, tmp1 ) );
     728             : 
     729           0 :             if ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) )
     730             :             {
     731           0 :                 noiseTransWidth = 3; /* minimum transition fading for noise filling in TCX-10 */
     732           0 :                 move16();
     733             :             }
     734             :         }
     735             : 
     736             : 
     737         634 :         IF( hTcxDec->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
     738             :         {
     739             :             /* noise filling seed */
     740         634 :             tmp32 = L_deposit_l( 0 );
     741      412474 :             FOR( i = 0; i < L_spec; i++ )
     742             :             {
     743      411840 :                 tmp32 = L_macNs_co( tmp32, abs_s( prm_sqQ[i] ), i, &Carry, &Overflow );
     744             :             }
     745         634 :             nf_seed = extract_l( tmp32 );
     746             :         }
     747             : 
     748         634 :         tmp1 = nf_seed;
     749         634 :         move16();
     750             : 
     751         634 :         pInfoTCXNoise = NULL;
     752         634 :         if ( st->igf )
     753             :         {
     754         634 :             pInfoTCXNoise = st->hIGFDec->infoTCXNoise_evs;
     755             :         }
     756         634 :         tcx_noise_filling( x, x_e, tmp1 /* seed */, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor,
     757         634 :                            fac_ns, pInfoTCXNoise, st->element_mode );
     758         634 :         st->seed_tcx_plc = tmp1;
     759         634 :         move16();
     760             :     }
     761             : 
     762         634 :     IF( st->enablePlcWaveadjust )
     763             :     {
     764           0 :         IF( bfi )
     765             :         {
     766           0 :             IF( EQ_16( st->nbLostCmpt, 1 ) )
     767             :             {
     768           0 :                 st->hPlcInfo->concealment_method = TCX_NONTONAL;
     769           0 :                 move16();
     770             :                 /* tonal/non-tonal decision */
     771           0 :                 test();
     772           0 :                 test();
     773           0 :                 IF( EQ_16( st->hPlcInfo->Transient[0], 1 ) && EQ_16( st->hPlcInfo->Transient[1], 1 ) && EQ_16( st->hPlcInfo->Transient[2], 1 ) )
     774             :                 {
     775           0 :                     Word16 sum_word16 = 0;
     776           0 :                     move16();
     777             : 
     778           0 :                     FOR( i = 9; i >= 0; i-- )
     779             :                     {
     780           0 :                         sum_word16 = add( sum_word16, st->hPlcInfo->TCX_Tonality[i] );
     781             :                     }
     782             : 
     783           0 :                     if ( GE_16( sum_word16, 6 ) )
     784             :                     {
     785           0 :                         st->hPlcInfo->concealment_method = TCX_TONAL;
     786           0 :                         move16();
     787             :                     }
     788             :                 }
     789             : 
     790           0 :                 if ( st->tonal_mdct_plc_active )
     791             :                 {
     792           0 :                     st->hPlcInfo->concealment_method = TCX_TONAL;
     793           0 :                     move16();
     794             :                 }
     795             :             }
     796             : 
     797           0 :             if ( GT_16( L_frameTCX, hTcxDec->L_frameTCX ) )
     798             :             {
     799           0 :                 st->hPlcInfo->concealment_method = TCX_TONAL;
     800           0 :                 move16();
     801             :             }
     802             : 
     803           0 :             temp_concealment_method = st->hPlcInfo->concealment_method;
     804           0 :             move16();
     805             : 
     806           0 :             if ( EQ_16( st->core, TCX_10_CORE ) )
     807             :             {
     808           0 :                 temp_concealment_method = TCX_TONAL;
     809           0 :                 move16();
     810             :             }
     811             :         }
     812             :         /* get the starting location of the subframe in the frame */
     813           0 :         IF( EQ_16( st->core, TCX_10_CORE ) )
     814             :         {
     815           0 :             st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) );
     816           0 :             move16();
     817             :         }
     818             :     }
     819             : 
     820             :     /* PLC: [TCX: Tonal Concealment] */
     821             :     /* PLC: [TCX: Fade-out]
     822             :      * PLC: Fade out to white noise */
     823             : 
     824         634 :     IF( bfi == 0 )
     825             :     {
     826         634 :         TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, x_e, L_frameTCX, L_frame, gainlpc2, gainlpc2_e, gain_tcx_e );
     827             :     }
     828             :     ELSE
     829             :     {
     830           0 :         test();
     831           0 :         IF( !st->enablePlcWaveadjust || EQ_16( temp_concealment_method, TCX_TONAL ) )
     832             :         {
     833             :             Word16 f, tmp;
     834             : 
     835             :             /* set f to 1 to not fade out */
     836             :             /* set f to 0 to immediately switch to white noise */
     837           0 :             f = hTcxDec->cummulative_damping_tcx;
     838           0 :             move16();
     839           0 :             if ( 0 != st->tcxonly )
     840             :             {
     841           0 :                 f = 32767 /*1.0f Q15*/;
     842           0 :                 move16();
     843             :             }
     844             : 
     845           0 :             test();
     846           0 :             test();
     847           0 :             test();
     848           0 :             test();
     849           0 :             test();
     850           0 :             test();
     851           0 :             IF( ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
     852             :             {
     853             :                 Word16 exp1, exp2;
     854             :                 Word32 E_2ndlast, E_last;
     855             : 
     856           0 :                 E_2ndlast = CalculateAbsEnergy_fx( 1, &( st->hTonalMDCTConc->lastBlockData.spectralData[0] ), infoIGFStartLine, &exp2 );
     857           0 :                 E_last = CalculateAbsEnergy_fx( 1, &( st->hTonalMDCTConc->lastBlockData.spectralData[1] ), infoIGFStartLine, &exp1 );
     858             : 
     859           0 :                 BASOP_Util_Divide_MantExp( extract_h( E_2ndlast ), exp2, extract_h( E_last ), exp1, &tmp1, &tmp2 );
     860             : 
     861           0 :                 tmp1 = shr( tmp1, 2 ); /*Q13*/
     862           0 :                 tmp1 = shl_sat( tmp1, tmp2 );
     863             :                 /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */
     864           0 :                 IF( GT_16( tmp1, 16384 /*2 in Q13*/ ) )
     865             :                 {
     866           0 :                     FOR( i = 0; i < infoIGFStartLine; i += 2 )
     867             :                     {
     868           0 :                         move32();
     869           0 :                         st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
     870             :                     }
     871             :                 }
     872           0 :                 ELSE IF( LT_16( tmp1, 4096 /*0.5 in Q13*/ ) )
     873             :                 {
     874           0 :                     FOR( i = 0; i < infoIGFStartLine; i += 2 )
     875             :                     {
     876           0 :                         move32();
     877           0 :                         st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i];
     878             :                     }
     879             :                 }
     880             :             }
     881             : 
     882           0 :             noiseTiltFactor = 32767 /*1.0f Q15*/;
     883           0 :             move16();
     884             : 
     885           0 :             tmp = 0;
     886           0 :             move16();
     887           0 :             test();
     888           0 :             if ( GE_16( st->bits_frame, 256 ) && st->rf_flag == 0 )
     889             :             {
     890           0 :                 tmp = 1;
     891           0 :                 move16();
     892             :             }
     893             : 
     894           0 :             tcxGetNoiseFillingTilt( A, M, L_frame, tmp, &noiseTiltFactor );
     895             : 
     896           0 :             TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, &x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc,
     897             :                                           noiseTiltFactor, f,
     898             :                                           infoIGFStartLine );
     899             :         }
     900             :     }
     901             : 
     902             : 
     903         634 :     IF( LT_16( L_spec, L_frame ) )
     904             :     {
     905           0 :         set32_fx( x + L_spec, 0, sub( L_frame, L_spec ) );
     906             :     }
     907         634 :     ELSE IF( GT_16( L_spec, L_frameTCX ) )
     908             :     {
     909           0 :         set32_fx( x + L_frameTCX, 0, sub( L_spec, L_frameTCX ) );
     910             :     }
     911             : 
     912         634 :     test();
     913         634 :     test();
     914         634 :     test();
     915         634 :     test();
     916         634 :     test();
     917         634 :     test();
     918         634 :     test();
     919         634 :     test();
     920         634 :     test();
     921         634 :     test();
     922         634 :     IF( bfi && ( !st->enablePlcWaveadjust || EQ_16( temp_concealment_method, TCX_TONAL ) ) && st->igf && ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
     923             :     {
     924           0 :         IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_SHORT );
     925           0 :         Copy( st->hIGFDec->igfData.igf_curr_subframe[0][0], st->hIGFDec->igfData.igf_curr_subframe[1][0], IGF_MAX_SFB );
     926             :     }
     927             : 
     928             :     /*-----------------------------------------------------------*
     929             :      * Noise shaping in frequency domain (1/Wz)                  *
     930             :      *-----------------------------------------------------------*/
     931         634 :     test();
     932         634 :     IF( st->igf && !bfi )
     933             :     {
     934         634 :         test();
     935         634 :         IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) )
     936             :         {
     937           0 :             IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_SHORT );
     938             :         }
     939             :         ELSE
     940             :         {
     941         634 :             IF( st->last_core == ACELP_CORE )
     942             :             {
     943          38 :                 IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_TRAN );
     944             :             }
     945             :             ELSE
     946             :             {
     947         596 :                 IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_NORM );
     948             :             }
     949             :         }
     950             :     }
     951             : 
     952             :     /* LPC gains already available */
     953         634 :     test();
     954         634 :     test();
     955         634 :     IF( !st->enablePlcWaveadjust || !bfi || ( EQ_16( temp_concealment_method, TCX_TONAL ) ) )
     956             :     {
     957         634 :         x_e = add( x_e, gain_tcx_e );
     958         634 :         mdct_shaping( x, L_frame, gainlpc2, gainlpc2_e );
     959         634 :         IF( bfi == 0 )
     960             :         {
     961      223562 :             FOR( i = L_frame; i < L_spec; i++ )
     962             :             {
     963      222928 :                 x[i] = L_shl( Mpy_32_16_1( x[i], gainlpc2[FDNS_NPTS - 1] ), gainlpc2_e[FDNS_NPTS - 1] );
     964      222928 :                 move32();
     965             :             }
     966             :         }
     967             : 
     968         634 :         set32_fx( x + L_spec, 0, sub( L_frameTCX, L_spec ) );
     969         634 :         test();
     970         634 :         test();
     971         634 :         IF( ( bfi != 0 ) && ( !st->enablePlcWaveadjust || EQ_16( temp_concealment_method, TCX_TONAL ) ) )
     972             :         {
     973           0 :             scale_sig32( x + infoIGFStartLine, sub( L_spec, infoIGFStartLine ), negate( gain_tcx_e ) );
     974             :         }
     975             :     }
     976             : 
     977             :     /* PLC: [TCX: Tonal Concealment] */
     978         634 :     test();
     979         634 :     IF( bfi && st->tonal_mdct_plc_active )
     980             :     {
     981           0 :         TonalMDCTConceal_Apply( st->hTonalMDCTConc, x, &x_e );
     982             :     }
     983             : 
     984         634 :     tmp32 = L_deposit_h( 0 );
     985         634 :     if ( hTcxDec->tcxltp_last_gain_unmodified > 0 )
     986             :     {
     987         452 :         tmp32 = L_add( st->old_fpitch, 0 );
     988             :     }
     989         634 :     tmp8 = 0;
     990         634 :     move16();
     991         634 :     test();
     992         634 :     if ( bfi && st->tonal_mdct_plc_active )
     993             :     {
     994           0 :         tmp8 = 1;
     995           0 :         move16();
     996             :     }
     997             : 
     998         634 :     TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, L_frameTCX, tmp32, bfi, tmp8 );
     999             : 
    1000         634 :     IF( st->enablePlcWaveadjust )
    1001             :     {
    1002             :         Word16 core;
    1003           0 :         core = st->core;
    1004           0 :         move16();
    1005             :         /* spectrum concealment */
    1006           0 :         IF( bfi && ( EQ_16( temp_concealment_method, TCX_NONTONAL ) ) )
    1007             :         {
    1008             :             /* x_e =31-x_scale; */
    1009           0 :             concealment_decode_fix( core, x, &x_e, st->hPlcInfo );
    1010             :         }
    1011             : 
    1012             :         /* update spectrum buffer, tonality flag, etc. */
    1013           0 :         concealment_update_x( bfi, core, st->tonality_flag, x, &x_e, st->hPlcInfo );
    1014             :     }
    1015             : 
    1016             :     /*-----------------------------------------------------------*
    1017             :      * IGF                                                       *
    1018             :      *-----------------------------------------------------------*/
    1019         634 :     test();
    1020         634 :     test();
    1021         634 :     IF( st->igf && !( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
    1022             :     {
    1023             :         Word16 igfGridIdx;
    1024             : 
    1025         634 :         test();
    1026         634 :         IF( ( EQ_16( st->last_core, ACELP_CORE ) ) || ( left_rect && bfi ) )
    1027             :         {
    1028             :             /* packet loss after first TCX must be handled like transition frame */
    1029          38 :             igfGridIdx = IGF_GRID_LB_TRAN;
    1030          38 :             move16();
    1031             :         }
    1032             :         ELSE
    1033             :         {
    1034         596 :             igfGridIdx = IGF_GRID_LB_NORM;
    1035         596 :             move16();
    1036             :         }
    1037             : 
    1038         634 :         *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l( L_mac0( 13849L, nf_seed, 31821 ) );
    1039         634 :         move16();
    1040         634 :         IGFDecApplyMono( st->hIGFDec, x, &x_e, igfGridIdx, bfi );
    1041             :     }
    1042         634 :     test();
    1043         634 :     test();
    1044         634 :     IF( st->igf && ( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
    1045             :     {
    1046           0 :         *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l( L_mac0( 13849L, nf_seed, 31821 ) );
    1047           0 :         move16();
    1048           0 :         IGFDecApplyMono( st->hIGFDec, x, &x_e, IGF_GRID_LB_SHORT, bfi );
    1049             :     }
    1050             : 
    1051         634 :     index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    1052         634 :     move16();
    1053             : 
    1054             :     /* normalize spectrum to minimize IMDCT_fx noise */
    1055         634 :     tmp1 = s_max( s_max( L_frame, L_frameTCX ), L_spec );
    1056         634 :     s = s_max( 0, sub( getScaleFactor32( x, tmp1 ), 4 ) ); /* Keep 4 bits headroom for TNS */
    1057         634 :     Scale_sig32( x, tmp1, s );
    1058         634 :     x_e = sub( x_e, s );
    1059             : 
    1060         634 :     IF( st->igf )
    1061             :     {
    1062         634 :         test();
    1063         634 :         IF( st->hIGFDec->flatteningTrigger != 0 && fUseTns == 0 )
    1064             :         {
    1065             :             Word16 startLine, endLine;
    1066         560 :             startLine = st->hIGFDec->infoIGFStartLine;
    1067         560 :             move16();
    1068         560 :             endLine = st->hIGFDec->infoIGFStopLine;
    1069         560 :             move16();
    1070             :             Word32 x_itf[N_MAX_TCX - IGF_START_MN];
    1071             :             Word16 j;
    1072             : 
    1073         560 :             const Word16 *chk_sparse = st->hIGFDec->flag_sparseBuf;
    1074         560 :             const Word32 *virtualSpec = st->hIGFDec->virtualSpec;
    1075             : 
    1076         560 :             const Word16 maxOrder = 8;
    1077         560 :             move16();
    1078             :             Word16 curr_order; /* not counted */
    1079         560 :             curr_order = 0;
    1080         560 :             move16();
    1081             :             Word16 A_itf[ITF_MAX_FILTER_ORDER + 1];
    1082             :             Word16 Q_A_itf;
    1083             :             Word16 predictionGain; /* not counted */
    1084         560 :             predictionGain = 0;
    1085         560 :             move16();
    1086             : 
    1087      202640 :             FOR( j = startLine; j < endLine; j++ )
    1088             :             {
    1089      202080 :                 IF( EQ_16( chk_sparse[j - IGF_START_MN], 2 ) )
    1090             :                 {
    1091          24 :                     x_itf[j - IGF_START_MN] = x[j];
    1092          24 :                     move32();
    1093          24 :                     x[j] = virtualSpec[j - IGF_START_MN];
    1094          24 :                     move32();
    1095             :                 }
    1096             :             }
    1097         560 :             ITF_Detect_fx( x + IGF_START_MN, startLine, endLine, maxOrder, A_itf, &Q_A_itf, &predictionGain, &curr_order, shl( x_e, 1 ) );
    1098         560 :             s = getScaleFactor32( &x[startLine], sub( endLine, startLine ) );
    1099         560 :             s = sub( s, 2 );
    1100      202640 :             FOR( j = startLine; j < endLine; j++ )
    1101             :             {
    1102      202080 :                 x[j] = L_shl( x[j], s );
    1103      202080 :                 move32();
    1104             :             }
    1105             : 
    1106         560 :             ITF_Apply_fx( x, startLine, endLine, A_itf, Q_A_itf, curr_order );
    1107             : 
    1108      202640 :             FOR( j = startLine; j < endLine; j++ )
    1109             :             {
    1110      202080 :                 x[j] = L_shr( x[j], s );
    1111      202080 :                 move32();
    1112             :             }
    1113             : 
    1114      202640 :             FOR( j = startLine; j < endLine; j++ )
    1115             :             {
    1116      202080 :                 IF( EQ_16( chk_sparse[j - IGF_START_MN], 2 ) )
    1117             :                 {
    1118          24 :                     x[j] = x_itf[j - IGF_START_MN];
    1119          24 :                     move32();
    1120             :                 }
    1121             :             }
    1122             :         }
    1123             :     }
    1124             : 
    1125         634 :     test();
    1126         634 :     IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    1127             :     {
    1128             :         Word16 L;
    1129           0 :         L = L_frameTCX;
    1130           0 :         move16();
    1131             : 
    1132           0 :         test();
    1133           0 :         test();
    1134           0 :         test();
    1135           0 :         if ( ( hTcxCfg->fIsTNSAllowed != 0 && fUseTns != 0 && bfi == 0 ) || ( GT_16( L_spec, L_frameTCX ) ) )
    1136             :         {
    1137           0 :             L = L_spec;
    1138           0 :             move16();
    1139             :         }
    1140             : 
    1141           0 :         tcxInvertWindowGrouping( hTcxCfg,
    1142             :                                  xn_buf32,
    1143             :                                  x,
    1144             :                                  L,
    1145             :                                  fUseTns,
    1146           0 :                                  st->last_core,
    1147             :                                  index,
    1148             :                                  frame_cnt,
    1149             :                                  bfi );
    1150             :     }
    1151             : 
    1152             : 
    1153             :     /*-----------------------------------------------------------*
    1154             :      * Temporal Noise Shaping Synthesis                          *
    1155             :      *-----------------------------------------------------------*/
    1156             : 
    1157         634 :     test();
    1158         634 :     test();
    1159         634 :     IF( ( hTcxCfg->fIsTNSAllowed != 0 ) && ( fUseTns != 0 ) && bfi == 0 )
    1160             :     {
    1161             :         /* Apply TNS to get the reconstructed signal */
    1162           4 :         test();
    1163           4 :         SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
    1164           4 :         ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, &tnsData, x, 0 );
    1165             : 
    1166           4 :         test();
    1167           4 :         IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    1168             :         {
    1169             : 
    1170           0 :             test();
    1171           0 :             test();
    1172           0 :             test();
    1173           0 :             IF( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
    1174             :                 ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) )
    1175             :             {
    1176           0 :                 tmp1 = shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 );
    1177             :                 /* undo rearrangement of LF sub-window lines for TNS synthesis filtering */
    1178           0 :                 IF( GT_16( s_max( L_frameTCX, L_spec ), hTcxCfg->tnsConfig[0][0].iFilterBorders[0] ) )
    1179             :                 {
    1180           0 :                     tmp2 = shr( s_max( L_frameTCX, L_spec ), 1 );
    1181           0 :                     Copy32( x + add( tmp1, 8 ), x + add( tmp2, 8 ), sub( tmp1, 8 ) );
    1182           0 :                     Copy32( x + 8, x + tmp2, 8 );
    1183           0 :                     Copy32( x + 16, x + 8, sub( tmp1, 8 ) );
    1184           0 :                     set32_fx( x + tmp1, 0, sub( tmp2, tmp1 ) );
    1185           0 :                     set32_fx( x + add( tmp2, tmp1 ), 0, sub( tmp2, tmp1 ) );
    1186             :                 }
    1187             :                 ELSE
    1188             :                 {
    1189           0 :                     Copy32( x + 8, xn_buf32, 8 );
    1190           0 :                     Copy32( x + 16, x + 8, sub( tmp1, 8 ) );
    1191           0 :                     Copy32( xn_buf32, x + tmp1, 8 );
    1192             :                 }
    1193             :             }
    1194             :         }
    1195             :     }
    1196             : 
    1197             : 
    1198             :     /*-----------------------------------------------------------*
    1199             :      * Compute inverse MDCT of x[].                              *
    1200             :      *-----------------------------------------------------------*/
    1201             : 
    1202             : 
    1203         634 :     Copy32( x, xn_buf32, s_max( s_max( L_frame, L_frameTCX ), L_spec ) );
    1204             : 
    1205         634 :     IF( st->igf != 0 )
    1206             :     {
    1207         634 :         set32_fx( xn_buf32 + st->hIGFDec->infoIGFStartLine, 0, sub( L_frameTCX, st->hIGFDec->infoIGFStartLine ) );
    1208             :     }
    1209        1268 :     IMDCT_fx( xn_buf32, x_e, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2,
    1210         634 :               st->hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_trans, st->hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length,
    1211         634 :               index, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx,
    1212         634 :               &st->hHQ_core->Q_old_wtda_LB, st, 0, acelp_zir );
    1213             :     /* Generate additional comfort noise to mask potential coding artefacts */
    1214         634 :     IF( st->flag_cna != 0 )
    1215             :     {
    1216         262 :         generate_masking_noise_mdct_fx( x, &x_e, st->hFdCngDec->hFdCngCom, s_max( s_max( L_frame, L_frameTCX ), L_spec ) );
    1217             :     }
    1218             : 
    1219        1268 :     IMDCT_fx( x, x_e, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB,
    1220         634 :               hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB,
    1221         634 :               index, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob,
    1222         634 :               frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, st, div_l( L_mult( FSCALE_DENOM, L_frameTCX_glob ), L_frame_glob ), acelp_zir );
    1223             : 
    1224             :     /* PLC: [TCX: Tonal Concealment] */
    1225             : 
    1226         634 :     IF( !bfi )
    1227             :     {
    1228         634 :         st->second_last_tns_active = st->last_tns_active;
    1229         634 :         move16();
    1230         634 :         st->last_tns_active = 0;
    1231         634 :         move16();
    1232         634 :         test();
    1233         634 :         if ( hTcxCfg->fIsTNSAllowed && fUseTns )
    1234             :         {
    1235           4 :             st->last_tns_active = 1;
    1236           4 :             move16();
    1237             :         }
    1238             : 
    1239         634 :         hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch;
    1240         634 :         move32();
    1241         634 :         hTcxDec->tcxltp_second_last_pitch = st->old_fpitch;
    1242         634 :         move32();
    1243         634 :         st->old_fpitch = L_add( L_deposit_h( hTcxLtpDec->tcxltp_pitch_int ), L_mult( hTcxLtpDec->tcxltp_pitch_fr, div_s( 1, st->pit_res_max ) /*Q16*/ ) );
    1244         634 :         move32();
    1245         634 :         st->old_fpitchFB = Mpy_32_16_1( st->old_fpitch /*Q16*/, mult_r( L_frameTCX /*Q0*/, getInvFrameLen( L_frame ) /*Q21*/ ) /*Q6*/ ) /*Q7*/;
    1246         634 :         move32();
    1247         634 :         st->old_fpitchFB = L_shr( st->old_fpitchFB, 7 - 16 ); /*->Q16*/
    1248         634 :         move32();
    1249             :     }
    1250             : 
    1251             : 
    1252             :     /* Update old_syn_overl */
    1253         634 :     IF( st->hTcxCfg->last_aldo == 0 )
    1254             :     {
    1255           0 :         Copy( xn_buf + L_frame, hTcxDec->syn_Overl, overlap );
    1256           0 :         Copy( xn_bufFB + L_frameTCX, hTcxDec->syn_OverlFB, overlapFB );
    1257             :     }
    1258             : 
    1259             :     /* Output */
    1260         634 :     Copy( xn_buf + sub( shr( overlap, 1 ), tcx_offset ), synth, L_frame_glob );
    1261         634 :     Copy( xn_bufFB + sub( shr( overlapFB, 1 ), tcx_offsetFB ), synthFB, L_frameTCX_glob );
    1262         634 : }
    1263             : 
    1264             : 
    1265         634 : void decoder_tcx_post_fx( Decoder_State *st_fx,
    1266             :                           Word16 *synth,
    1267             :                           Word16 *synthFB,
    1268             :                           Word16 *A,
    1269             :                           Word16 bfi )
    1270             : {
    1271             :     Word16 i;
    1272             :     Word16 level_syn;
    1273             :     Word16 level_syn_e;
    1274             :     Word32 step;
    1275             :     Word16 gainCNG, gainCNG_e;
    1276             :     Word16 xn_buf[L_FRAME_MAX];
    1277             :     Word16 tmp1, tmp2, s;
    1278             :     Word32 tmp32;
    1279             :     Word32 tmp32_1, tmp32_2;
    1280             :     TCX_DEC_HANDLE hTcxDec;
    1281             : 
    1282         634 :     hTcxDec = st_fx->hTcxDec;
    1283             : 
    1284             :     /* TCX output */
    1285         634 :     Copy( synth, xn_buf, st_fx->L_frame );
    1286             : 
    1287             :     /* first TCX frame after ACELP; overwrite ltp initialization done during acelp PLC */
    1288         634 :     test();
    1289         634 :     test();
    1290         634 :     if ( !st_fx->bfi && st_fx->prev_bfi && st_fx->last_core == ACELP_CORE )
    1291             :     {
    1292           0 :         hTcxDec->tcxltp_last_gain_unmodified = 0;
    1293           0 :         move16();
    1294             :     }
    1295         634 :     test();
    1296         634 :     IF( bfi != 0 && st_fx->use_partial_copy == 0 )
    1297             :     {
    1298           0 :         test();
    1299             :         /* run lpc gain compensation not for waveform adjustment */
    1300           0 :         IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) )
    1301             :         {
    1302             :             UWord32 dmy;
    1303           0 :             tmp32_1 /*gainHelperFB*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) );             /*Q28*/
    1304           0 :             tmp32_2 /*stepCompensateFB*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
    1305             : 
    1306           0 :             Mpy_32_32_ss( tmp32_2 /*Q28*/,
    1307           0 :                           L_shl( L_mult0( st_fx->L_frame,
    1308           0 :                                           getInvFrameLen( hTcxDec->L_frameTCX ) /*Q21*/ ) /*Q21*/,
    1309             :                                  8 ) /*Q29*/,
    1310             :                           &tmp32_2,
    1311             :                           &dmy ); /*Q26*/
    1312             : 
    1313           0 :             tmp32_2 = L_shl( tmp32_2, 3 - 1 ); /*Q28*/
    1314             : 
    1315           0 :             FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
    1316             :             {
    1317           0 :                 tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
    1318           0 :                 synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) );
    1319           0 :                 move16();
    1320           0 :                 tmp32_1 = L_sub( tmp32_1, tmp32_2 );
    1321             :             }
    1322             :         }
    1323           0 :         tmp32_1 /*gainHelper*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) );             /*Q28*/
    1324           0 :         tmp32_2 /*stepCompensate*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
    1325           0 :         FOR( i = 0; i < st_fx->L_frame; i++ )
    1326             :         {
    1327           0 :             tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
    1328           0 :             xn_buf[i] = extract_l( Mpy_32_16_1( tmp32, xn_buf[i] ) );
    1329           0 :             move16();
    1330           0 :             tmp32_1 = L_sub( tmp32_1, tmp32_2 );
    1331             :         }
    1332             :     }
    1333             : 
    1334             :     /* PLC: [TCX: Fade-out]
    1335             :      * PLC: estimate and update CNG energy */
    1336             : 
    1337             :     /* level_syn = (float)sqrt(( dot_product(synthFB, synthFB, L_frame)) / L_frame ); */
    1338         634 :     s = sub( getScaleFactor16( synthFB, hTcxDec->L_frameTCX ), 4 );
    1339             :     {
    1340             :         Word64 tmp64;
    1341         634 :         tmp64 = 0;
    1342         634 :         move64();
    1343      525434 :         FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
    1344             :         {
    1345      524800 :             tmp1 = shl( synthFB[i], s );
    1346      524800 :             tmp64 = W_mac0_16_16( tmp64, tmp1, tmp1 );
    1347             :         }
    1348         634 :         tmp32 = W_sat_l( tmp64 );
    1349             :     }
    1350         634 :     tmp32 = Mpy_32_16_1( tmp32, getInvFrameLen( hTcxDec->L_frameTCX ) );
    1351         634 :     tmp2 = norm_l( tmp32 );
    1352         634 :     tmp1 = round_fx_sat( L_shl( tmp32, tmp2 ) );
    1353         634 :     s = sub( sub( sub( 1, shl( s, 1 ) ), 6 /*table lookup for inverse framelength*/ ), tmp2 );
    1354         634 :     tmp1 = Sqrt16( tmp1, &s );
    1355         634 :     move16();
    1356         634 :     level_syn = tmp1; /*Q0*/
    1357             : 
    1358             :     /* PLC: [TCX: Fade-out]
    1359             :      * PLC: estimate and update CNG energy */
    1360             : 
    1361         634 :     level_syn_e = add( s, 15 );
    1362         634 :     test();
    1363         634 :     test();
    1364         634 :     IF( bfi == 0 && st_fx->tcxonly != 0 && EQ_16( st_fx->clas_dec, UNVOICED_CLAS ) )
    1365             :     {
    1366             : 
    1367             :         Word16 Qnew_levelBackgroundTrace;
    1368           0 :         Qnew_levelBackgroundTrace = 0;
    1369           0 :         move16();
    1370           0 :         minimumStatistics_fx( hTcxDec->conNoiseLevelMemory,         /*Q15*/
    1371             :                               &hTcxDec->conNoiseLevelIndex,         /*Q0 */
    1372             :                               &hTcxDec->conCurrLevelIndex,          /*Q0 */
    1373             :                               &hTcxDec->conCngLevelBackgroundTrace, /*Q15*/
    1374             :                               &hTcxDec->conLastFrameLevel,          /*Q15*/
    1375             :                               level_syn,                            /*Q15*/
    1376           0 :                               hTcxDec->conNoiseLevelMemory_e,
    1377           0 :                               hTcxDec->conCngLevelBackgroundTrace_e,
    1378             :                               &Qnew_levelBackgroundTrace,
    1379             :                               &hTcxDec->conLastFrameLevel_e,
    1380             :                               level_syn_e /*scaling of level_syn*/
    1381             :         );
    1382             : 
    1383             :         /*note: All parameters being different from Q0 have to have the same Q-format*/
    1384             : 
    1385           0 :         hTcxDec->conCngLevelBackgroundTrace_e = Qnew_levelBackgroundTrace;
    1386           0 :         move16();
    1387             :     }
    1388             : 
    1389             :     /* PLC: [TCX: Fade-out]
    1390             :      * PLC: fade-out in time domain */
    1391         634 :     IF( bfi != 0 )
    1392             :     {
    1393             :         Word32 conceal_eof_gain32;
    1394             :         Word32 conceal_eof_gainFB;
    1395           0 :         move16();
    1396           0 :         move16();
    1397           0 :         gainCNG = 1;
    1398           0 :         gainCNG_e = 14 + 15 + 6; /*gainCNG is 2`097`152 - should be enough in case tracinglevel =~0 */
    1399           0 :         IF( st_fx->tcxonly != 0 )
    1400             :         {
    1401             :             /*gainCNG = st_fx->conCngLevelBackgroundTrace/(tracingLevel+0.01f);*/
    1402             : 
    1403           0 :             IF( level_syn != 0 )
    1404             :             {
    1405           0 :                 BASOP_Util_Divide_MantExp(
    1406           0 :                     hTcxDec->conCngLevelBackgroundTrace,
    1407           0 :                     hTcxDec->conCngLevelBackgroundTrace_e,
    1408             :                     level_syn,
    1409             :                     level_syn_e,
    1410             :                     &gainCNG,
    1411             :                     &gainCNG_e );
    1412             :             }
    1413             :         }
    1414             :         ELSE
    1415             :         {
    1416             :             /*gainCNG = st_fx->cngTDLevel/(tracingLevel+0.01f);*/
    1417           0 :             IF( level_syn != 0 )
    1418             :             {
    1419           0 :                 BASOP_Util_Divide_MantExp(
    1420           0 :                     st_fx->cngTDLevel,
    1421           0 :                     st_fx->cngTDLevel_e,
    1422             :                     level_syn,
    1423             :                     level_syn_e,
    1424             :                     &gainCNG,
    1425             :                     &gainCNG_e );
    1426             :             }
    1427             :         }
    1428             : 
    1429           0 :         if ( ( EQ_16( st_fx->nbLostCmpt, 1 ) ) )
    1430             :         {
    1431           0 :             hTcxDec->conceal_eof_gain = 16384 /*1.0f Q14*/; /*Q14*/
    1432           0 :             move16();
    1433             :         }
    1434             : 
    1435             :         /* step = (st_fx->conceal_eof_gain - ( st_fx->conceal_eof_gain * st_fx->damping + gainCNG * (1 - st_fx->damping) )) / st_fx->L_frame; */
    1436           0 :         tmp2 = BASOP_Util_Add_MantExp(
    1437           0 :             mult_r( hTcxDec->conceal_eof_gain /*Q14*/,
    1438           0 :                     hTcxDec->damping /*Q14*/ ),
    1439             :             15 - 13 /*->Q15*/,
    1440           0 :             mult_r( gainCNG /*Q15*/, sub( 0x4000, hTcxDec->damping /*Q14*/ ) ) /*Q14*/,
    1441           0 :             add( gainCNG_e, 15 - 14 ) /*->Q15*/,
    1442             :             &tmp1 );
    1443           0 :         tmp2 = BASOP_Util_Add_MantExp( hTcxDec->conceal_eof_gain, 15 - 14, negate( tmp1 ), tmp2, &tmp1 );
    1444             : 
    1445           0 :         step = L_shl_sat( L_mult( tmp1, getInvFrameLen( st_fx->L_frame ) ), sub( tmp2, 6 /*scaling from table lookup*/ + 1 /*go to Q30*/ ) ); /*Q30*/
    1446             :         {
    1447             :             Word32 stepFB;
    1448             :             UWord32 dmy;
    1449           0 :             conceal_eof_gainFB = L_deposit_h( hTcxDec->conceal_eof_gain ); /*Q30*/
    1450           0 :             Mpy_32_32_ss( step, L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ), &stepFB, &dmy );
    1451           0 :             stepFB = L_shl_sat( stepFB, 3 - 1 ); /*Q30*/
    1452           0 :             FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
    1453             :             {
    1454           0 :                 synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, synthFB[i] ), 1 ) );
    1455           0 :                 move16();
    1456           0 :                 conceal_eof_gainFB = L_sub_sat( conceal_eof_gainFB, stepFB );
    1457             :             }
    1458             :         }
    1459           0 :         conceal_eof_gain32 = L_deposit_h( hTcxDec->conceal_eof_gain ); /*Q30*/
    1460           0 :         FOR( i = 0; i < st_fx->L_frame; i++ )
    1461             :         {
    1462           0 :             xn_buf[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gain32 /*Q30*/, xn_buf[i] ), 1 ) );
    1463           0 :             move16();
    1464           0 :             conceal_eof_gain32 = L_sub_sat( conceal_eof_gain32, step );
    1465             :         }
    1466           0 :         hTcxDec->conceal_eof_gain = round_fx_sat( conceal_eof_gain32 ); /*Q14*/
    1467           0 :         move16();
    1468             :         /* run lpc gain compensation not for waveform adjustment */
    1469           0 :         test();
    1470           0 :         IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) )
    1471             :         {
    1472           0 :             st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB,
    1473           0 :                                                                                 st_fx->last_concealed_gain_syn_deemph ),
    1474           0 :                                                                    st_fx->last_concealed_gain_syn_deemph_e ) );
    1475             :             /*Q30->Q14*/
    1476           0 :             move16();
    1477             :         }
    1478             :         ELSE
    1479             :         {
    1480           0 :             st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/
    1481           0 :             move16();
    1482             :         }
    1483           0 :         st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( step ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 3 ) ); /*Q15*/
    1484           0 :         move16();
    1485             :     }
    1486             : 
    1487             :     /*-----------------------------------------------------------*
    1488             :      * Memory update                                             *
    1489             :      *-----------------------------------------------------------*/
    1490             : 
    1491             :     /* Update synth, exc and old_Aq  */
    1492         634 :     tcx_decoder_memory_update( xn_buf, /*Q0*/
    1493             :                                synth,  /*Q0*/
    1494             :                                A,
    1495             :                                st_fx,
    1496             :                                0 );
    1497             : 
    1498             : 
    1499             :     /* PLC: [TCX: Memory update] */
    1500             : 
    1501         634 :     st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr];
    1502         634 :     move32();
    1503         634 :     st_fx->old_pitch_buf_fx[1] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 1];
    1504         634 :     move32();
    1505         634 :     Copy32( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr );
    1506         634 :     set32_fx( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], st_fx->old_fpitch, st_fx->nb_subfr );
    1507         634 :     st_fx->bfi_pitch_fx = shl_sat( round_fx( st_fx->old_fpitch ), 6 );
    1508         634 :     move16();
    1509         634 :     st_fx->bfi_pitch_frame = st_fx->L_frame;
    1510         634 :     move16();
    1511             : 
    1512         634 :     st_fx->mem_pitch_gain[add( shl( st_fx->nb_subfr, 1 ), 1 )] = st_fx->mem_pitch_gain[st_fx->nb_subfr + 1];
    1513         634 :     move16();
    1514         634 :     st_fx->mem_pitch_gain[st_fx->nb_subfr * 2] = st_fx->mem_pitch_gain[st_fx->nb_subfr];
    1515         634 :     move16();
    1516             : 
    1517        3542 :     FOR( i = 0; i < st_fx->nb_subfr; i++ )
    1518             :     {
    1519        2908 :         st_fx->mem_pitch_gain[sub( sub( shl( st_fx->nb_subfr, 1 ), 1 ), i )] = st_fx->mem_pitch_gain[sub( sub( st_fx->nb_subfr, 1 ), i )];
    1520        2908 :         move16();
    1521        2908 :         st_fx->mem_pitch_gain[sub( sub( st_fx->nb_subfr, 1 ), i )] = hTcxDec->tcxltp_last_gain_unmodified;
    1522        2908 :         move16();
    1523             :     }
    1524         634 : }
    1525             : 
    1526      904001 : void decoder_tcx_post_ivas_fx( Decoder_State *st_fx,
    1527             :                                Word16 *synth,   // Q_syn
    1528             :                                Word16 *synthFB, // Q_syn
    1529             :                                Word16 Q_syn,
    1530             :                                Word16 *A, // Q: 14 - norm_s(A[0])
    1531             :                                Word16 bfi,
    1532             :                                Word16 MCT_flag )
    1533             : {
    1534             :     Word16 i;
    1535             :     Word16 level_syn;
    1536             :     Word16 level_syn_e;
    1537             :     Word32 step;
    1538             :     Word16 step_e;
    1539             :     Word16 gainCNG, gainCNG_e;
    1540             :     Word16 xn_buf[L_FRAME_MAX];
    1541             :     Word16 tmp1, tmp2, s;
    1542             :     Word32 tmp32;
    1543             :     Word32 tmp32_1, tmp32_2;
    1544             :     TCX_DEC_HANDLE hTcxDec;
    1545             : 
    1546      904001 :     hTcxDec = st_fx->hTcxDec;
    1547             : 
    1548             :     /* TCX output */
    1549      904001 :     Copy( synth, xn_buf, st_fx->L_frame );
    1550             : 
    1551             :     /* first TCX frame after ACELP; overwrite ltp initialization done during acelp PLC */
    1552      904001 :     test();
    1553      904001 :     test();
    1554      904001 :     if ( !st_fx->bfi && st_fx->prev_bfi && EQ_16( st_fx->last_core, ACELP_CORE ) )
    1555             :     {
    1556         108 :         hTcxDec->tcxltp_last_gain_unmodified = 0;
    1557         108 :         move16();
    1558             :     }
    1559      904001 :     test();
    1560      904001 :     test();
    1561      904001 :     test();
    1562      904001 :     IF( st_fx->hTcxLtpDec != NULL && st_fx->element_mode > EVS_MONO && ( EQ_16( st_fx->clas_dec, UNVOICED_CLAS ) || EQ_16( st_fx->clas_dec, INACTIVE_CLAS ) ) )
    1563             :     {
    1564             :         /* deactivate TCX LTP for non-voiced frames */
    1565      478157 :         st_fx->hTcxLtpDec->tcxltp = 0;
    1566      478157 :         move16();
    1567      478157 :         st_fx->hTcxLtpDec->tcxltp_gain = 0;
    1568      478157 :         move16();
    1569             :     }
    1570      904001 :     test();
    1571      904001 :     IF( bfi != 0 && st_fx->use_partial_copy == 0 )
    1572             :     {
    1573        9641 :         test();
    1574        9641 :         test();
    1575             :         /* run lpc gain compensation not for waveform adjustment */
    1576        9641 :         IF( 0 == st_fx->enablePlcWaveadjust || ( st_fx->hPlcInfo != NULL && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) )
    1577             :         {
    1578             :             UWord32 dmy;
    1579        9641 :             tmp32_1 /*gainHelperFB*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) );             /*Q28*/
    1580        9641 :             tmp32_2 /*stepCompensateFB*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
    1581             : 
    1582        9641 :             Mpy_32_32_ss( tmp32_2 /*Q28*/,
    1583        9641 :                           L_shl( L_mult0( st_fx->L_frame,
    1584        9641 :                                           getInvFrameLen( hTcxDec->L_frameTCX ) /*Q21*/ ) /*Q21*/,
    1585             :                                  8 ) /*Q29*/,
    1586             :                           &tmp32_2,
    1587             :                           &dmy ); /*Q26*/
    1588             : 
    1589        9641 :             tmp32_2 = L_shl( tmp32_2, 3 - 1 ); /*Q28*/
    1590             : 
    1591     6791401 :             FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
    1592             :             {
    1593     6781760 :                 tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) );                                 /*16Q15*/
    1594     6781760 :                 synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) ); // Q_syn
    1595     6781760 :                 move16();
    1596     6781760 :                 tmp32_1 = L_sub( tmp32_1, tmp32_2 );
    1597             :             }
    1598             :         }
    1599        9641 :         tmp32_1 /*gainHelper*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) );             /*Q28*/
    1600        9641 :         tmp32_2 /*stepCompensate*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
    1601     4609577 :         FOR( i = 0; i < st_fx->L_frame; i++ )
    1602             :         {
    1603     4599936 :             tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) );                            /*16Q15*/
    1604     4599936 :             xn_buf[i] = extract_h( L_shl_sat( Mpy_32_16_1( tmp32, xn_buf[i] ), 16 ) ); // Q_syn
    1605     4599936 :             move16();
    1606     4599936 :             tmp32_1 = L_sub( tmp32_1, tmp32_2 );
    1607             :         }
    1608             :     }
    1609             : 
    1610             :     /* PLC: [TCX: Fade-out]
    1611             :      * PLC: estimate and update CNG energy */
    1612             : 
    1613             :     /* level_syn = (float)sqrt(( dot_product(synthFB, synthFB, L_frame)) / L_frame ); */
    1614      904001 :     s = sub( getScaleFactor16( synthFB, hTcxDec->L_frameTCX ), 4 );
    1615             :     {
    1616      904001 :         Word64 tmp64 = 0;
    1617      904001 :         move64();
    1618   757379201 :         FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
    1619             :         {
    1620   756475200 :             tmp1 = shl( synthFB[i], s );
    1621   756475200 :             tmp64 = W_mac0_16_16( tmp64, tmp1, tmp1 );
    1622             :         }
    1623      904001 :         tmp32 = W_sat_l( tmp64 );
    1624             :     }
    1625      904001 :     tmp32 = Mpy_32_16_1( tmp32, getInvFrameLen( hTcxDec->L_frameTCX ) );
    1626      904001 :     tmp2 = norm_l( tmp32 );
    1627      904001 :     tmp1 = round_fx_sat( L_shl( tmp32, tmp2 ) );
    1628             :     // s = sub(sub(sub(1, shl(s, 1)), 6/*table lookup for inverse framelength*/), tmp2);
    1629      904001 :     s = sub( 25, add( shl( add( Q_syn, s ), 1 ), tmp2 ) );
    1630      904001 :     tmp1 = Sqrt16( tmp1, &s );
    1631      904001 :     move16();
    1632      904001 :     level_syn = tmp1; /*Q0*/
    1633             : 
    1634             :     /* PLC: [TCX: Fade-out]
    1635             :      * PLC: estimate and update CNG energy */
    1636             : 
    1637      904001 :     level_syn_e = s; // add(s, 15);
    1638      904001 :     move16();
    1639      904001 :     test();
    1640      904001 :     test();
    1641      904001 :     test();
    1642      904001 :     test();
    1643      904001 :     IF( bfi == 0 && st_fx->tcxonly != 0 && ( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) || MCT_flag ) && EQ_16( st_fx->clas_dec, UNVOICED_CLAS ) )
    1644             :     {
    1645             : 
    1646             :         Word16 Qnew_levelBackgroundTrace;
    1647      352010 :         Qnew_levelBackgroundTrace = 0;
    1648      352010 :         move16();
    1649      352010 :         minimumStatistics_fx( hTcxDec->conNoiseLevelMemory,         /*Q15*/
    1650             :                               &hTcxDec->NoiseLevelIndex_bfi,        /*Q0 */
    1651             :                               &hTcxDec->CurrLevelIndex_bfi,         /*Q0 */
    1652             :                               &hTcxDec->conCngLevelBackgroundTrace, /*Q15*/
    1653             :                               &hTcxDec->conLastFrameLevel,          /*Q15*/
    1654             :                               level_syn,                            /*Q15*/
    1655      352010 :                               hTcxDec->conNoiseLevelMemory_e,
    1656      352010 :                               hTcxDec->conCngLevelBackgroundTrace_e,
    1657             :                               &Qnew_levelBackgroundTrace,
    1658             :                               &hTcxDec->conLastFrameLevel_e,
    1659             :                               level_syn_e /*scaling of level_syn*/
    1660             :         );
    1661             : 
    1662             :         /*note: All parameters being different from Q0 have to have the same Q-format*/
    1663             : 
    1664      352010 :         hTcxDec->conCngLevelBackgroundTrace_e = Qnew_levelBackgroundTrace;
    1665      352010 :         move16();
    1666             :     }
    1667             : 
    1668             :     /* PLC: [TCX: Fade-out]
    1669             :      * PLC: fade-out in time domain */
    1670      904001 :     IF( bfi != 0 )
    1671             :     {
    1672             :         Word32 conceal_eof_gainFB;
    1673             :         Word16 conceal_eof_gainFB_e;
    1674        9641 :         move16();
    1675        9641 :         move16();
    1676        9641 :         gainCNG = 1;
    1677        9641 :         gainCNG_e = 14 + 15 + 6; /*gainCNG is 2`097`152 - should be enough in case tracinglevel =~0 */
    1678        9641 :         IF( st_fx->tcxonly != 0 )
    1679             :         {
    1680             :             /*gainCNG = st_fx->conCngLevelBackgroundTrace/(tracingLevel+0.01f);*/
    1681        8502 :             IF( level_syn )
    1682             :             {
    1683        7161 :                 level_syn_e = BASOP_Util_Add_MantExp( level_syn, level_syn_e, 20992, -6, &level_syn ); /* 0.01 in Q21*/
    1684             :             }
    1685             :             ELSE
    1686             :             {
    1687        1341 :                 level_syn = 328; /* (1 / 0.01) in Q15 */
    1688        1341 :                 level_syn_e = 0;
    1689        1341 :                 move16();
    1690        1341 :                 move16();
    1691             :             }
    1692             : 
    1693        8502 :             IF( level_syn != 0 )
    1694             :             {
    1695        8502 :                 BASOP_Util_Divide_MantExp(
    1696        8502 :                     hTcxDec->conCngLevelBackgroundTrace,
    1697        8502 :                     hTcxDec->conCngLevelBackgroundTrace_e,
    1698             :                     level_syn,
    1699             :                     level_syn_e,
    1700             :                     &gainCNG,
    1701             :                     &gainCNG_e );
    1702             :             }
    1703        8502 :             test();
    1704        8502 :             IF( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && !MCT_flag )
    1705             :             {
    1706        3176 :                 IF( GT_16( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) )
    1707             :                 {
    1708           0 :                     gainCNG = 0;
    1709           0 :                     move16();
    1710             :                 }
    1711        3176 :                 ELSE IF( GT_16( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) )
    1712             :                 {
    1713             :                     // gainCNG *= 1.f - (float) sub( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN;
    1714           0 :                     tmp32 = L_sub( ONE_IN_Q31, imult3216( 107374182 /* 1 / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN in Q31*/, sub( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) ) ); /* Q31 */
    1715           0 :                     gainCNG = extract_l( Mpy_32_32( gainCNG, tmp32 ) );
    1716             :                 }
    1717             :             }
    1718             :         }
    1719             :         ELSE
    1720             :         {
    1721             :             /*gainCNG = st_fx->cngTDLevel/(tracingLevel+0.01f);*/
    1722        1139 :             IF( level_syn )
    1723             :             {
    1724        1139 :                 level_syn_e = BASOP_Util_Add_MantExp( level_syn, level_syn_e, 20992, -6, &level_syn ); /* 0.01 in Q21*/
    1725             :             }
    1726             :             ELSE
    1727             :             {
    1728           0 :                 level_syn = 328; /* (1 / 0.01) in Q15 */
    1729           0 :                 level_syn_e = 0;
    1730           0 :                 move16();
    1731           0 :                 move16();
    1732             :             }
    1733             : 
    1734        1139 :             IF( level_syn != 0 )
    1735             :             {
    1736        1139 :                 BASOP_Util_Divide_MantExp(
    1737        1139 :                     st_fx->cngTDLevel,
    1738        1139 :                     st_fx->cngTDLevel_e,
    1739             :                     level_syn,
    1740             :                     level_syn_e,
    1741             :                     &gainCNG,
    1742             :                     &gainCNG_e );
    1743             :             }
    1744             :         }
    1745             : 
    1746        9641 :         IF( ( EQ_16( st_fx->nbLostCmpt, 1 ) ) )
    1747             :         {
    1748        5409 :             hTcxDec->conceal_eof_gain32 = ONE_IN_Q30 /*1.0f Q30*/;
    1749        5409 :             move32();
    1750        5409 :             hTcxDec->conceal_eof_gain_e = 1;
    1751        5409 :             move16();
    1752             :         }
    1753             : 
    1754             :         /* step = (st_fx->conceal_eof_gain - ( st_fx->conceal_eof_gain * st_fx->damping + gainCNG * (1 - st_fx->damping) )) / st_fx->L_frame; */
    1755       19282 :         Word32 L_tmp = BASOP_Util_Add_Mant32Exp(
    1756             :             Mpy_32_16_1( hTcxDec->conceal_eof_gain32,
    1757        9641 :                          hTcxDec->damping /*Q14*/ ),
    1758        9641 :             add( 1, hTcxDec->conceal_eof_gain_e ) /*->Q15*/,
    1759        9641 :             L_mult( gainCNG /*Q15*/, sub( 0x4000, hTcxDec->damping /*Q14*/ ) ) /*Q14*/,
    1760        9641 :             add( gainCNG_e, 15 - 14 ) /*->Q15*/,
    1761             :             &tmp2 );
    1762             : 
    1763        9641 :         L_tmp = BASOP_Util_Add_Mant32Exp( hTcxDec->conceal_eof_gain32, hTcxDec->conceal_eof_gain_e, L_negate( L_tmp ), tmp2, &tmp2 );
    1764        9641 :         step = Mpy_32_16_1( L_tmp, getInvFrameLen( st_fx->L_frame ) );
    1765        9641 :         step_e = sub( tmp2, 6 );
    1766             :         {
    1767             :             Word32 stepFB;
    1768             :             Word16 stepFB_e;
    1769             :             UWord32 dmy;
    1770             :             Word16 tmp_shift;
    1771        9641 :             conceal_eof_gainFB = hTcxDec->conceal_eof_gain32;
    1772        9641 :             conceal_eof_gainFB_e = hTcxDec->conceal_eof_gain_e;
    1773        9641 :             move32();
    1774        9641 :             move16();
    1775        9641 :             Mpy_32_32_ss( step, L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ), &stepFB, &dmy );
    1776        9641 :             stepFB_e = add( step_e, 2 );
    1777             : 
    1778     6791401 :             FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
    1779             :             {
    1780     6781760 :                 tmp_shift = conceal_eof_gainFB_e;
    1781     6781760 :                 synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, synthFB[i] ), tmp_shift ) ); // Q_syn
    1782     6781760 :                 move16();
    1783     6781760 :                 conceal_eof_gainFB = BASOP_Util_Add_Mant32Exp( conceal_eof_gainFB, conceal_eof_gainFB_e, L_negate( stepFB ), stepFB_e, &conceal_eof_gainFB_e ); // Q: 31 - conceal_eof_gainFB_e
    1784             :             }
    1785             :         }
    1786     4609577 :         FOR( i = 0; i < st_fx->L_frame; i++ )
    1787             :         {
    1788     4599936 :             xn_buf[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( hTcxDec->conceal_eof_gain32, xn_buf[i] ), hTcxDec->conceal_eof_gain_e ) ); // Qx
    1789     4599936 :             move16();
    1790     4599936 :             hTcxDec->conceal_eof_gain32 = BASOP_Util_Add_Mant32Exp( hTcxDec->conceal_eof_gain32, hTcxDec->conceal_eof_gain_e, L_negate( step ), step_e, &hTcxDec->conceal_eof_gain_e );
    1791     4599936 :             move32();
    1792             :         }
    1793             : 
    1794             :         /* run lpc gain compensation not for waveform adjustment */
    1795        9641 :         IF( st_fx->hPlcInfo != NULL )
    1796             :         {
    1797           0 :             test();
    1798           0 :             IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) )
    1799             :             {
    1800           0 :                 st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e ) ); /*Q30->Q14*/
    1801           0 :                 move16();
    1802             :             }
    1803             :             ELSE
    1804             :             {
    1805           0 :                 st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/
    1806           0 :                 move16();
    1807             :             }
    1808           0 :             st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( L_shr_sat( step, sub( 1, step_e ) ) ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 4 ) ); /*Q15*/
    1809           0 :             move16();
    1810             :         }
    1811             :     }
    1812             : 
    1813             :     /*-----------------------------------------------------------*
    1814             :      * Memory update                                             *
    1815             :      *-----------------------------------------------------------*/
    1816             : 
    1817             :     /* Update synth, exc and old_Aq  */
    1818      904001 :     tcx_decoder_memory_update( xn_buf, /*Q0*/
    1819             :                                synth,  /*Q0*/
    1820             :                                A,
    1821             :                                st_fx,
    1822             :                                0 );
    1823             : 
    1824             : 
    1825             :     /* PLC: [TCX: Memory update] */
    1826             : 
    1827      904001 :     st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr];
    1828      904001 :     move32();
    1829      904001 :     st_fx->old_pitch_buf_fx[1] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 1];
    1830      904001 :     move32();
    1831      904001 :     Copy32( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr );
    1832      904001 :     set32_fx( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], st_fx->old_fpitch, st_fx->nb_subfr );
    1833      904001 :     st_fx->bfi_pitch_fx = shl_sat( round_fx( st_fx->old_fpitch ), 6 );
    1834      904001 :     st_fx->bfi_pitch_frame = st_fx->L_frame;
    1835      904001 :     move16();
    1836             : 
    1837      904001 :     st_fx->mem_pitch_gain[st_fx->nb_subfr * 2 + 1] = st_fx->mem_pitch_gain[st_fx->nb_subfr + 1]; // Q14
    1838      904001 :     move16();
    1839      904001 :     st_fx->mem_pitch_gain[st_fx->nb_subfr * 2] = st_fx->mem_pitch_gain[st_fx->nb_subfr]; // Q14
    1840      904001 :     move16();
    1841             : 
    1842     5093230 :     FOR( i = 0; i < st_fx->nb_subfr; i++ )
    1843             :     {
    1844     4189229 :         st_fx->mem_pitch_gain[( st_fx->nb_subfr * 2 - 1 ) - i] = st_fx->mem_pitch_gain[st_fx->nb_subfr - 1 - i]; // Q14
    1845     4189229 :         move16();
    1846     4189229 :         st_fx->mem_pitch_gain[st_fx->nb_subfr - 1 - i] = shr( hTcxDec->tcxltp_last_gain_unmodified, 1 ); /* Q14 */
    1847     4189229 :         move16();
    1848             :     }
    1849      904001 : }
    1850             : 
    1851           0 : static Word32 CalculateAbsEnergy_fx(                     /* o : normalized result              Q31 */
    1852             :                                      const Word32 L_off, /* i : initial sum value               Qn */
    1853             :                                      const Word16 x[],   /* i : x vector                        Qn */
    1854             :                                      const Word16 lg,    /* i : vector length, range [0..7FFF]  Q0 */
    1855             :                                      Word16 *exp         /* o : exponent of result in [-32,31]  Q0 */
    1856             : )
    1857             : {
    1858             :     Word16 i;
    1859             :     Word32 L_sum;
    1860             :     Word64 L_sum64;
    1861             : 
    1862           0 :     L_sum64 = W_deposit32_l( L_off );
    1863             : 
    1864           0 :     FOR( i = 0; i < lg; i += 2 )
    1865             :     {
    1866           0 :         L_sum64 = W_mac_16_16( L_sum64, x[i], x[i] );
    1867             :     }
    1868           0 :     L_sum = w_norm_llQ31( L_sum64, exp ); /*Q31 - *exp */
    1869           0 :     return L_sum;
    1870             : }
    1871             : 
    1872        1654 : void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_TDAC, Word16 *xn_buf, const Word16 *tcx_aldo_window_1, const PWord16 *tcx_aldo_window_1_trunc, const PWord16 *tcx_aldo_window_2, const PWord16 *tcx_mdct_window_half, const PWord16 *tcx_mdct_window_minimum, const PWord16 *tcx_mdct_window_trans, Word16 tcx_mdct_window_half_length, Word16 tcx_mdct_window_min_length, Word16 index, Word16 left_rect, Word16 tcx_offset, Word16 overlap, Word16 L_frame, Word16 L_frameTCX, Word16 L_spec_TCX5, Word16 L_frame_glob, Word16 frame_cnt, Word16 bfi, Word16 *old_out, Word16 *Q_old_wtda, Decoder_State *st, Word16 fullbandScale, Word16 *acelp_zir )
    1873             : {
    1874        1654 :     const TCX_CONFIG_HANDLE tcx_cfg = st->hTcxCfg;
    1875             :     Word16 tmp_offset;
    1876             :     Word16 tmp1, tmp2, tmp3, *tmpP16;
    1877             :     Word32 tmp32;
    1878             :     Word8 tmp8;
    1879             :     Word16 i;
    1880             :     Word16 nz;
    1881             :     Word16 aldo;
    1882             :     TCX_DEC_HANDLE hTcxDec;
    1883        1654 :     aldo = 0;
    1884        1654 :     move16();
    1885             : 
    1886        1654 :     hTcxDec = st->hTcxDec;
    1887             : 
    1888             :     /* number of zero for ALDO windows*/
    1889        1654 :     tmp32 = L_add( st->sr_core, 0 );
    1890        1654 :     IF( fullbandScale != 0 )
    1891             :     {
    1892         827 :         tmp32 = L_add( st->output_Fs, 0 );
    1893             :     }
    1894        1654 :     nz = NS2SA_FX2( tmp32, N_ZERO_MDCT_NS );
    1895             : 
    1896        1654 :     tmp_offset = 0;
    1897        1654 :     move16();
    1898        1654 :     IF( tcx_offset < 0 )
    1899             :     {
    1900         462 :         tmp_offset = negate( tcx_offset );
    1901             :     }
    1902        1654 :     test();
    1903        1654 :     IF( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) )
    1904             :     {
    1905             :         /* Mode decision in PLC
    1906             : 
    1907             :         last OL   curr OL   left TCX-10  right TCX-10
    1908             :         -------------------------------------------------------------
    1909             :             0      0         2x TCX-5* 1x  TCX-10
    1910             :             0      2         1x TCX-10 1x  TCX-10
    1911             :             0      3         1x TCX-10 1x  TCX-10
    1912             :             2      0         2x TCX-5  1x  TCX-10
    1913             :             2      2         2x TCX-5  2x  TCX-5
    1914             :             2      3         2x TCX-5  2x  TCX-5
    1915             :             3      0         2x TCX-5  1x  TCX-10
    1916             :             3      2         2x TCX-5  2x  TCX-5
    1917             :             3      3         2x TCX-5  2x  TCX-5
    1918             :         */
    1919           0 :         test();
    1920           0 :         test();
    1921           0 :         test();
    1922           0 :         test();
    1923           0 :         test();
    1924           0 :         test();
    1925           0 :         IF( ( bfi == 0 && tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP ) || ( bfi != 0 && ( tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP ) && ( tcx_cfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) )
    1926           0 :         {
    1927             :             /* minimum or half overlap, two transforms, grouping into one window */
    1928             :             Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    1929             :             Word16 w;
    1930             :             Word16 L_win, L_ola;
    1931             : 
    1932           0 :             L_win = shr( L_frame, 1 );
    1933           0 :             L_ola = tcx_mdct_window_half_length;
    1934           0 :             move16();
    1935           0 :             if ( EQ_16( tcx_cfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    1936             :             {
    1937           0 :                 L_ola = tcx_mdct_window_min_length;
    1938           0 :                 move16();
    1939             :             }
    1940             : 
    1941           0 :             set16_fx( xn_buf, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */
    1942           0 :             set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    1943             : 
    1944           0 :             FOR( w = 0; w < 2; w++ )
    1945             :             {
    1946             : 
    1947           0 :                 TCX_MDCT_Inverse( x + L_mult0( w, L_spec_TCX5 ), sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    1948             : 
    1949           0 :                 tmp1 = left_rect;
    1950           0 :                 move16();
    1951           0 :                 tmp2 = tcx_cfg->tcx_last_overlap_mode;
    1952           0 :                 move16();
    1953           0 :                 tmp3 = st->last_core_bfi;
    1954           0 :                 move16();
    1955           0 :                 tmp8 = (Word8) st->last_is_cng;
    1956           0 :                 move16();
    1957           0 :                 IF( w > 0 )
    1958             :                 {
    1959           0 :                     tmp1 = 0;
    1960           0 :                     move16();
    1961           0 :                     tmp2 = MIN_OVERLAP;
    1962           0 :                     move16();
    1963           0 :                     tmp3 = 1;
    1964           0 :                     move16();
    1965           0 :                     tmp8 = (Word8) 0;
    1966           0 :                     move16();
    1967             :                 }
    1968           0 :                 test();
    1969           0 :                 if ( w == 0 && EQ_16( index, 2 ) )
    1970             :                 {
    1971           0 :                     tmp2 = MIN_OVERLAP;
    1972           0 :                     move16();
    1973             :                 }
    1974           0 :                 IF( frame_cnt > 0 )
    1975             :                 {
    1976           0 :                     tmp3 = 1;
    1977           0 :                     move16();
    1978           0 :                     tmp8 = (Word8) 0;
    1979           0 :                     move16();
    1980             :                 }
    1981             : 
    1982           0 :                 tcx_windowing_synthesis_current_frame( win,
    1983             :                                                        tcx_aldo_window_2,
    1984             :                                                        tcx_mdct_window_half,
    1985             :                                                        tcx_mdct_window_minimum,
    1986             :                                                        L_ola,
    1987             :                                                        tcx_mdct_window_half_length,
    1988             :                                                        tcx_mdct_window_min_length,
    1989             :                                                        tmp1,
    1990             :                                                        tmp2,
    1991             :                                                        acelp_zir,
    1992           0 :                                                        hTcxDec->old_syn_Overl,
    1993             :                                                        syn_Overl_TDAC,
    1994           0 :                                                        st->old_Aq_12_8_fx,
    1995             :                                                        tcx_mdct_window_trans,
    1996             :                                                        L_win,
    1997             :                                                        tmp_offset,
    1998             :                                                        tmp3,
    1999             :                                                        tmp8,
    2000             :                                                        fullbandScale );
    2001             : 
    2002           0 :                 IF( w > 0 )
    2003             :                 {
    2004           0 :                     tcx_windowing_synthesis_past_frame( xn_buf + tcx_offset - shr( L_ola, 1 ) + imult1616( w, L_win ),
    2005             :                                                         tcx_aldo_window_1_trunc,
    2006             :                                                         tcx_mdct_window_half,
    2007             :                                                         tcx_mdct_window_minimum,
    2008             :                                                         L_ola,
    2009             :                                                         tcx_mdct_window_half_length,
    2010             :                                                         tcx_mdct_window_min_length,
    2011             :                                                         MIN_OVERLAP );
    2012             :                 }
    2013             :                 /* add part of current sub-window overlapping with previous window */
    2014           0 :                 Vr_add( win,
    2015           0 :                         xn_buf + tcx_offset - shr( L_ola, 1 ) + w * L_win, /*instrumented only shr because in fact, its only L_win+L_win+L_win...*/
    2016           0 :                         xn_buf + tcx_offset - shr( L_ola, 1 ) + w * L_win,
    2017             :                         L_ola );
    2018             :                 /* copy new sub-window region not overlapping with previous window */
    2019           0 :                 Copy(
    2020           0 :                     win + L_ola,
    2021           0 :                     xn_buf + tcx_offset + shr( L_ola, 1 ) + w * L_win,
    2022             :                     L_win );
    2023             :             }
    2024             : 
    2025             :             /* To assure that no garbage values are passed to overlap */
    2026           0 :             set16_fx( xn_buf + L_frame + tcx_offset + shr( L_ola, 1 ), 0, overlap - tcx_offset - shr( L_ola, 1 ) );
    2027             :         }
    2028           0 :         ELSE IF( bfi == 0 && ( frame_cnt == 0 ) && ( tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
    2029           0 :         {
    2030             :             Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    2031             :             Word16 L_win, L_ola, w;
    2032             : 
    2033             :             /* special overlap attempt, two transforms, grouping into one window */
    2034           0 :             L_win = shr( L_frame, 1 );
    2035           0 :             L_ola = tcx_mdct_window_min_length;
    2036           0 :             move16();
    2037             : 
    2038           0 :             set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    2039             : 
    2040             :             /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
    2041             : 
    2042           0 :             TCX_MDCT_Inverse( x, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2043           0 :                               win + L_win,
    2044           0 :                               0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode );
    2045             : 
    2046           0 :             set16_fx( xn_buf, 0, shr( overlap, 1 ) );
    2047             :             /* copy new sub-window region not overlapping with previous window */
    2048           0 :             Copy( win + L_win, xn_buf + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
    2049             : 
    2050             :             /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
    2051           0 :             TCX_MDCT_Inverse( x + L_spec_TCX5, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2052             :                               win,
    2053           0 :                               L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    2054             : 
    2055           0 :             tcx_windowing_synthesis_current_frame( win,
    2056             :                                                    tcx_aldo_window_2,
    2057             :                                                    tcx_mdct_window_half,
    2058             :                                                    tcx_mdct_window_minimum,
    2059             :                                                    L_ola,
    2060             :                                                    tcx_mdct_window_half_length,
    2061             :                                                    tcx_mdct_window_min_length,
    2062             :                                                    0,           /* left_rect */
    2063             :                                                    MIN_OVERLAP, /* left_mode */
    2064             :                                                    acelp_zir,
    2065           0 :                                                    hTcxDec->old_syn_Overl,
    2066             :                                                    syn_Overl_TDAC,
    2067           0 :                                                    st->old_Aq_12_8_fx,
    2068             :                                                    tcx_mdct_window_trans,
    2069             :                                                    L_win,
    2070             :                                                    tmp_offset,
    2071             :                                                    1, /* st->last_core_bfi */
    2072             :                                                    0, /* st->last_is_cng */
    2073             :                                                    fullbandScale );
    2074             : 
    2075           0 :             tmpP16 = xn_buf + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) );
    2076             : 
    2077           0 :             tcx_windowing_synthesis_past_frame( tmpP16,
    2078             :                                                 tcx_aldo_window_1_trunc,
    2079             :                                                 tcx_mdct_window_half,
    2080             :                                                 tcx_mdct_window_minimum,
    2081             :                                                 L_ola,
    2082             :                                                 tcx_mdct_window_half_length,
    2083             :                                                 tcx_mdct_window_min_length,
    2084             :                                                 MIN_OVERLAP );
    2085             : 
    2086             :             /* add part of current sub-window overlapping with previous window */
    2087           0 :             FOR( i = 0; i < L_ola; i++ )
    2088             :             {
    2089           0 :                 tmpP16[i] = add( tmpP16[i], win[i] );
    2090           0 :                 move16();
    2091             :             }
    2092             : 
    2093             :             /* copy new sub-window region not overlapping with previous window */
    2094           0 :             Copy( win + L_ola,
    2095           0 :                   xn_buf + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ),
    2096             :                   L_win );
    2097             : 
    2098             :             /* extra folding-out on left side of win, for perfect reconstruction */
    2099           0 :             FOR( w = ( overlap / 2 ); w < overlap; w++ )
    2100             :             {
    2101           0 :                 xn_buf[( ( overlap - 1 ) - w )] = negate( xn_buf[w] );
    2102           0 :                 move16();
    2103             :             }
    2104             : 
    2105           0 :             tcx_windowing_synthesis_current_frame( xn_buf,
    2106             :                                                    tcx_aldo_window_2,
    2107             :                                                    tcx_mdct_window_half,
    2108             :                                                    tcx_mdct_window_minimum,
    2109             :                                                    overlap,
    2110             :                                                    tcx_mdct_window_half_length,
    2111             :                                                    tcx_mdct_window_min_length,
    2112             :                                                    left_rect,
    2113             :                                                    0, /* left_mode */
    2114             :                                                    acelp_zir,
    2115           0 :                                                    hTcxDec->old_syn_Overl,
    2116             :                                                    syn_Overl_TDAC,
    2117           0 :                                                    st->old_Aq_12_8_fx,
    2118             :                                                    tcx_mdct_window_trans,
    2119           0 :                                                    shl( L_win, 1 ),
    2120             :                                                    tmp_offset,
    2121           0 :                                                    st->last_core_bfi,
    2122           0 :                                                    (Word8) st->last_is_cng,
    2123             :                                                    fullbandScale );
    2124             :         }
    2125             :         ELSE /* default  i.e. maximum overlap, single transform, no grouping */
    2126             :         {
    2127             : 
    2128           0 :             TCX_MDCT_Inverse( x, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), xn_buf, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    2129             : 
    2130           0 :             tmp1 = index;
    2131           0 :             move16();
    2132           0 :             test();
    2133           0 :             test();
    2134           0 :             test();
    2135           0 :             if ( bfi == 0 && ( frame_cnt > 0 ) && ( index == 0 ) && ( st->last_core != ACELP_CORE ) )
    2136             :             {
    2137           0 :                 tmp1 = MIN_OVERLAP;
    2138           0 :                 move16();
    2139             :             }
    2140             : 
    2141           0 :             tmp3 = st->last_core_bfi;
    2142           0 :             move16();
    2143           0 :             if ( frame_cnt > 0 )
    2144             :             {
    2145           0 :                 tmp3 = 1;
    2146           0 :                 move16();
    2147             :             }
    2148             : 
    2149           0 :             tmp8 = (Word8) st->last_is_cng;
    2150           0 :             move16();
    2151           0 :             if ( frame_cnt > 0 )
    2152             :             {
    2153           0 :                 tmp8 = 0;
    2154           0 :                 move16();
    2155             :             }
    2156             : 
    2157           0 :             tcx_windowing_synthesis_current_frame( xn_buf,
    2158             :                                                    tcx_aldo_window_2,
    2159             :                                                    tcx_mdct_window_half,
    2160             :                                                    tcx_mdct_window_minimum,
    2161             :                                                    overlap,
    2162             :                                                    tcx_mdct_window_half_length,
    2163             :                                                    tcx_mdct_window_min_length,
    2164             :                                                    left_rect,
    2165             :                                                    tmp1,
    2166             :                                                    acelp_zir,
    2167           0 :                                                    hTcxDec->old_syn_Overl,
    2168             :                                                    syn_Overl_TDAC,
    2169           0 :                                                    st->old_Aq_12_8_fx,
    2170             :                                                    tcx_mdct_window_trans,
    2171           0 :                                                    shr( L_frame_glob, 1 ),
    2172             :                                                    tmp_offset,
    2173             :                                                    tmp3,
    2174             :                                                    tmp8,
    2175             :                                                    fullbandScale );
    2176             :         }
    2177             :     }
    2178             :     ELSE /* frame is TCX-20 or not TCX-only */
    2179             :     {
    2180        1654 :         assert( frame_cnt == 0 );
    2181             : 
    2182        1654 :         IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    2183             :         {
    2184             :             Word32 tmp_buf[L_FRAME_PLUS];
    2185             :             Word16 Q;
    2186             : 
    2187             :             /* DCT */
    2188        1192 :             Q = sub( 31, x_e );
    2189        1192 :             edct_fx( x, tmp_buf, L_frame, &Q );
    2190             : 
    2191             :             /* scale by sqrt(L / NORM_MDCT_FACTOR) */
    2192        1192 :             tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
    2193        1192 :             tmp2 = 4;
    2194        1192 :             move16();
    2195        1192 :             tmp1 = Sqrt16( tmp1, &tmp2 );
    2196             : 
    2197      669224 :             FOR( i = 0; i < L_frame; i++ )
    2198             :             {
    2199      668032 :                 tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
    2200      668032 :                 move32();
    2201             :             }
    2202        1192 :             Q = sub( Q, tmp2 );
    2203             : 
    2204             : 
    2205        1192 :             window_ola_fx( tmp_buf,
    2206             :                            xn_buf,
    2207             :                            &Q,
    2208             :                            old_out,
    2209             :                            Q_old_wtda,
    2210             :                            L_frame,
    2211        1192 :                            tcx_cfg->tcx_last_overlap_mode,
    2212        1192 :                            tcx_cfg->tcx_curr_overlap_mode,
    2213             :                            0,
    2214             :                            0,
    2215             :                            NULL );
    2216             : 
    2217             :             /* scale output */
    2218        1192 :             IF( Q <= 0 )
    2219             :             {
    2220       59819 :                 FOR( i = 0; i < L_frame; i++ )
    2221             :                 {
    2222       59712 :                     xn_buf[i] = shr_sat( xn_buf[i], Q );
    2223       59712 :                     move16();
    2224             :                 }
    2225             :             }
    2226             :             ELSE
    2227             :             {
    2228        1085 :                 tmp1 = shr( 0x4000, sub( Q, 1 ) );
    2229             : 
    2230      609405 :                 FOR( i = 0; i < L_frame; i++ )
    2231             :                 {
    2232      608320 :                     xn_buf[i] = mult_r( xn_buf[i], tmp1 );
    2233      608320 :                     move16();
    2234             :                 }
    2235             :             }
    2236             : 
    2237        1192 :             aldo = 1;
    2238        1192 :             move16();
    2239             :         }
    2240             :         ELSE
    2241             :         {
    2242             : 
    2243         462 :             TCX_MDCT_Inverse( x, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), xn_buf, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    2244             : 
    2245             : 
    2246             :             /*-----------------------------------------------------------*
    2247             :              * Windowing, overlap and add                                *
    2248             :              *-----------------------------------------------------------*/
    2249             : 
    2250             : 
    2251             :             /* Window current frame */
    2252         462 :             tmp3 = st->last_core_bfi;
    2253         462 :             move16();
    2254             : 
    2255         462 :             tmp8 = (Word8) st->last_is_cng;
    2256         462 :             move16();
    2257         924 :             tcx_windowing_synthesis_current_frame( xn_buf,
    2258             :                                                    tcx_aldo_window_2,
    2259             :                                                    tcx_mdct_window_half,
    2260             :                                                    tcx_mdct_window_minimum,
    2261             :                                                    overlap,
    2262             :                                                    tcx_mdct_window_half_length,
    2263             :                                                    tcx_mdct_window_min_length,
    2264             :                                                    left_rect,
    2265         462 :                                                    tcx_cfg->tcx_last_overlap_mode,
    2266             :                                                    acelp_zir,
    2267         462 :                                                    hTcxDec->old_syn_Overl,
    2268             :                                                    syn_Overl_TDAC,
    2269         462 :                                                    st->old_Aq_12_8_fx,
    2270             :                                                    tcx_mdct_window_trans,
    2271         462 :                                                    shr( L_frame_glob, 1 ),
    2272             :                                                    tmp_offset,
    2273             :                                                    tmp3,
    2274             :                                                    tmp8,
    2275             :                                                    fullbandScale );
    2276             :         } /* TRANSITION_OVERLAP */
    2277             :     }     /* TCX-20 and TCX-only */
    2278             : 
    2279             :     /* Window and overlap-add past frame if past frame is TCX */
    2280        1654 :     test();
    2281        1654 :     IF( ( frame_cnt != 0 ) || ( GT_16( st->last_core_bfi, ACELP_CORE ) ) )
    2282             :     {
    2283        1190 :         test();
    2284        1190 :         test();
    2285        1190 :         IF( ( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) )
    2286             :         {
    2287           0 :             test();
    2288           0 :             test();
    2289           0 :             test();
    2290           0 :             test();
    2291           0 :             if ( ( bfi == 0 ) && ( frame_cnt > 0 ) && ( index == 0 ) &&
    2292           0 :                  ( EQ_16( tcx_cfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) && ( st->last_core != ACELP_CORE ) )
    2293             :             {
    2294           0 :                 index = MIN_OVERLAP; /* use minimum overlap between the two TCX-10 windows */
    2295           0 :                 move16();
    2296             :             }
    2297             : 
    2298           0 :             IF( tcx_cfg->last_aldo != 0 )
    2299             :             {
    2300             :                 Word16 tmp4;
    2301             : 
    2302           0 :                 tmp2 = add( *Q_old_wtda, TCX_IMDCT_HEADROOM );
    2303           0 :                 tmp4 = sub( shr( overlap, 1 ), tcx_offset );
    2304             : 
    2305           0 :                 FOR( i = 0; i < tmp4; i++ )
    2306             :                 {
    2307           0 :                     xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM );
    2308           0 :                     move16();
    2309             :                 }
    2310             : 
    2311           0 :                 tmp1 = sub( overlap, tcx_mdct_window_min_length );
    2312           0 :                 FOR( i = 0; i < tmp1; i++ )
    2313             :                 {
    2314           0 :                     xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], shr_sat( old_out[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
    2315           0 :                     move16();
    2316             :                 }
    2317             : 
    2318             :                 /* fade truncated ALDO window */
    2319           0 :                 tmp1 = sub( overlap, shr( tcx_mdct_window_min_length, 1 ) );
    2320           0 :                 FOR( ; i < tmp1; i++ )
    2321             :                 {
    2322           0 :                     tmp3 = mult_r( shr( old_out[i + nz], tmp2 ), tcx_mdct_window_minimum[i - overlap + tcx_mdct_window_min_length].v.re );
    2323           0 :                     xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM );
    2324           0 :                     move16();
    2325             :                 }
    2326           0 :                 FOR( ; i < overlap; i++ )
    2327             :                 {
    2328           0 :                     tmp3 = mult_r( shr( old_out[i + nz], tmp2 ), tcx_mdct_window_minimum[overlap - 1 - i].v.im );
    2329           0 :                     xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM );
    2330           0 :                     move16();
    2331             :                 }
    2332             : 
    2333           0 :                 FOR( i = add( i, tmp4 ); i < L_frame; i++ )
    2334             :                 {
    2335           0 :                     xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
    2336           0 :                     move16();
    2337             :                 }
    2338             :             }
    2339             :             ELSE
    2340             :             {
    2341           0 :                 tmp1 = index;
    2342           0 :                 move16();
    2343           0 :                 test();
    2344           0 :                 if ( ( index == 0 ) || ( EQ_16( tcx_cfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
    2345             :                 {
    2346           0 :                     tmp1 = tcx_cfg->tcx_last_overlap_mode;
    2347           0 :                     move16();
    2348             :                 }
    2349             : 
    2350           0 :                 tcx_windowing_synthesis_past_frame( old_syn_overl,
    2351             :                                                     tcx_aldo_window_1_trunc,
    2352             :                                                     tcx_mdct_window_half,
    2353             :                                                     tcx_mdct_window_minimum,
    2354             :                                                     overlap,
    2355             :                                                     tcx_mdct_window_half_length,
    2356             :                                                     tcx_mdct_window_min_length,
    2357             :                                                     tmp1 );
    2358             : 
    2359             :                 BASOP_SATURATE_WARNING_OFF_EVS;
    2360           0 :                 IF( bfi )
    2361             :                 {
    2362           0 :                     tmp1 = sub( shr( overlap, 1 ), tcx_offset );
    2363           0 :                     tmp3 = shr( tcx_mdct_window_half_length, 1 );
    2364           0 :                     FOR( i = 0; i < tmp1; i++ )
    2365             :                     {
    2366           0 :                         xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
    2367           0 :                         move16();
    2368             :                     }
    2369           0 :                     FOR( i = 0; i < tmp3; i++ )
    2370             :                     {
    2371           0 :                         tmp2 = add_sat( xn_buf[i + tmp1], mult_r( old_syn_overl[i], tcx_mdct_window_half[i].v.re ) );
    2372           0 :                         xn_buf[i + tmp1] = shl_sat( tmp2, TCX_IMDCT_HEADROOM );
    2373           0 :                         move16();
    2374             :                     }
    2375           0 :                     FOR( ; i < tcx_mdct_window_half_length; i++ )
    2376             :                     {
    2377           0 :                         tmp2 = add( xn_buf[i + tmp1], mult_r( old_syn_overl[i], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) );
    2378           0 :                         xn_buf[i + tmp1] = shl_sat( tmp2, TCX_IMDCT_HEADROOM );
    2379           0 :                         move16();
    2380             :                     }
    2381           0 :                     IF( LT_16( add( i, tmp1 ), L_frame ) )
    2382             :                     {
    2383           0 :                         FOR( i = add( i, tmp1 ); i < L_frame; i++ )
    2384             :                         {
    2385           0 :                             xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
    2386           0 :                             move16();
    2387             :                         }
    2388             :                     }
    2389             :                 }
    2390           0 :                 ELSE IF( left_rect == 0 )
    2391             :                 {
    2392           0 :                     FOR( i = 0; i < overlap; i++ )
    2393             :                     {
    2394             : 
    2395           0 :                         xn_buf[i] = shl_sat( add_sat( xn_buf[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM );
    2396           0 :                         move16();
    2397             :                     }
    2398             : 
    2399           0 :                     IF( LT_16( i, L_frame ) )
    2400             :                     {
    2401           0 :                         FOR( ; i < L_frame; i++ )
    2402             :                         {
    2403           0 :                             xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
    2404           0 :                             move16();
    2405             :                         }
    2406             :                     }
    2407             :                 }
    2408             :                 ELSE
    2409             :                 {
    2410           0 :                     tmp1 = shr( overlap, 1 );
    2411           0 :                     FOR( i = 0; i < tmp1; i++ )
    2412             :                     {
    2413           0 :                         xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
    2414           0 :                         move16();
    2415             :                     }
    2416             : 
    2417           0 :                     tmpP16 = xn_buf + tmp1;
    2418           0 :                     FOR( i = 0; i < overlap; i++ )
    2419             :                     {
    2420           0 :                         tmpP16[i] = shl_sat( add( tmpP16[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM );
    2421           0 :                         move16();
    2422             :                     }
    2423             : 
    2424           0 :                     IF( LT_16( add( i, tmp1 ), L_frame ) )
    2425             :                     {
    2426           0 :                         FOR( i = add( i, tmp1 ); i < L_frame; i++ )
    2427             :                         {
    2428           0 :                             xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
    2429           0 :                             move16();
    2430             :                         }
    2431             :                     }
    2432             :                 }
    2433             :                 BASOP_SATURATE_WARNING_ON_EVS;
    2434             :             }
    2435             :         }
    2436             :         /* aldo must not become 0 unless for TCX10 and frames after tansistion frames */
    2437        1190 :         assert( aldo != 0 || ( L_frameTCX == hTcxDec->L_frameTCX >> 1 && st->tcxonly ) || st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP );
    2438             :     }
    2439             :     ELSE
    2440             :     {
    2441         464 :         IF( aldo == 0 )
    2442             :         {
    2443             :             BASOP_SATURATE_WARNING_OFF_EVS;
    2444      330862 :             FOR( i = 0; i < L_frame; i++ )
    2445             :             {
    2446      330400 :                 xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
    2447      330400 :                 move16();
    2448             :             }
    2449             :             BASOP_SATURATE_WARNING_ON_EVS;
    2450             :         }
    2451             :     }
    2452             : 
    2453        1654 :     test();
    2454        1654 :     test();
    2455        1654 :     test();
    2456        1654 :     IF( ( aldo == 0 ) &&
    2457             :         ( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
    2458             :           NE_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
    2459             :     {
    2460             :         /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
    2461       74802 :         FOR( i = 0; i < nz; i++ )
    2462             :         {
    2463       74340 :             old_out[i] = shr( xn_buf[L_frame - nz + i], TCX_IMDCT_HEADROOM );
    2464       74340 :             move16();
    2465             :         }
    2466         462 :         Copy( xn_buf + L_frame, old_out + nz, overlap );
    2467         462 :         set16_fx( old_out + nz + overlap, 0, nz );
    2468             : 
    2469         462 :         tcx_windowing_synthesis_past_frame( old_out + nz,
    2470             :                                             tcx_aldo_window_1_trunc,
    2471             :                                             tcx_mdct_window_half,
    2472             :                                             tcx_mdct_window_minimum,
    2473             :                                             overlap,
    2474             :                                             tcx_mdct_window_half_length,
    2475             :                                             tcx_mdct_window_min_length,
    2476         462 :                                             tcx_cfg->tcx_curr_overlap_mode );
    2477             : 
    2478             :         /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
    2479         462 :         IF( EQ_16( tcx_cfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
    2480             :         {
    2481       74802 :             FOR( i = 0; i < nz; i++ )
    2482             :             {
    2483       74340 :                 old_out[nz + overlap + i] = shr( mult_r( xn_buf[L_frame - 1 - i], tcx_aldo_window_1[nz - 1 - i] ), TCX_IMDCT_HEADROOM );
    2484       74340 :                 move16();
    2485             :             }
    2486         462 :             aldo = 1;
    2487         462 :             move16();
    2488             :         }
    2489             : 
    2490         462 :         *Q_old_wtda = -TCX_IMDCT_HEADROOM;
    2491         462 :         move16();
    2492             :     }
    2493        1654 :     if ( fullbandScale != 0 )
    2494             :     {
    2495         827 :         st->hTcxCfg->last_aldo = aldo;
    2496         827 :         move16();
    2497             :     }
    2498             : 
    2499             :     /* Smoothing between the ACELP PLC and TCX Transition frame. Using the shape of the half overlap window for the crossfading. */
    2500        1654 :     test();
    2501        1654 :     test();
    2502        1654 :     test();
    2503        1654 :     IF( left_rect && ( frame_cnt == 0 ) && ( st->last_core_bfi == ACELP_CORE ) && st->prev_bfi )
    2504             :     {
    2505             : 
    2506           0 :         IF( fullbandScale )
    2507             :         {
    2508           0 :             tmp1 = sub( shr( overlap, 1 ), tcx_offset );
    2509           0 :             tmp3 = shr( tcx_mdct_window_half_length, 1 );
    2510           0 :             FOR( i = 0; i < tmp3; i++ )
    2511             :             {
    2512           0 :                 xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im );
    2513           0 :                 xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_OverlFB[i], mult_r_sat( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) );
    2514           0 :                 move16();
    2515           0 :                 move16();
    2516             :             }
    2517           0 :             FOR( ; i < tcx_mdct_window_half_length; i++ )
    2518             :             {
    2519           0 :                 xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[( ( tcx_mdct_window_half_length - 1 ) - i )].v.re );
    2520           0 :                 xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_OverlFB[i], mult_r_sat( tcx_mdct_window_half[( ( tcx_mdct_window_half_length - 1 ) - i )].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) );
    2521           0 :                 move16();
    2522           0 :                 move16();
    2523             :             }
    2524             :         }
    2525             :         ELSE
    2526             :         {
    2527           0 :             tmp1 = sub( shr( overlap, 1 ), tcx_offset );
    2528           0 :             tmp3 = shr( tcx_mdct_window_half_length, 1 );
    2529           0 :             FOR( i = 0; i < tmp3; i++ )
    2530             :             {
    2531           0 :                 xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im );
    2532           0 :                 xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_Overl[i], mult_r_sat( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) );
    2533           0 :                 move16();
    2534           0 :                 move16();
    2535             :             }
    2536           0 :             FOR( ; i < tcx_mdct_window_half_length; i++ )
    2537             :             {
    2538           0 :                 xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.re );
    2539           0 :                 xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_Overl[i], mult_r_sat( tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) );
    2540           0 :                 move16();
    2541           0 :                 move16();
    2542             :             }
    2543             :         }
    2544             :     }
    2545        1654 : }
    2546             : 
    2547             : 
    2548     1698930 : static Word16 IMDCT_ivas_fx_calc_qwin(
    2549             :     Decoder_State *st,
    2550             :     Word16 *syn_Overl_TDAC,
    2551             :     Word16 Q_syn_Overl_TDAC,
    2552             :     Word16 *syn_Overl,
    2553             :     Word16 Q_syn_Overl,
    2554             :     Word16 *old_syn_Overl,
    2555             :     Word16 Q_old_syn_Overl,
    2556             :     Word16 *old_out_fx,
    2557             :     Word16 Q_old_out_fx,
    2558             :     Word16 q_win,
    2559             :     const Word16 FB_flag )
    2560             : {
    2561             :     Word16 t, old_syn_Overl_len, syn_Overl_TDAC_len;
    2562             : 
    2563     1698930 :     t = L_FRAME32k;
    2564     1698930 :     move16();
    2565     1698930 :     if ( FB_flag )
    2566             :     {
    2567      849465 :         t = L_FRAME48k;
    2568      849465 :         move16();
    2569             :     }
    2570             : 
    2571     1698930 :     old_syn_Overl_len = st->hTcxCfg->tcx_mdct_window_length;
    2572     1698930 :     syn_Overl_TDAC_len = s_max( st->hTcxCfg->tcx_mdct_window_length_old, 0 );
    2573             : 
    2574     1698930 :     IF( ( st->prev_bfi && EQ_16( st->last_core_bfi, ACELP_CORE ) ) || EQ_16( st->last_core, ACELP_CORE ) )
    2575             :     {
    2576       21524 :         old_syn_Overl_len = shr( st->L_frame, 1 );
    2577       21524 :         syn_Overl_TDAC_len = shr( st->last_L_frame, 1 );
    2578             :     }
    2579             : 
    2580     1698930 :     IF( st->prev_bfi && ( st->last_core_bfi == ACELP_CORE ) )
    2581             :     {
    2582        4984 :         syn_Overl_TDAC_len = old_syn_Overl_len;
    2583             :     }
    2584             : 
    2585     1698930 :     q_win = 6;
    2586     1698930 :     move16();
    2587             : 
    2588             :     // q_win  == norm + Q_syn_Overl_TDAC
    2589     1698930 :     q_win = s_min( q_win, norm_arr( syn_Overl_TDAC, syn_Overl_TDAC_len ) + Q_syn_Overl_TDAC );
    2590             : 
    2591             :     // q_win = s_min( q_win, norm_arr( syn_Overl, oldLength / 2 ) + Q_syn_Overl );
    2592     1698930 :     q_win = s_min( q_win, norm_arr( syn_Overl, old_syn_Overl_len ) + Q_syn_Overl );
    2593             : 
    2594     1698930 :     q_win = s_min( q_win, norm_arr( old_syn_Overl, old_syn_Overl_len ) + Q_old_syn_Overl );
    2595             : 
    2596             :     // q_win = s_min( q_win, norm_arr( old_out_fx, oldLength ) + Q_old_out_fx );
    2597     1698930 :     q_win = s_min( q_win, norm_arr( old_out_fx, t ) + Q_old_out_fx );
    2598             : 
    2599             : #if 0
    2600             :     set16_zero_fx(syn_Overl_TDAC + oldLength / 2, (t-oldLength)/2 );
    2601             :     //set16_zero_fx(syn_Overl + oldLength / 2, (t-oldLength)/2 );
    2602             :     set16_zero_fx(old_syn_Overl + oldLength / 2, (t-oldLength)/2 );
    2603             :     //set16_zero_fx(old_out_fx + oldLength, (t-oldLength) );
    2604             : #endif
    2605     1698930 :     q_win = s_max( -3, sub( q_win, 2 ) );
    2606             : 
    2607     1698930 :     return q_win;
    2608             : }
    2609             : 
    2610     1717256 : static void IMDCT_ivas_fx_rescale(
    2611             :     Word16 *xn_buf_fx,
    2612             :     Word16 *q_xn_buf_fx,
    2613             :     Word16 *syn_Overl_TDAC,
    2614             :     Word16 *Q_syn_Overl_TDAC,
    2615             :     Word16 *syn_Overl,
    2616             :     Word16 *Q_syn_Overl,
    2617             :     Word16 *old_syn_Overl,
    2618             :     Word16 *Q_old_syn_Overl,
    2619             :     Word16 *old_out_fx,
    2620             :     Word16 *Q_old_out_fx,
    2621             :     Word16 q_win,
    2622             :     const Word16 FB_flag )
    2623             : {
    2624             :     Word16 oldLength;
    2625             : 
    2626     1717256 :     oldLength = L_FRAME32k;
    2627     1717256 :     move16();
    2628     1717256 :     if ( FB_flag )
    2629             :     {
    2630      858628 :         oldLength = L_FRAME48k;
    2631      858628 :         move16();
    2632             :     }
    2633             : 
    2634             : #if 1
    2635     1717256 :     IF( xn_buf_fx != NULL )
    2636             :     {
    2637     1715678 :         Scale_sig( xn_buf_fx, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX, sub( q_win, *q_xn_buf_fx ) );
    2638     1715678 :         *q_xn_buf_fx = q_win;
    2639     1715678 :         move16();
    2640             :     }
    2641     1717256 :     Scale_sig( syn_Overl_TDAC, oldLength / 2, sub( q_win, *Q_syn_Overl_TDAC ) ); // st->hTcxDec->Q_syn_Overl_TDAC -> q_win
    2642     1717256 :     *Q_syn_Overl_TDAC = q_win;
    2643     1717256 :     move16();
    2644     1717256 :     Scale_sig( syn_Overl, oldLength / 2, sub( q_win, *Q_syn_Overl ) ); // st->hTcxDec->Q_syn_Overl -> q_win
    2645     1717256 :     *Q_syn_Overl = q_win;
    2646     1717256 :     move16();
    2647     1717256 :     if ( FB_flag == 0 )
    2648             :     {
    2649      858628 :         Scale_sig( old_syn_Overl, oldLength / 2, sub( q_win, *Q_old_syn_Overl ) ); // Q(-1 - st->Q_syn) -> q_win
    2650      858628 :         *Q_old_syn_Overl = q_win;
    2651      858628 :         move16();
    2652             :     }
    2653     1717256 :     Scale_sig( old_out_fx, oldLength, sub( q_win, *Q_old_out_fx ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win
    2654     1717256 :     *Q_old_out_fx = q_win;
    2655     1717256 :     move16();
    2656             : #endif
    2657     1717256 : }
    2658             : 
    2659      114732 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
    2660             :     const Word16 L,  /* Q0 */
    2661             :     Word16 *factor_e /* Q0 */
    2662             : )
    2663             : {
    2664             : 
    2665             :     Word16 factor;
    2666             : 
    2667      114732 :     IF( EQ_16( L, NORM_MDCT_FACTOR ) )
    2668             :     {
    2669       27296 :         factor = 32767;
    2670       27296 :         move16();
    2671       27296 :         *factor_e = 0;
    2672       27296 :         move16();
    2673             :     }
    2674       87436 :     ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
    2675             :     {
    2676       14371 :         factor = 23170;
    2677       14371 :         move16();
    2678       14371 :         *factor_e = 1;
    2679       14371 :         move16();
    2680             :     }
    2681       73065 :     ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
    2682             :     {
    2683         969 :         factor = 32767;
    2684         969 :         move16();
    2685         969 :         *factor_e = 1;
    2686         969 :         move16();
    2687             :     }
    2688             :     ELSE
    2689             :     {
    2690       72096 :         factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
    2691       72096 :         *factor_e = 4;
    2692       72096 :         move16();
    2693             : 
    2694       72096 :         factor = Sqrt16( factor, factor_e );
    2695             :     }
    2696             : 
    2697      114732 :     return factor;
    2698             : }
    2699             : 
    2700      114650 : static void TCX_MDCT_Inverse_qwin_fx(
    2701             :     Word32 *x, // Q( 31 - x_e )
    2702             :     Word16 x_e,
    2703             :     Word16 *y,                 /* Qy */
    2704             :     const Word16 l,            /* Q0 */
    2705             :     const Word16 m,            /* Q0 */
    2706             :     const Word16 r,            /* Q0 */
    2707             :     const Word16 element_mode, /* Q0 */
    2708             :     Word16 *q_win,
    2709             :     Word16 allow_qwin_change )
    2710             : {
    2711             : 
    2712             :     Word16 i, fac, negfac, s;
    2713      114650 :     Word16 L2 = l, R2 = r;
    2714             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
    2715             :     Word16 fac_e;
    2716             :     (void) element_mode;
    2717      114650 :     L2 = shr( l, 1 );
    2718      114650 :     R2 = shr( r, 1 );
    2719             : 
    2720      114650 :     x_e = sub( 15, x_e );
    2721      114650 :     edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
    2722      114650 :     x_e = sub( 15, x_e );
    2723             : 
    2724      114650 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
    2725      114650 :     x_e = add( x_e, fac_e );
    2726             : 
    2727      114650 :     negfac = negate( fac );
    2728             : 
    2729      114650 :     IF( allow_qwin_change )
    2730             :     {
    2731             :         // x_e + q_win == L_norm_arr(tmp_buf, , *q_win );
    2732             :         // q_win = L_norm_arr(tmp_buf, , *q_win ) -  x_e;
    2733       46678 :         s = L_norm_arr( tmp_buf + L2, m + R2 + L2 );
    2734       46678 :         *q_win = s_min( sub( s, x_e ), *q_win );
    2735             :     }
    2736             : 
    2737      114650 :     s = add( x_e, *q_win );
    2738      114650 :     move16();
    2739             : 
    2740     9287082 :     FOR( i = 0; i < R2; i++ )
    2741             :     {
    2742     9172432 :         y[l + m + R2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); /* fold out right end of DCT        exp(fac_e)*/
    2743             : 
    2744     9172432 :         move16();
    2745             :     }
    2746             : 
    2747     8957852 :     FOR( i = 0; i < L2; i++ )
    2748             :     {
    2749     8843202 :         y[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], fac ), s ) ); /* negate, fold out left end of DCT        exp(fac_e)*/
    2750     8843202 :         move16();
    2751             :     }
    2752             : 
    2753    17478802 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
    2754             :     {
    2755             :         Word16 f;
    2756             : 
    2757    17364152 :         f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
    2758    17364152 :         y[L2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT      exp(fac_e)*/
    2759    17364152 :         move16();
    2760    17364152 :         y[l + m + R2 - 1 - i] = f;
    2761    17364152 :         move16();
    2762             :     }
    2763      114650 : }
    2764             : 
    2765          20 : static void TCX_MDST_Inverse_qwin_fx(
    2766             :     Word32 *x, /* exp(x_e) */
    2767             :     Word16 x_e,
    2768             :     Word16 *y,      /* Qx */
    2769             :     const Word16 l, /* Q0 */
    2770             :     const Word16 m, /* Q0 */
    2771             :     const Word16 r, /* Q0 */
    2772             :     Word16 *q_win,
    2773             :     Word16 allow_qwin_change )
    2774             : {
    2775             : 
    2776             :     Word16 i, fac, negfac, s;
    2777          20 :     Word16 L2 = l, R2 = r;
    2778          20 :     move16();
    2779          20 :     move16();
    2780             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
    2781             :     Word16 fac_e;
    2782             : 
    2783          20 :     L2 = shr( l, 1 );
    2784          20 :     R2 = shr( r, 1 );
    2785             : 
    2786          20 :     x_e = sub( 15, x_e );
    2787          20 :     edst_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
    2788          20 :     x_e = sub( 15, x_e );
    2789             : 
    2790          20 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
    2791          20 :     x_e = add( x_e, fac_e );
    2792             : 
    2793          20 :     negfac = negate( fac );
    2794             : 
    2795          20 :     IF( allow_qwin_change )
    2796             :     {
    2797             :         // x_e + q_win == L_norm_arr(tmp_buf, , *q_win );
    2798             :         // q_win = L_norm_arr(tmp_buf, , *q_win ) -  x_e;
    2799           8 :         s = L_norm_arr( tmp_buf + L2, m + R2 + L2 );
    2800           8 :         *q_win = s_min( sub( s, x_e ), *q_win );
    2801             :     }
    2802             : 
    2803          20 :     s = add( x_e, *q_win );
    2804          20 :     move16();
    2805             : 
    2806         934 :     FOR( i = 0; i < R2; i++ )
    2807             :     {
    2808         914 :         y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) ); /* fold out right end of DCT           exp(fac_e)*/
    2809         914 :         move16();
    2810             :     }
    2811             : 
    2812         934 :     FOR( i = 0; i < L2; i++ )
    2813             :     {
    2814         914 :         y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], negfac ), s ) ); /* negate, fold out left end of DCT             exp(fac_e)*/
    2815         914 :         move16();
    2816             :     }
    2817             : 
    2818        1556 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
    2819             :     {
    2820             :         Word16 f;
    2821        1536 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) );
    2822             : 
    2823        1536 :         y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT  exp(fac_e)*/
    2824        1536 :         move16();
    2825             : 
    2826        1536 :         y[l + m + R2 - 1 - i] = negate( f );
    2827        1536 :         move16();
    2828             :     }
    2829          20 : }
    2830             : 
    2831             : /*-------------------------------------------------------------------*
    2832             :  * TCX_MDXT_Inverse_fx()
    2833             :  *
    2834             :  *
    2835             :  *-------------------------------------------------------------------*/
    2836          62 : static void TCX_MDXT_Inverse_qwin_fx(
    2837             :     const Word32 *x, /* exp(x_e) */
    2838             :     Word16 x_e,
    2839             :     Word16 *y,                 /* Qx */
    2840             :     const Word16 l,            /* Q0 */
    2841             :     const Word16 m,            /* Q0 */
    2842             :     const Word16 r,            /* Q0 */
    2843             :     const UWord16 kernel_type, /* Q0 */
    2844             :     Word16 *q_win,
    2845             :     Word16 allow_qwin_change )
    2846             : {
    2847             :     Word16 signLeft;
    2848             :     Word16 signRight;
    2849             :     Word16 i, fac, negfac, s, fac_e;
    2850          62 :     const Word16 L2 = shr( l, 1 ), R2 = shr( r, 1 );
    2851             :     Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
    2852             :     Word16 f;
    2853             : 
    2854          62 :     set32_fx( tmp_buf, 0, N_MAX + L_MDCT_OVLP_MAX / 2 );
    2855             : 
    2856          62 :     edxt_fx( x, tmp_buf + L2, add( add( L2, m ), R2 ), kernel_type, TRUE );
    2857             : 
    2858          62 :     fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
    2859          62 :     x_e = add( x_e, fac_e );
    2860             : 
    2861          62 :     negfac = negate( fac );
    2862          62 :     IF( GE_16( kernel_type, MDCT_II ) )
    2863             :     {
    2864          46 :         signLeft = negfac;
    2865             :     }
    2866             :     ELSE
    2867             :     {
    2868          16 :         signLeft = fac;
    2869             :     }
    2870             :     // signRight = ( kernel_type & 1 ? fac : negfac );
    2871          62 :     IF( L_and( kernel_type, 1 ) )
    2872             :     {
    2873          16 :         signRight = fac;
    2874             :     }
    2875             :     ELSE
    2876             :     {
    2877          46 :         signRight = negfac;
    2878             :     }
    2879             : 
    2880          62 :     IF( allow_qwin_change )
    2881             :     {
    2882             :         // x_e + q_win == L_norm_arr(tmp_buf, , *q_win );
    2883             :         // q_win = L_norm_arr(tmp_buf, , *q_win ) -  x_e;
    2884          24 :         s = L_norm_arr( tmp_buf + L2, m + R2 + L2 );
    2885          24 :         *q_win = s_min( sub( s, x_e ), *q_win );
    2886             :     }
    2887             : 
    2888          62 :     s = add( x_e, *q_win );
    2889          62 :     move16();
    2890             : 
    2891        3424 :     FOR( i = 0; i < L2; i++ )
    2892             :     {
    2893        3362 :         y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], signLeft ), s ) ); /* fold out the left end      exp(fac_e)*/
    2894             :     }
    2895             : 
    2896        3464 :     FOR( i = 0; i < R2; i++ )
    2897             :     {
    2898        3402 :         y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], signRight ), s ) ); /* ...and right end      exp(fac_e)*/
    2899        3402 :         move16();
    2900             :     }
    2901             : 
    2902        4750 :     FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
    2903             :     {
    2904             : 
    2905        4688 :         f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
    2906             : 
    2907        4688 :         y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT      exp(fac_e)*/
    2908        4688 :         move16();
    2909             : 
    2910        4688 :         y[l + m + R2 - 1 - i] = f;
    2911        4688 :         move16();
    2912             :     }
    2913             : 
    2914          62 :     return;
    2915             : }
    2916             : 
    2917     1698930 : void IMDCT_ivas_fx(
    2918             :     Word32 *x_fx, // Q(q_x)
    2919             :     Word16 q_x,
    2920             :     Word16 *old_syn_overl_fx, // *Q_old_syn_overl_fx
    2921             :     Word16 *Q_old_syn_overl_fx,
    2922             :     Word16 *syn_Overl_TDAC_fx, // *Q_syn_Overl_TDAC_fx
    2923             :     Word16 *Q_syn_Overl_TDAC_fx,
    2924             :     Word16 *xn_buf_fx, // Q(-2)
    2925             :     Word16 q_xn_buf_fx,
    2926             :     const Word16 *tcx_aldo_window_1_fx,        // Q(15)
    2927             :     const PWord16 *tcx_aldo_window_1_trunc_fx, // Q(15)
    2928             :     const PWord16 *tcx_aldo_window_2_fx,       // Q(15)
    2929             :     const PWord16 *tcx_mdct_window_half_fx,    // Q(15)
    2930             :     const PWord16 *tcx_mdct_window_minimum_fx, // Q(15)
    2931             :     const PWord16 *tcx_mdct_window_trans_fx,   // Q(15)
    2932             :     const Word16 tcx_mdct_window_half_length,  // Q(15)
    2933             :     const Word16 tcx_mdct_window_min_length,   // Q(15)
    2934             :     Word16 index,
    2935             :     const UWord16 kernel_type, /* i  : TCX transform kernel type               */
    2936             :     const Word16 left_rect,
    2937             :     const Word16 tcx_offset,
    2938             :     const Word16 overlap,
    2939             :     const Word16 L_frame,
    2940             :     const Word16 L_frameTCX,
    2941             :     const Word16 L_spec_TCX5,
    2942             :     const Word16 L_frame_glob,
    2943             :     const Word16 frame_cnt,
    2944             :     const Word16 bfi,
    2945             :     Word16 *old_out_fx, // Q(-2)
    2946             :     Word16 *q_old_out_fx,
    2947             :     const Word16 FB_flag,
    2948             :     Decoder_State *st,
    2949             :     const Word16 fullbandScale,
    2950             :     Word16 *acelp_zir_fx,
    2951             :     Word16 *q_acelp_zir_fx,
    2952             :     Word16 *pq_win )
    2953             : {
    2954             :     Word16 i, nz, aldo, w, L_win, L_ola;
    2955             :     Word16 win_fx[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    2956     1698930 :     TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
    2957     1698930 :     TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
    2958             :     Word16 x_e_hdrm;
    2959             :     Word32 c;
    2960             :     Word16 exp;
    2961     1698930 :     Word16 q_win = *pq_win;
    2962     1698930 :     Word16 allow_qwin_change = 1;
    2963     1698930 :     move16();
    2964     1698930 :     move16();
    2965     1698930 :     x_e_hdrm = sub( Q16, q_x );
    2966             : #if 0
    2967             :     IF( *pq_win == 0 )
    2968             :     {
    2969             :         allow_qwin_change = 0;
    2970             :     }
    2971             : #endif
    2972     1698930 :     IF( allow_qwin_change )
    2973             :     {
    2974             :         // q_win = IMDCT_ivas_fx_adjust_qwin( *Q_syn_Overl_TDAC_fx, *Q_old_syn_overl_fx, hTcxDec->Q_old_syn_Overl, *q_old_out_fx, q_win );
    2975     1698930 :         q_win = IMDCT_ivas_fx_calc_qwin( st, syn_Overl_TDAC_fx, *Q_syn_Overl_TDAC_fx, old_syn_overl_fx, *Q_old_syn_overl_fx,
    2976     1698930 :                                          hTcxDec->old_syn_Overl, hTcxDec->Q_old_syn_Overl, old_out_fx, *q_old_out_fx, q_win, FB_flag );
    2977             :     }
    2978             : 
    2979     1698930 :     aldo = 0;
    2980     1698930 :     move16();
    2981             : 
    2982     1698930 :     c = L_mult0( NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), L_frame );
    2983     1698930 :     exp = 0;
    2984     1698930 :     move16();
    2985     1698930 :     nz = BASOP_Util_Divide3216_Scale( c, L_frameTCX, &exp );
    2986     1698930 :     exp = add( exp, ( 31 - 15 ) );
    2987     1698930 :     nz = shr( nz, sub( 15, exp ) ); // Q0
    2988             : 
    2989     1698930 :     test();
    2990     1698930 :     test();
    2991     1698930 :     test();
    2992     1698930 :     test();
    2993     1698930 :     test();
    2994     1698930 :     test();
    2995     1698930 :     IF( st->element_mode != EVS_MONO && ( frame_cnt == 0 ) && ( bfi == 0 ) && ( st->prev_bfi != 0 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && ( hTcxCfg->last_aldo == 0 ) )
    2996             :     {
    2997             :         Word32 fac;
    2998             :         // fac = shl_sat( mult_r( extract_h( L_shr_sat( hTcxDec->conceal_eof_gain32, sub( 1, hTcxDec->conceal_eof_gain_e ) ) ), st->last_concealed_gain_syn_deemph ), 1 );
    2999          30 :         fac = Mpy_32_16_1( hTcxDec->conceal_eof_gain32, st->last_concealed_gain_syn_deemph ); // q = 31 - hTcxDec->conceal_eof_gain_e - last_concealed_gain_syn_deemph_e
    3000          30 :         Word16 eff_e = add( hTcxDec->conceal_eof_gain_e, st->last_concealed_gain_syn_deemph_e );
    3001        6442 :         FOR( Word16 ind = 0; ind < overlap; ind++ )
    3002             :         {
    3003        6412 :             old_syn_overl_fx[ind] = extract_h( L_shl_sat( Mpy_32_16_1( fac, old_syn_overl_fx[ind] ), eff_e ) ); // Q(-2)
    3004        6412 :             move16();
    3005             :         }
    3006             :     }
    3007             : 
    3008     1698930 :     test();
    3009     1698930 :     IF( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && st->tcxonly )
    3010             :     {
    3011             :         /* Mode decision in PLC
    3012             : 
    3013             :         last OL   curr OL   left TCX-10  right TCX-10
    3014             :         -------------------------------------------------------------
    3015             :             0      0         2x TCX-5* 1x  TCX-10
    3016             :             0      2         1x TCX-10 1x  TCX-10
    3017             :             0      3         1x TCX-10 1x  TCX-10
    3018             :             2      0         2x TCX-5  1x  TCX-10
    3019             :             2      2         2x TCX-5  2x  TCX-5
    3020             :             2      3         2x TCX-5  2x  TCX-5
    3021             :             3      0         2x TCX-5  1x  TCX-10
    3022             :             3      2         2x TCX-5  2x  TCX-5
    3023             :             3      3         2x TCX-5  2x  TCX-5
    3024             :         */
    3025       64364 :         test();
    3026       64364 :         test();
    3027       64364 :         test();
    3028       64364 :         test();
    3029       64364 :         test();
    3030       64364 :         test();
    3031       64364 :         IF( ( ( bfi == 0 ) && NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) || ( ( bfi != 0 ) && NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
    3032       18326 :         {
    3033             :             /* minimum or half overlap, two transforms, grouping into one window */
    3034       18326 :             L_win = shr( L_frame, 1 );
    3035             :             // L_ola = EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ? tcx_mdct_window_min_length : tcx_mdct_window_half_length;
    3036       18326 :             IF( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    3037             :             {
    3038        8030 :                 L_ola = tcx_mdct_window_min_length;
    3039             :             }
    3040             :             ELSE
    3041             :             {
    3042       10296 :                 L_ola = tcx_mdct_window_half_length;
    3043             :             }
    3044       18326 :             move16();
    3045             : 
    3046       18326 :             set16_fx( win_fx, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) >> 1 );
    3047       18326 :             Word16 tcx_offset_tmp = add( tcx_offset, shr( L_ola, 1 ) );
    3048       18326 :             set16_fx( xn_buf_fx, 0, tcx_offset_tmp ); /* zero left end of buffer */
    3049             : 
    3050       18326 :             Word16 L_spec_TCX5_tmp = 0;
    3051       18326 :             move16();
    3052       18326 :             IF( allow_qwin_change )
    3053             :             {
    3054             :                 /* Use fixed q_win to avoid the need to adapt scaling of two TCX5 blocks (less effort with maybe not ideal scaling) */
    3055       18326 :                 q_win = -2;
    3056       18326 :                 move16();
    3057       18326 :                 allow_qwin_change = 0;
    3058       18326 :                 move16();
    3059             :             }
    3060             : 
    3061       54978 :             FOR( w = 0; w < 2; w++ )
    3062             :             {
    3063       36652 :                 test();
    3064       36652 :                 test();
    3065       36652 :                 L_spec_TCX5_tmp = imult1616( w, L_spec_TCX5 );
    3066             :                 // Assume that xn_buf_fx has no headroom.
    3067       36652 :                 q_win = s_min( q_xn_buf_fx, q_win );
    3068             : 
    3069       36652 :                 IF( EQ_16( kernel_type, MDST_IV ) || s_and( kernel_type, w ) )
    3070             :                 {
    3071           8 :                     TCX_MDST_Inverse_qwin_fx( x_fx + L_spec_TCX5_tmp, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, &q_win, allow_qwin_change );
    3072             :                 }
    3073       36644 :                 ELSE IF( ( kernel_type != 0 ) && ( w == 0 ) ) /* type 1 or 2 */
    3074             :                 {
    3075          34 :                     TCX_MDXT_Inverse_qwin_fx( x_fx + L_spec_TCX5_tmp, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, kernel_type, &q_win, allow_qwin_change );
    3076             :                 }
    3077             :                 ELSE
    3078             :                 {
    3079       36610 :                     TCX_MDCT_Inverse_qwin_fx( x_fx + L_spec_TCX5_tmp, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode, &q_win, allow_qwin_change );
    3080             :                 }
    3081             : 
    3082       36652 :                 IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
    3083             : 
    3084       36652 :                 tcx_windowing_synthesis_current_frame( win_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, 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_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : (Word8) st->last_is_cng, fullbandScale );
    3085             : 
    3086       36652 :                 IF( w > 0 )
    3087             :                 {
    3088             :                     Word16 tmp;
    3089       18326 :                     tmp = add( sub( tcx_offset, shr( L_ola, 1 ) ), imult1616( w, L_win ) );
    3090       18326 :                     tcx_windowing_synthesis_past_frame( xn_buf_fx + tmp, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, MIN_OVERLAP );
    3091             :                 }
    3092             : 
    3093             :                 /* add part of current sub-window overlapping with previous window */
    3094       36652 :                 v_add_16( win_fx, xn_buf_fx + add( sub( tcx_offset, shr( L_ola, 1 ) ), imult1616( w, L_win ) ), xn_buf_fx + add( sub( tcx_offset, shr( L_ola, 1 ) ), imult1616( w, L_win ) ), L_ola );
    3095             : 
    3096             :                 /* copy new sub-window region not overlapping with previous window */
    3097       36652 :                 Copy( win_fx + L_ola, xn_buf_fx + add( tcx_offset, add( shr( L_ola, 1 ), imult1616( w, L_win ) ) ), L_win );
    3098             :             }
    3099             : 
    3100             :             /* To assure that no garbage values are passed to overlap */
    3101       18326 :             set16_fx( xn_buf_fx + add( L_frame, add( tcx_offset, shr( L_ola, 1 ) ) ), 0, sub( overlap, add( tcx_offset, shr( L_ola, 1 ) ) ) );
    3102       18326 :             test();
    3103       18326 :             test();
    3104       18326 :             test();
    3105       18326 :             IF( ( st->prev_bfi != 0 ) && ( frame_cnt == 0 ) && NE_16( st->last_core, st->last_core_bfi ) && EQ_16( st->last_core_bfi, ACELP_CORE ) )
    3106             :             {
    3107           2 :                 tcx_windowing_synthesis_past_frame( old_syn_overl_fx, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_last_overlap_mode );
    3108           2 :                 v_add_16( xn_buf_fx, old_syn_overl_fx, xn_buf_fx, overlap );
    3109             :             }
    3110             :         }
    3111       46038 :         ELSE IF( ( bfi == 0 ) && ( frame_cnt == 0 ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
    3112       15046 :         {
    3113             :             /* special overlap attempt, two transforms, grouping into one window */
    3114       15046 :             L_win = shr( L_frame, 1 );
    3115       15046 :             L_ola = tcx_mdct_window_min_length;
    3116       15046 :             move16();
    3117             : 
    3118       15046 :             set16_fx( win_fx, 0, shr( add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1 ) );
    3119             : 
    3120             :             /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
    3121             :             Word16 q_win_prev;
    3122             : 
    3123             : #if 0
    3124             :             // Assume that xn_buf_fx has no headroom.
    3125             :             q_win = s_min( q_xn_buf_fx, q_win );
    3126             : #endif
    3127       15046 :             IF( allow_qwin_change )
    3128             :             {
    3129             :                 /* Use fixed q_win to avoid the need to adapt scaling of two TCX5 blocks (less effort with maybe not ideal scaling) */
    3130       15046 :                 q_win = -2;
    3131       15046 :                 move16();
    3132       15046 :                 allow_qwin_change = 0;
    3133       15046 :                 move16();
    3134             :             }
    3135             : 
    3136       15046 :             IF( EQ_16( kernel_type, MDST_IV ) )
    3137             :             {
    3138           0 :                 TCX_MDST_Inverse_qwin_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, &q_win, allow_qwin_change );
    3139             :             }
    3140       15046 :             ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
    3141             :             {
    3142           4 :                 TCX_MDXT_Inverse_qwin_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, kernel_type, &q_win, allow_qwin_change );
    3143             :             }
    3144             :             ELSE
    3145             :             {
    3146       15042 :                 TCX_MDCT_Inverse_qwin_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode, &q_win, allow_qwin_change );
    3147             :             }
    3148       15046 :             q_win_prev = q_win;
    3149             : 
    3150       15046 :             set16_fx( xn_buf_fx, 0, shr( overlap, 1 ) );
    3151             : 
    3152             :             /* copy new sub-window region not overlapping with previous window */
    3153       15046 :             Copy( win_fx + L_win, xn_buf_fx + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
    3154             : 
    3155       15046 :             q_xn_buf_fx = q_win;
    3156       15046 :             move16();
    3157             : 
    3158             :             /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
    3159       15046 :             IF( s_and( kernel_type, 1 ) )
    3160             :             {
    3161           4 :                 TCX_MDST_Inverse_qwin_fx( x_fx + L_spec_TCX5, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, &q_win, allow_qwin_change );
    3162             :             }
    3163             :             ELSE
    3164             :             {
    3165       15042 :                 TCX_MDCT_Inverse_qwin_fx( x_fx + L_spec_TCX5, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode, &q_win, allow_qwin_change );
    3166             :             }
    3167             : 
    3168       15046 :             assert( q_win_prev == q_win );
    3169             : 
    3170       15046 :             IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
    3171             : 
    3172       15046 :             tcx_windowing_synthesis_current_frame( win_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 0,
    3173       15046 :                                                    /* left_rect */ MIN_OVERLAP, /* left_mode */ acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, L_win, ( tcx_offset < 0 ) ? -tcx_offset : 0, 1, /* st->last_mode_bfi */ 0, /* st->last_is_cng */ fullbandScale );
    3174             : 
    3175       15046 :             tcx_windowing_synthesis_past_frame( xn_buf_fx + shr( overlap, 1 ) + sub( L_win, shr( L_ola, 1 ) ), tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 2 );
    3176             : 
    3177             :             /* add part of current sub-window overlapping with previous window */
    3178       15046 :             v_add_16( win_fx, xn_buf_fx + add( shr( overlap, 1 ), sub( L_win, shr( L_ola, 1 ) ) ), xn_buf_fx + sub( add( shr( overlap, 1 ), L_win ), shr( L_ola, 1 ) ), L_ola );
    3179             : 
    3180             :             /* copy new sub-window region not overlapping with previous window */
    3181       15046 :             Copy( win_fx + L_ola, xn_buf_fx + add( add( shr( overlap, 1 ), L_win ), shr( L_ola, 1 ) ), L_win );
    3182             : 
    3183             :             /* extra folding-out on left side of win, for perfect reconstruction */
    3184       15046 :             IF( GE_16( kernel_type, MDCT_II ) )
    3185             :             {
    3186           0 :                 FOR( w = overlap / 2; w < overlap; w++ )
    3187             :                 {
    3188           0 :                     xn_buf_fx[overlap - 1 - w] = xn_buf_fx[w];
    3189           0 :                     move16();
    3190             :                 }
    3191             :             }
    3192             :             ELSE
    3193             :             {
    3194     2319936 :                 FOR( w = overlap / 2; w < overlap; w++ )
    3195             :                 {
    3196     2304890 :                     xn_buf_fx[overlap - 1 - w] = negate( xn_buf_fx[w] );
    3197     2304890 :                     move16();
    3198             :                 }
    3199             :             }
    3200       15046 :             tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, 0, /* left_mode */ acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shl( L_win, 1 ), ( tcx_offset < 0 ) ? -tcx_offset : 0, st->last_core_bfi, (Word8) st->last_is_cng, fullbandScale );
    3201             :         }
    3202             :         ELSE
    3203             :         {
    3204             :             /* default, i.e. maximum overlap, single transform, no grouping */
    3205       30992 :             IF( allow_qwin_change && fullbandScale )
    3206             :             {
    3207       15496 :                 q_win = s_min( q_win, norm_arr( acelp_zir_fx, shr( L_frame_glob, 1 ) ) + *q_acelp_zir_fx );
    3208             :             }
    3209             : 
    3210       30992 :             IF( EQ_16( kernel_type, MDST_IV ) )
    3211             :             {
    3212           8 :                 TCX_MDST_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, &q_win, allow_qwin_change );
    3213             :             }
    3214       30984 :             ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
    3215             :             {
    3216          24 :                 TCX_MDXT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, kernel_type, &q_win, allow_qwin_change );
    3217             :             }
    3218             :             ELSE
    3219             :             {
    3220       30960 :                 TCX_MDCT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, st->element_mode, &q_win, allow_qwin_change );
    3221             :             }
    3222             :             // Because xn_buf_fx is overwritten above.
    3223       30992 :             q_xn_buf_fx = q_win;
    3224       30992 :             move16();
    3225             : 
    3226       30992 :             IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
    3227             : 
    3228       30992 :             IF( !fullbandScale )
    3229             :             {
    3230       15496 :                 *q_acelp_zir_fx = q_xn_buf_fx;
    3231             :             }
    3232             :             ELSE
    3233             :             {
    3234       15496 :                 scale_sig( acelp_zir_fx, shr( L_frame_glob, 1 ), sub( q_xn_buf_fx, *q_acelp_zir_fx ) );
    3235             :             }
    3236       30992 :             tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, !bfi && ( frame_cnt > 0 ) && ( index == 0 ) && NE_16( st->last_core, ACELP_CORE ) ? MIN_OVERLAP : index, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shr( L_frame_glob, 1 ), ( tcx_offset < 0 ) ? -tcx_offset : 0, ( frame_cnt > 0 /*|| (st->last_con_tcx )*/ ) ? 1 : st->last_core_bfi, ( frame_cnt > 0 ) ? 0 : (Word8) st->last_is_cng, fullbandScale );
    3237             : 
    3238             :         } /* tcx_last_overlap_mode != FULL_OVERLAP */
    3239             :     }
    3240             :     ELSE
    3241             :     {
    3242             :         /* frame is TCX-20 or not TCX-only */
    3243     1634566 :         assert( frame_cnt == 0 );
    3244     1634566 :         IF( NE_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    3245             :         {
    3246             : 
    3247             :             Word16 q_tmp_fx_32, q_xn_buf_fx_32;
    3248     1617570 :             q_tmp_fx_32 = 15;
    3249     1617570 :             q_xn_buf_fx_32 = q_x;
    3250     1617570 :             move16();
    3251     1617570 :             move16();
    3252             :             Word32 xn_buf_fx_32[2000], tmp_fx_32[1200], old_out_fx_32[1200];
    3253     1617570 :             set32_fx( xn_buf_fx_32, 0, 2000 );
    3254     1617570 :             IF( NE_16( kernel_type, MDCT_IV ) ) /* inverse transform */
    3255             :             {
    3256        1578 :                 Word16 tmp_a = add( shr( overlap, 1 ), nz );
    3257        1578 :                 IF( EQ_16( kernel_type, MDST_IV ) )
    3258             :                 {
    3259         600 :                     edst_fx( x_fx, xn_buf_fx_32 + tmp_a, L_frame, &q_xn_buf_fx_32 );
    3260             :                 }
    3261             :                 ELSE /* type 1 or 2 */
    3262             :                 {
    3263         978 :                     edxt_fx( x_fx, xn_buf_fx_32 + tmp_a, L_frame, kernel_type, TRUE );
    3264             :                 }
    3265             : 
    3266             :                 Word16 res_m, res_e;
    3267        1578 :                 res_e = 0;
    3268        1578 :                 move16();
    3269        1578 :                 res_m = BASOP_Util_Divide1616_Scale( L_frame, NORM_MDCT_FACTOR, &res_e );
    3270        1578 :                 res_m = Sqrt16( res_m, &res_e );
    3271             : 
    3272      783722 :                 FOR( Word16 ind = 0; ind < L_frame; ind++ )
    3273             :                 {
    3274      782144 :                     tmp_fx_32[ind] = L_shl( Mpy_32_16_1( xn_buf_fx_32[( overlap / 2 ) + nz + ind], res_m ), res_e );
    3275      782144 :                     move32();
    3276             :                 }
    3277        1578 :                 q_tmp_fx_32 = q_xn_buf_fx_32;
    3278        1578 :                 move16();
    3279             : 
    3280             :                 // q_win < norm + q_tmp_fx_32 - 16
    3281        1578 :                 q_win = s_min( q_win, L_norm_arr( tmp_fx_32, L_frame ) + q_tmp_fx_32 - 16 );
    3282        1578 :                 IMDCT_ivas_fx_rescale( NULL, NULL, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
    3283             : 
    3284        1578 :                 Word16 diff = sub( q_tmp_fx_32, q_win );
    3285        1578 :                 Word16 q_old_out_diff = sub( q_tmp_fx_32, *q_old_out_fx );
    3286        1578 :                 IF( q_old_out_diff < 0 )
    3287             :                 {
    3288           0 :                     Scale_sig( old_out_fx, L_frame, q_old_out_diff );
    3289           0 :                     *q_old_out_fx = add( *q_old_out_fx, q_old_out_diff );
    3290           0 :                     q_old_out_diff = 0;
    3291             :                 }
    3292      783722 :                 FOR( Word16 ind = 0; ind < L_frame; ind++ )
    3293             :                 {
    3294      782144 :                     assert( L_shr( L_shl( old_out_fx[ind], q_old_out_diff ), q_old_out_diff ) == old_out_fx[ind] );
    3295      782144 :                     old_out_fx_32[ind] = L_shl( L_deposit_l( old_out_fx[ind] ), q_old_out_diff );
    3296      782144 :                     move32();
    3297             :                 }
    3298             : 
    3299        1578 :                 window_ola_ext_fx( tmp_fx_32, xn_buf_fx_32, old_out_fx_32, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, kernel_type );
    3300             : 
    3301      783722 :                 FOR( Word16 ind = 0; ind < L_frame; ind++ )
    3302             :                 {
    3303      782144 :                     assert( extract_h( L_shr( old_out_fx_32[ind], q_old_out_diff ) ) == 0 || extract_h( L_shr( old_out_fx_32[ind], q_old_out_diff ) ) == -1 );
    3304      782144 :                     old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], q_old_out_diff ) );
    3305      782144 :                     assert( extract_h( L_shr( xn_buf_fx_32[ind], diff ) ) == 0 || extract_h( L_shr( xn_buf_fx_32[ind], diff ) ) == -1 );
    3306      782144 :                     xn_buf_fx[ind] = extract_l( L_shr( xn_buf_fx_32[ind], diff ) );
    3307      782144 :                     move16();
    3308      782144 :                     move16();
    3309             :                 }
    3310             :             }
    3311             :             ELSE
    3312             :             {
    3313     1615992 :                 edct_ivas_fx( x_fx, xn_buf_fx_32 + add( shr( overlap, 1 ), nz ), L_frame, &q_xn_buf_fx_32 );
    3314             :                 Word16 res_m, res_e;
    3315     1615992 :                 res_e = 0;
    3316     1615992 :                 move16();
    3317     1615992 :                 res_m = BASOP_Util_Divide1616_Scale( L_frame, NORM_MDCT_FACTOR, &res_e );
    3318     1615992 :                 res_m = Sqrt16( res_m, &res_e );
    3319             : 
    3320  1107267128 :                 FOR( Word16 ind = 0; ind < L_frame; ind++ )
    3321             :                 {
    3322  1105651136 :                     tmp_fx_32[ind] = Mpy_32_16_1( xn_buf_fx_32[( overlap / 2 ) + nz + ind], res_m );
    3323  1105651136 :                     move32();
    3324             :                 }
    3325     1615992 :                 q_tmp_fx_32 = sub( q_xn_buf_fx_32, res_e );
    3326             :                 // v_multc_fixed( xn_buf_fx_32 + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp_fx_32, L_frame );
    3327             : 
    3328     1615992 :                 if ( allow_qwin_change )
    3329             :                 {
    3330             :                     // sub( q_xn_buf_fx_32, q_win ) == 16 - L_norm_arr( xn_buf_fx_32, L_frame )
    3331             :                     // q_xn_buf_fx_32 - q_win == 16 - L_norm_arr( xn_buf_fx_32, L_frame )
    3332             :                     // q_win == - 16 + L_norm_arr( xn_buf_fx_32, L_frame ) + q_xn_buf_fx_32
    3333     1615992 :                     q_win = s_min( q_win, add( sub( q_xn_buf_fx_32, 16 ), sub( L_norm_arr( xn_buf_fx_32 + ( overlap / 2 ) + nz, L_frame ), 2 ) ) );
    3334             :                 }
    3335     1615992 :                 IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
    3336             : 
    3337     1615992 :                 Word16 q_diff = sub( q_xn_buf_fx_32, q_win );
    3338  1107267128 :                 FOR( Word16 ind = 0; ind < L_frame; ind++ )
    3339             :                 {
    3340  1105651136 :                     assert( extract_h( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) ) == 0 || extract_h( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) ) == -1 );
    3341  1105651136 :                     xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = extract_l( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) );
    3342  1105651136 :                     move16();
    3343             :                 }
    3344             : 
    3345     1615992 :                 window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, q_old_out_fx, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL );
    3346     1615992 :                 if ( allow_qwin_change )
    3347             :                 {
    3348             :                     // sub( q_tmp_fx_32, q_win ) == -norm_arr( xn_buf_fx, L_frame )
    3349             :                     // q_tmp_fx_32 - q_win == -norm_arr( xn_buf_fx, L_frame )
    3350             :                     // q_win == q_tmp_fx_32 + norm_arr( xn_buf_fx, L_frame )
    3351     1615992 :                     q_win = s_min( q_win, add( q_tmp_fx_32, norm_arr( xn_buf_fx, L_frame ) ) );
    3352             :                 }
    3353     1615992 :                 Word16 diff = sub( q_tmp_fx_32, q_win );
    3354  1107267128 :                 FOR( Word16 ind = 0; ind < L_frame; ind++ )
    3355             :                 {
    3356  1105651136 :                     xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], diff );
    3357  1105651136 :                     move16();
    3358             :                 }
    3359             :             }
    3360     1617570 :             aldo = 1;
    3361     1617570 :             move16();
    3362             :         }
    3363             :         ELSE
    3364             :         {
    3365             :             // Word16 acelp_mem_len = tcx_offset < 0 ? -tcx_offset : 0;
    3366             :             Word16 acelp_mem_len;
    3367             : 
    3368       16996 :             IF( tcx_offset < 0 )
    3369             :             {
    3370       16996 :                 acelp_mem_len = negate( tcx_offset );
    3371             :             }
    3372             :             ELSE
    3373             :             {
    3374           0 :                 acelp_mem_len = 0;
    3375           0 :                 move16();
    3376             :             }
    3377             : 
    3378       16996 :             IF( allow_qwin_change && fullbandScale )
    3379             :             {
    3380        8498 :                 q_win = s_min( q_win, norm_arr( acelp_zir_fx, shr( L_frame_glob, 1 ) ) + *q_acelp_zir_fx );
    3381             :             }
    3382       16996 :             IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st->last_core_brate, SID_2k40 ) || st->last_core == ACELP_CORE ) && ( fullbandScale == 0 ) )
    3383             :             {
    3384             :                 /* Increase headroom because if the ACELP ZIR is used below, the synthesis filter gain is unknown. */
    3385        1278 :                 IF( allow_qwin_change )
    3386             :                 {
    3387        1278 :                     allow_qwin_change = 0;
    3388        1278 :                     move16();
    3389        1278 :                     q_win = s_max( -2, sub( q_win, 1 ) );
    3390             :                 }
    3391             :             }
    3392             : 
    3393       16996 :             IF( EQ_16( kernel_type, MDST_IV ) )
    3394             :             {
    3395           0 :                 TCX_MDST_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, &q_win, allow_qwin_change );
    3396             :             }
    3397       16996 :             ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
    3398             :             {
    3399           0 :                 TCX_MDXT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, kernel_type, &q_win, allow_qwin_change );
    3400             :             }
    3401             :             ELSE
    3402             :             {
    3403       16996 :                 TCX_MDCT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, st->element_mode, &q_win, allow_qwin_change );
    3404             :             }
    3405             :             // Because xn_buf_fx is overwritten above.
    3406       16996 :             q_xn_buf_fx = q_win;
    3407       16996 :             move16();
    3408             : 
    3409       16996 :             IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
    3410             :             /*-----------------------------------------------------------*
    3411             :              * Windowing, overlap and add                                *
    3412             :              *-----------------------------------------------------------*/
    3413       16996 :             test();
    3414       16996 :             test();
    3415       16996 :             test();
    3416       16996 :             IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st->last_core_brate, SID_2k40 ) || st->last_core == ACELP_CORE ) && ( fullbandScale == 0 ) )
    3417             :             {
    3418             :                 /* get LPC from that signal part to use for acelp zir smoothing */
    3419        1278 :                 const Word16 analysis_len = shr( L_frame_glob, 2 );
    3420             :                 Word16 buf_fx[L_FRAME_MAX / 4];
    3421             :                 Word16 window_buf_fx[L_FRAME_MAX / 4];
    3422             :                 Word32 r_fx[M + 1];
    3423             :                 Word16 q_r, q_buf;
    3424             : 
    3425             :                 /* get the first 5 ms of non-aliased TCX syntesis */
    3426        1278 :                 Copy( xn_buf_fx + add( shr( overlap, 1 ), shl( acelp_mem_len, 1 ) ), &buf_fx[0], analysis_len );
    3427             : 
    3428        1278 :                 q_buf = q_win;
    3429        1278 :                 move16();
    3430             : 
    3431        1278 :                 ham_cos_window_ivas( &window_buf_fx[0], shr( analysis_len, 1 ), shr( analysis_len, 1 ) );
    3432        1278 :                 autocorr_fx_32( &buf_fx[0], M, &r_fx[0], &q_r, analysis_len, &window_buf_fx[0], 0, 0 );
    3433        1278 :                 lag_wind_32( r_fx, M, L_frame_glob * FRAMES_PER_SEC, LAGW_STRONG );
    3434        1278 :                 lev_dur_fx( &st->old_Aq_12_8_fx_32[0], &r_fx[0], M, NULL, 28 /*Q(st->q_old_Aq_12_8_fx_32)*/, add( add( shl( q_buf, 1 ), q_r ), 1 ) );
    3435       23004 :                 FOR( Word16 ind = 0; ind <= M; ind++ )
    3436             :                 {
    3437       21726 :                     st->old_Aq_12_8_fx[ind] = (Word16) L_shr( st->old_Aq_12_8_fx_32[ind], 16 ); // Q28 -> Q12
    3438       21726 :                     move16();
    3439             :                 }
    3440             :             }
    3441       16996 :             IF( !fullbandScale )
    3442             :             {
    3443        8498 :                 *q_acelp_zir_fx = q_xn_buf_fx;
    3444             :             }
    3445             :             ELSE
    3446             :             {
    3447        8498 :                 scale_sig( acelp_zir_fx, shr( L_frame_glob, 1 ), sub( q_xn_buf_fx, *q_acelp_zir_fx ) );
    3448             :             }
    3449             :             /* Window current frame */
    3450       16996 :             tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, hTcxCfg->tcx_last_overlap_mode, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shr( L_frame_glob, 1 ), acelp_mem_len, st->last_core_bfi, (Word8) st->last_is_cng, fullbandScale );
    3451             :         }
    3452             :     } /* TCX-20 and TCX-only */
    3453     1698930 :     test();
    3454     1698930 :     IF( ( frame_cnt != 0 ) || GT_16( st->last_core_bfi, ACELP_CORE ) )
    3455             :     {
    3456     1667148 :         test();
    3457     1667148 :         test();
    3458     1667148 :         IF( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && ( st->tcxonly != 0 ) ) ||
    3459             :             EQ_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    3460             :         {
    3461       56900 :             test();
    3462       56900 :             test();
    3463       56900 :             test();
    3464       56900 :             test();
    3465       56900 :             if ( ( bfi == 0 ) && ( frame_cnt > 0 ) && ( index == 0 ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && NE_16( st->last_core, ACELP_CORE ) )
    3466             :             {
    3467       15046 :                 index = MIN_OVERLAP; /* use minimum overlap between the two TCX-10 windows */
    3468       15046 :                 move16();
    3469             :             }
    3470             : 
    3471       56900 :             IF( hTcxCfg->last_aldo != 0 )
    3472             :             {
    3473     6022110 :                 FOR( i = 0; i < sub( overlap, tcx_mdct_window_min_length ); i++ )
    3474             :                 {
    3475     5998680 :                     xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )], old_out_fx[( i + nz )] ); // Q(-2)
    3476     5998680 :                     move16();
    3477             :                 }
    3478             : 
    3479             :                 /* fade truncated ALDO window */
    3480       23430 :                 test();
    3481       23430 :                 test();
    3482       23430 :                 test();
    3483       23430 :                 IF( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( frame_cnt == 0 ) && EQ_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) )
    3484             :                 {
    3485             :                     // tested
    3486      646822 :                     FOR( ; i < overlap; i++ ) /* perfectly reconstructing ALDO shortening */
    3487             :                     {
    3488      631944 :                         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], old_out_fx[( i + nz )] ); // q_win
    3489      631944 :                         move16();
    3490             :                     }
    3491      330850 :                     FOR( i = 0; i < ( tcx_mdct_window_min_length / 2 ); i++ )
    3492             :                     {
    3493      315972 :                         xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[i].v.re ) ); // q_win
    3494      315972 :                         move16();
    3495             :                     }
    3496      330850 :                     FOR( ; i < tcx_mdct_window_min_length; i++ )
    3497             :                     {
    3498      315972 :                         xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[( tcx_mdct_window_min_length - ( 1 + i ) )].v.im ) ); // q_win
    3499      315972 :                         move16();
    3500             :                     }
    3501             :                 }
    3502             :                 ELSE
    3503             :                 {
    3504      192470 :                     FOR( ; i < ( overlap - ( tcx_mdct_window_min_length / 2 ) ); i++ )
    3505             :                     {
    3506      183918 :                         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( ( tcx_mdct_window_min_length - overlap ) + i )].v.re ) ); // Q(-2)
    3507      183918 :                         move16();
    3508             :                     }
    3509      192470 :                     FOR( ; i < overlap; i++ )
    3510             :                     {
    3511      183918 :                         xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( overlap - ( 1 + i ) )].v.im ) ); // Q(-2)
    3512      183918 :                         move16();
    3513             :                     }
    3514             :                 }
    3515             :             }
    3516             :             ELSE
    3517             :             {
    3518       33470 :                 tcx_windowing_synthesis_past_frame( old_syn_overl_fx, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( ( index == 0 ) || EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) ? hTcxCfg->tcx_last_overlap_mode : index );
    3519             : 
    3520       33470 :                 IF( bfi != 0 )
    3521             :                 {
    3522        7730 :                     FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ )
    3523             :                     {
    3524        7566 :                         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2)
    3525        7566 :                         move16();
    3526             :                     }
    3527        7730 :                     FOR( ; i < tcx_mdct_window_half_length; i++ )
    3528             :                     {
    3529        7566 :                         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2)
    3530        7566 :                         move16();
    3531             :                     }
    3532             :                 }
    3533       33306 :                 ELSE IF( left_rect == 0 )
    3534             :                 {
    3535    10036614 :                     FOR( i = 0; i < overlap; i++ )
    3536             :                     {
    3537    10003308 :                         xn_buf_fx[i] = add_sat( xn_buf_fx[i], old_syn_overl_fx[i] ); // Q(-2)
    3538    10003308 :                         move16();
    3539             :                     }
    3540             :                 }
    3541             :                 ELSE
    3542             :                 {
    3543           0 :                     FOR( i = 0; i < overlap; i++ )
    3544             :                     {
    3545           0 :                         xn_buf_fx[( i + ( overlap / 2 ) )] = add_sat( xn_buf_fx[( i + ( overlap / 2 ) )], old_syn_overl_fx[i] ); // Q(-2)
    3546           0 :                         move16();
    3547             :                     }
    3548             :                 }
    3549             :             }
    3550             :         }
    3551             :     }
    3552     1698930 :     test();
    3553     1698930 :     test();
    3554     1698930 :     test();
    3555     1698930 :     IF( ( aldo == 0 ) && ( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && ( frame_cnt > 0 ) ) || NE_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
    3556             :     {
    3557             :         /* Compute windowed synthesis in case of switching to ALDO windows in next frame */
    3558       49178 :         Copy( xn_buf_fx + sub( L_frame, nz ), old_out_fx, add( nz, overlap ) );
    3559       49178 :         set16_fx( old_out_fx + add( nz, overlap ), 0, nz );
    3560       49178 :         *q_old_out_fx = q_win;
    3561       49178 :         tcx_windowing_synthesis_past_frame( old_out_fx + nz, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_curr_overlap_mode );
    3562             : 
    3563             :         /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
    3564       49178 :         IF( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
    3565             :         {
    3566       37912 :             IF( s_and( kernel_type, 1 ) )
    3567             :             {
    3568        1522 :                 FOR( i = 0; i < nz; i++ )
    3569             :                 {
    3570        1512 :                     old_out_fx[( ( nz + overlap ) + i )] = negate( mult_r( xn_buf_fx[( L_frame - ( 1 + i ) )], tcx_aldo_window_1_fx[( nz - ( 1 + i ) )] ) ); // Q(-2)
    3571        1512 :                     move16();
    3572             :                 }
    3573             :             }
    3574             :             ELSE
    3575             :             {
    3576     6946770 :                 FOR( i = 0; i < nz; i++ )
    3577             :                 {
    3578     6908868 :                     old_out_fx[( ( nz + overlap ) + i )] = mult_r( xn_buf_fx[( L_frame - ( 1 + i ) )], tcx_aldo_window_1_fx[( nz - ( 1 + i ) )] ); // Q(-2)
    3579     6908868 :                     move16();
    3580             :                 }
    3581             :             }
    3582       37912 :             aldo = 1;
    3583       37912 :             move16();
    3584             :         }
    3585             :     }
    3586             : 
    3587     1698930 :     if ( FB_flag != 0 )
    3588             :     {
    3589      849465 :         hTcxCfg->last_aldo = aldo;
    3590      849465 :         move16();
    3591             :     }
    3592             : 
    3593             :     /* Smoothing between the ACELP PLC and TCX Transition frame. Using the shape of the half overlap window for the crossfading. */
    3594     1698930 :     test();
    3595     1698930 :     test();
    3596     1698930 :     test();
    3597     1698930 :     IF( ( left_rect != 0 ) && ( frame_cnt == 0 ) && st->last_core_bfi == ACELP_CORE && ( st->prev_bfi != 0 ) ){
    3598         188 :         IF( FB_flag != 0 ){
    3599        6694 :             FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ ){
    3600        6600 :                 xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[i].v.im );                                                                    // Q(-2)
    3601        6600 :     xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_OverlFB[i], tcx_mdct_window_half_fx[i].v.re ), tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2)
    3602        6600 :     move16();
    3603        6600 :     move16();
    3604             : }
    3605        6694 : FOR( ; i < tcx_mdct_window_half_length; i++ )
    3606             : {
    3607        6600 :     xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.re );                                                                                                                          // Q(-2)
    3608        6600 :     xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_OverlFB[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ), tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2)
    3609        6600 :     move16();
    3610        6600 :     move16();
    3611             : }
    3612             : }
    3613             : ELSE
    3614             : {
    3615        3700 :     FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ )
    3616             :     {
    3617        3606 :         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[i].v.im );
    3618        3606 :         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[i].v.re ), tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2)
    3619        3606 :         move16();
    3620        3606 :         move16();
    3621             :     }
    3622        3700 :     FOR( ; i < tcx_mdct_window_half_length; i++ )
    3623             :     {
    3624        3606 :         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.re );
    3625        3606 :         xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ), tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2)
    3626        3606 :         move16();
    3627        3606 :         move16();
    3628             :     }
    3629             : }
    3630             : }
    3631     1698930 : *pq_win = q_win;
    3632     1698930 : move16();
    3633             : 
    3634     1698930 : return;
    3635             : }
    3636             : 
    3637     2521239 : void init_tcx_info_fx(
    3638             :     Decoder_State *st,            /* i/o: coder memory state                                               */
    3639             :     const Word16 L_frame_glob,    /* i  : global frame length                                              */
    3640             :     const Word16 L_frameTCX_glob, /* i  : FB global frame length                                           */
    3641             :     const Word16 frame_cnt,       /* i  : frame counter in the super_frame                                 */
    3642             :     const Word16 bfi,             /* i  : bad frame indicator                                              */
    3643             :     Word16 *tcx_offset,           /* o  : folding point offset relative to the end of the previous frame   */
    3644             :     Word16 *tcx_offsetFB,         /* o  : FB folding point offset relative to the end of the previous frame*/
    3645             :     Word16 *L_frame,              /* o  : frame length                                                     */
    3646             :     Word16 *L_frameTCX,           /* o  : TCX frame length                                                 */
    3647             :     Word16 *left_rect,            /* o  : left part is rectangular                                         */
    3648             :     Word16 *L_spec                /* o  : spectrum length                                                  */
    3649             : )
    3650             : {
    3651     2521239 :     TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
    3652     2521239 :     TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
    3653             : 
    3654             :     /* Init lengths */
    3655     2521239 :     *tcx_offset = hTcxCfg->tcx_offset;
    3656     2521239 :     *tcx_offsetFB = hTcxCfg->tcx_offsetFB;
    3657     2521239 :     move16();
    3658     2521239 :     move16();
    3659             : 
    3660     2521239 :     IF( bfi )
    3661             :     {
    3662             :         /* PLC: [TCX: Memory update]
    3663             :          * PLC: Init buffers */
    3664             : 
    3665       27815 :         assert( st->L_frame_past > 0 );
    3666       27815 :         *L_frame = st->L_frame_past;
    3667       27815 :         move16();
    3668       27815 :         *L_frameTCX = st->L_frameTCX_past;
    3669       27815 :         move16();
    3670             : 
    3671       27815 :         *left_rect = hTcxDec->prev_widow_left_rect;
    3672       27815 :         move16();
    3673             : 
    3674       27815 :         IF( *left_rect )
    3675             :         {
    3676         188 :             *tcx_offset = hTcxCfg->lfacNext;
    3677         188 :             move16();
    3678         188 :             *tcx_offsetFB = hTcxCfg->lfacNextFB;
    3679         188 :             move16();
    3680         188 :             *L_spec = add( *L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
    3681             :         }
    3682             :     }
    3683             :     ELSE
    3684             :     {
    3685     2493424 :         test();
    3686     2493424 :         IF( frame_cnt == 0 && st->last_core == ACELP_CORE )
    3687             :         {
    3688       12395 :             if ( !st->prev_bfi )
    3689             :             {
    3690       12173 :                 hTcxCfg->last_aldo = 0;
    3691       12173 :                 move16();
    3692             :             }
    3693             : 
    3694             :             /* if past frame is ACELP */
    3695       12395 :             *L_frame = add( L_frame_glob, *tcx_offset );
    3696       12395 :             *L_frameTCX = add( L_frameTCX_glob, *tcx_offsetFB );
    3697       12395 :             move16();
    3698       12395 :             move16();
    3699       12395 :             IF( EQ_16( st->last_core, st->last_core_from_bs ) )
    3700             :             {
    3701             :                 /* case: last frame was lost and concealed as CNG */
    3702             :                 /* using the longer transition spec length causes reading of uninitialized data */
    3703       12287 :                 *L_spec = add( *L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
    3704       12287 :                 move16();
    3705             :             }
    3706             : 
    3707       12395 :             assert( hTcxCfg->lfacNext <= 0 );
    3708       12395 :             *L_frame = sub( *L_frame, hTcxCfg->lfacNext );
    3709       12395 :             *L_frameTCX = sub( *L_frameTCX, hTcxCfg->lfacNextFB );
    3710       12395 :             *tcx_offset = hTcxCfg->lfacNext;
    3711       12395 :             move16();
    3712       12395 :             move16();
    3713       12395 :             move16();
    3714       12395 :             *tcx_offsetFB = hTcxCfg->lfacNextFB;
    3715       12395 :             move16();
    3716             : 
    3717       12395 :             *left_rect = 1;
    3718       12395 :             move16();
    3719       12395 :             hTcxDec->prev_widow_left_rect = 1;
    3720       12395 :             move16();
    3721             :         }
    3722             :         ELSE
    3723             :         {
    3724     2481029 :             *L_frame = L_frame_glob;
    3725     2481029 :             move16();
    3726     2481029 :             *L_frameTCX = L_frameTCX_glob;
    3727     2481029 :             move16();
    3728     2481029 :             *left_rect = 0;
    3729     2481029 :             move16();
    3730     2481029 :             hTcxDec->prev_widow_left_rect = 0;
    3731     2481029 :             move16();
    3732             :         }
    3733             : 
    3734     2493424 :         st->L_frame_past = *L_frame;
    3735     2493424 :         move16();
    3736     2493424 :         st->L_frameTCX_past = *L_frameTCX;
    3737     2493424 :         move16();
    3738             :     }
    3739             : 
    3740     2521239 :     IF( st->igf )
    3741             :     {
    3742     1652958 :         test();
    3743     1652958 :         IF( EQ_16( *L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly ) )
    3744             :         {
    3745       75319 :             IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_SHORT );
    3746             :         }
    3747             :         ELSE
    3748             :         {
    3749     1577639 :             test();
    3750     1577639 :             test();
    3751     1577639 :             IF( st->last_core == ACELP_CORE || ( *left_rect && st->bfi ) )
    3752             :             {
    3753       10681 :                 IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_TRAN );
    3754             :             }
    3755             :             ELSE
    3756             :             {
    3757     1566958 :                 IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_NORM );
    3758             :             }
    3759             :         }
    3760             :     }
    3761     2521239 : }
    3762             : 
    3763             : 
    3764             : /*-------------------------------------------------------------------*
    3765             :  *  decoder_tcx_IGF_mono_fx()
    3766             :  *
    3767             :  *  TCX: apply mono IGF
    3768             :  *-------------------------------------------------------------------*/
    3769             : 
    3770      190686 : void decoder_tcx_IGF_mono_fx(
    3771             :     Decoder_State *st,      /* i/o: coder memory state                 */
    3772             :     Word32 x_fx[],          /* o  : de-quatized coefficients           */
    3773             :     Word16 *x_e,            /* o  : de-quatized coefficients exponent  */
    3774             :     Word16 *x_len,          /* o  : de-quatized coefficients length    */
    3775             :     const Word16 L_frame,   /* i  : frame length                       */
    3776             :     const Word16 left_rect, /* i  : left part is rectangular           */
    3777             :     const Word16 bfi,       /* i  : bad frame indicator                */
    3778             :     const Word16 frame_cnt  /* i  : frame counter in the super_frame   */
    3779             : )
    3780             : {
    3781             :     Word16 igfGridIdx;
    3782             : 
    3783      190686 :     test();
    3784      190686 :     IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly ) )
    3785             :     {
    3786        9692 :         igfGridIdx = IGF_GRID_LB_SHORT;
    3787        9692 :         move16();
    3788             :     }
    3789             :     ELSE
    3790             :     {
    3791      180994 :         test();
    3792      180994 :         IF( ( EQ_16( st->last_core, ACELP_CORE ) || left_rect ) )
    3793             :         {
    3794         956 :             igfGridIdx = IGF_GRID_LB_TRAN;
    3795         956 :             move16();
    3796             :         }
    3797             :         ELSE
    3798             :         {
    3799      180038 :             igfGridIdx = IGF_GRID_LB_NORM;
    3800      180038 :             move16();
    3801             :         }
    3802             :     }
    3803             : 
    3804      190686 :     IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, igfGridIdx );
    3805             : 
    3806      190686 :     IF( st->igf )
    3807             :     {
    3808      190686 :         igfGridIdx = IGF_GRID_LB_SHORT;
    3809      190686 :         move16();
    3810             :         /*st->hIGFDec.igfData.igfInfo.nfSeed = (int16_t)(*nf_seed * 31821L + 13849L);*/
    3811             : 
    3812      190686 :         test();
    3813      190686 :         IF( NE_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly )
    3814             :         {
    3815      180994 :             test();
    3816      180994 :             test();
    3817      180994 :             IF( EQ_16( st->last_core, ACELP_CORE ) || ( left_rect && bfi ) )
    3818             :             {
    3819         956 :                 igfGridIdx = IGF_GRID_LB_TRAN;
    3820         956 :                 move16();
    3821             :             }
    3822             :             ELSE
    3823             :             {
    3824      180038 :                 igfGridIdx = IGF_GRID_LB_NORM;
    3825      180038 :                 move16();
    3826             :             }
    3827             :         }
    3828             : 
    3829      190686 :         IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, igfGridIdx, bfi, st->element_mode );
    3830             : 
    3831      190686 :         *x_len = st->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
    3832      190686 :         move16();
    3833             :     }
    3834             : 
    3835      190686 :     return;
    3836             : }
    3837             : 
    3838             : 
    3839       86792 : void decoder_tcx_IGF_stereo_fx(
    3840             :     Decoder_State **sts,                     /* i/o: coder memory states                    */
    3841             :     STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo structure                  */
    3842             :     Word16 ms_mask[NB_DIV][MAX_SFB],         /* i  : bandwise MS mask                       */
    3843             :     Word32 *x_fx[CPE_CHANNELS][NB_DIV],      /* i/o: de-quatized coefficients               */
    3844             :     Word16 x_e[CPE_CHANNELS][NB_DIV],        /* i/o: de-quatized coefficients exponents     */
    3845             :     Word16 x_len[CPE_CHANNELS][NB_DIV],      /* o  : length of de-quantized coefficients    */
    3846             :     const Word16 L_frame,                    /* i  : frame length                           */
    3847             :     const Word16 left_rect,                  /* i  : left part is rectangular               */
    3848             :     const Word16 k,                          /* i  : Subframe index                         */
    3849             :     const Word16 bfi,                        /* i  : bad frame indicator                    */
    3850             :     const Word16 MCT_flag                    /* i  : hMCT handle allocated (1) or not (0)   */
    3851             : )
    3852             : {
    3853             :     Word16 coreMsMask[N_MAX];
    3854             :     STEREO_MDCT_BAND_PARAMETERS *sfbConf;
    3855             :     Word16 core, sfb, igfGridIdx, restrict_hopsize;
    3856             : 
    3857       86792 :     core = sts[0]->core;
    3858       86792 :     move16();
    3859             : 
    3860             :     /* assumptions: stereo filling was already done on the flattened spectra
    3861             :      *               IGF region is always coded M/S, never L/R (to be done in the encoder)
    3862             :      *               for residual bands with stereo filling infoTcxNoise is set to zero
    3863             :      *               both channels have the same IGF configuration
    3864             :      */
    3865             : 
    3866             : 
    3867             :     /* initialization */
    3868       86792 :     IF( EQ_16( core, TCX_20_CORE ) )
    3869             :     {
    3870       82325 :         sfbConf = &hStereoMdct->stbParamsTCX20;
    3871             :     }
    3872             :     ELSE
    3873             :     {
    3874        4467 :         sfbConf = &hStereoMdct->stbParamsTCX10;
    3875             :     }
    3876             : 
    3877       86792 :     if ( EQ_16( sts[0]->last_core, ACELP_CORE ) )
    3878             :     {
    3879           8 :         sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
    3880             :     }
    3881             : 
    3882             :     /* create line wise ms mask for the core bands */
    3883       86792 :     set16_fx( coreMsMask, 0, N_MAX );
    3884             : 
    3885     3681862 :     FOR( sfb = 0; sfb < sfbConf->sfbCnt; sfb++ )
    3886             :     {
    3887     3595070 :         set16_fx( &coreMsMask[sfbConf->sfbOffset[sfb]], ms_mask[k][sfb], sub( sfbConf->sfbOffset[sfb + 1], sfbConf->sfbOffset[sfb] ) );
    3888             :     }
    3889             : 
    3890       86792 :     test();
    3891       86792 :     IF( EQ_16( L_frame, shr( sts[0]->L_frame, 1 ) ) && ( sts[0]->tcxonly ) )
    3892             :     {
    3893        4467 :         igfGridIdx = IGF_GRID_LB_SHORT;
    3894        4467 :         move16();
    3895             :     }
    3896             :     ELSE
    3897             :     {
    3898       82325 :         test();
    3899       82325 :         IF( EQ_16( sts[0]->last_core, ACELP_CORE ) || left_rect )
    3900             :         {
    3901           8 :             igfGridIdx = IGF_GRID_LB_TRAN;
    3902           8 :             move16();
    3903             :         }
    3904             :         ELSE
    3905             :         {
    3906       82317 :             igfGridIdx = IGF_GRID_LB_NORM;
    3907       82317 :             move16();
    3908             :         }
    3909             :     }
    3910       86792 :     IGFDecUpdateInfo_ivas_fx( sts[0]->hIGFDec, k, igfGridIdx );
    3911             : 
    3912       86792 :     test();
    3913       86792 :     IF( EQ_16( L_frame, shr( sts[1]->L_frame, 1 ) ) && ( sts[1]->tcxonly ) )
    3914             :     {
    3915        4467 :         igfGridIdx = IGF_GRID_LB_SHORT;
    3916        4467 :         move16();
    3917             :     }
    3918             :     ELSE
    3919             :     {
    3920       82325 :         test();
    3921       82325 :         IF( EQ_16( sts[1]->last_core, ACELP_CORE ) || left_rect )
    3922             :         {
    3923           8 :             igfGridIdx = IGF_GRID_LB_TRAN;
    3924           8 :             move16();
    3925             :         }
    3926             :         ELSE
    3927             :         {
    3928       82317 :             igfGridIdx = IGF_GRID_LB_NORM;
    3929       82317 :             move16();
    3930             :         }
    3931             :     }
    3932       86792 :     IGFDecUpdateInfo_ivas_fx( sts[1]->hIGFDec, k, igfGridIdx );
    3933             : 
    3934             : 
    3935       86792 :     IF( sts[0]->igf )
    3936             :     {
    3937       86792 :         igfGridIdx = IGF_GRID_LB_SHORT;
    3938       86792 :         move16();
    3939       86792 :         test();
    3940       86792 :         IF( NE_16( L_frame, shr( sts[0]->L_frame, 1 ) ) && ( sts[0]->tcxonly ) )
    3941             :         {
    3942       82325 :             test();
    3943       82325 :             IF( EQ_16( sts[0]->last_core, ACELP_CORE ) || ( left_rect && bfi ) )
    3944             :             {
    3945           8 :                 igfGridIdx = IGF_GRID_LB_TRAN;
    3946           8 :                 move16();
    3947             :             }
    3948             :             ELSE
    3949             :             {
    3950       82317 :                 igfGridIdx = IGF_GRID_LB_NORM;
    3951       82317 :                 move16();
    3952             :             }
    3953             :         }
    3954             : 
    3955       86792 :         restrict_hopsize = 0;
    3956       86792 :         move16();
    3957       86792 :         if ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
    3958             :         {
    3959       14029 :             restrict_hopsize = 1;
    3960       14029 :             move16();
    3961             :         }
    3962             : 
    3963       86792 :         IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x_fx[0][k], &x_e[0][k], x_fx[1][k], &x_e[1][k], igfGridIdx, coreMsMask, restrict_hopsize, bfi, MCT_flag );
    3964             : 
    3965       86792 :         x_len[0][k] = sts[0]->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
    3966       86792 :         move16();
    3967       86792 :         x_len[1][k] = sts[1]->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
    3968       86792 :         move16();
    3969             :     }
    3970             : 
    3971       86792 :     return;
    3972             : }
    3973             : 
    3974             : 
    3975      221229 : void decoder_tcx_ivas_fx(
    3976             :     Decoder_State *st,
    3977             :     Word16 prm[],
    3978             :     Word16 A_fx[],       // Q: 14 - norm_s(A_fx[0])
    3979             :     Word16 Aind[],       // Q: 14 - norm_s(Aind[0])
    3980             :     Word16 synth_fx[],   // Q_syn
    3981             :     Word16 synthFB_fx[], // Q_syn
    3982             :     const Word16 bfi,
    3983             :     const Word16 frame_cnt,
    3984             :     const Word16 sba_dirac_stereo_flag )
    3985             : {
    3986             :     Word32 x_fx[N_MAX];
    3987             :     Word16 x_e;
    3988             :     Word16 gainlpc2_fx[FDNS_NPTS];
    3989             :     Word16 gainlpc2_e[FDNS_NPTS];
    3990             :     Word16 gain_tcx_e, gain_tcx_fx;
    3991             :     Word16 fUseTns, L_frame_glob, L_frameTCX_glob;
    3992             :     STnsData tnsData;
    3993             :     Word16 tcx_offset, tcx_offsetFB, L_frame, L_frameTCX;
    3994             :     Word16 left_rect, L_spec, tmp_concealment_method, nf_seed;
    3995             :     const Word16 *prm_sqQ;
    3996             :     Word16 xn_buf_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* Q14 */
    3997             :     Word16 shift;
    3998             :     Word16 x_len;
    3999             :     Word16 q_x;
    4000      221229 :     q_x = Q11;
    4001      221229 :     move16();
    4002      221229 :     x_e = 30;
    4003      221229 :     move16();
    4004      221229 :     gain_tcx_e = 0;
    4005      221229 :     gain_tcx_fx = 0;
    4006      221229 :     move16();
    4007      221229 :     move16();
    4008      221229 :     set32_fx( x_fx, 0, N_MAX );
    4009      221229 :     set16_fx( gainlpc2_fx, 0, FDNS_NPTS );
    4010      221229 :     set16_fx( gainlpc2_e, 0, FDNS_NPTS );
    4011             : 
    4012      221229 :     L_spec = st->hTcxCfg->tcx_coded_lines;
    4013      221229 :     move16();
    4014      221229 :     L_frame_glob = st->L_frame;
    4015      221229 :     move16();
    4016      221229 :     L_frameTCX_glob = st->hTcxDec->L_frameTCX;
    4017      221229 :     move16();
    4018      221229 :     IF( EQ_16( st->core, TCX_10_CORE ) )
    4019             :     {
    4020        3894 :         L_spec = shr( L_spec, 1 );
    4021        3894 :         L_frame_glob = shr( L_frame_glob, 1 );
    4022        3894 :         L_frameTCX_glob = shr( L_frameTCX_glob, 1 );
    4023             :     }
    4024             : 
    4025      221229 :     tmp_concealment_method = 0;
    4026      221229 :     move16();
    4027      221229 :     nf_seed = 0;
    4028      221229 :     move16();
    4029      221229 :     fUseTns = 0; /* flag that is set if TNS data is present */
    4030      221229 :     move16();
    4031             : 
    4032      221229 :     set16_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX );
    4033             : 
    4034      221229 :     init_tcx_info_fx( st, L_frame_glob, L_frameTCX_glob, frame_cnt, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec );
    4035             : 
    4036      221229 :     decoder_tcx_invQ_fx( st, prm, A_fx, Aind, L_spec, L_frame, L_frameTCX, x_fx, &x_e, gainlpc2_fx, gainlpc2_e, &xn_buf_fx[0], &fUseTns, &tnsData, &gain_tcx_fx, &gain_tcx_e, &prm_sqQ, &nf_seed, bfi, frame_cnt );
    4037             : 
    4038      221229 :     shift = Find_Max_Norm32( x_fx, N_MAX );
    4039      221229 :     Scale_sig32( x_fx, N_MAX, shift );
    4040      221229 :     x_e = sub( x_e, shift );
    4041             : 
    4042      221229 :     decoder_tcx_noisefilling_fx( st, NULL, 0, A_fx, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, x_fx, &x_e, gainlpc2_fx, gainlpc2_e, &tmp_concealment_method, gain_tcx_fx, gain_tcx_e, prm_sqQ, nf_seed, bfi, 0, frame_cnt );
    4043             : 
    4044      221229 :     decoder_tcx_noiseshaping_igf_fx( st, L_spec, L_frame, L_frameTCX, left_rect, x_fx, &x_e, &x_len, gainlpc2_fx, gainlpc2_e, &tmp_concealment_method, bfi );
    4045             : 
    4046      221229 :     shift = sub( Find_Max_Norm32( x_fx, N_MAX ), 6 ); // 6 -> guardbits//
    4047      221229 :     Scale_sig32( x_fx, N_MAX, shift );
    4048      221229 :     x_e = sub( x_e, shift );
    4049             : 
    4050      221229 :     decoder_tcx_tns_fx( st, L_frame_glob, L_spec, L_frame, L_frameTCX, x_fx, fUseTns, &tnsData, bfi, frame_cnt, 0, NULL );
    4051             : 
    4052      221229 :     Scale_sig32( x_fx, N_MAX, sub( x_e, 20 ) );                                                     // Scaling x_fx to Q11
    4053      221229 :     Scale_sig( xn_buf_fx, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX, sub( st->Q_syn, 14 ) ); // Scaling xn_buf_fx to Q_syn
    4054      221229 :     x_e = sub( 31, 11 );
    4055             : 
    4056      221229 :     IF( st->igf != 0 )
    4057             :     {
    4058      210461 :         Scale_sig32( st->hIGFDec->virtualSpec, ( N_MAX_TCX - IGF_START_MN ), ( sub( st->hIGFDec->virtualSpec_e, x_e ) ) );
    4059      210461 :         st->hIGFDec->virtualSpec_e = x_e;
    4060      210461 :         move16();
    4061             :     }
    4062             : 
    4063      221229 :     Copy_Scale_sig_16_32_no_sat( st->old_Aq_12_8_fx, st->old_Aq_12_8_fx_32, M + 1, ( sub( 28, ( sub( 15, norm_s( sub( st->old_Aq_12_8_fx[0], 1 ) ) ) ) ) ) );
    4064             : 
    4065             :     Word16 q_win, q_winFB;
    4066             : 
    4067      221229 :     q_win = st->Q_syn;
    4068      221229 :     move16();
    4069      221229 :     q_winFB = st->Q_syn;
    4070      221229 :     move16();
    4071             : 
    4072      221229 :     assert( q_win == 0 );
    4073             : 
    4074      221229 :     Scale_sig( synth_fx, L_frame_glob, sub( q_win, st->Q_syn ) );        // Scaling to Q_syn
    4075      221229 :     Scale_sig( synthFB_fx, L_frameTCX_glob, sub( q_winFB, st->Q_syn ) ); // Scaling to Q_syn
    4076             : 
    4077      221229 :     decoder_tcx_imdct_fx( st, L_frame_glob, L_frameTCX_glob, L_spec, tcx_offset, tcx_offsetFB, L_frame, L_frameTCX, left_rect, &x_fx[0], q_x, xn_buf_fx, &q_win, &q_winFB, MDCT_IV,
    4078             :                           fUseTns, &synth_fx[0], &synthFB_fx[0], bfi, frame_cnt, sba_dirac_stereo_flag );
    4079             : 
    4080             :     /* Scaling up again */
    4081      221229 :     Scale_sig( synth_fx, L_frame_glob, sub( st->Q_syn, q_win ) );
    4082      221229 :     Scale_sig( synthFB_fx, L_frameTCX_glob, sub( st->Q_syn, q_winFB ) );
    4083             :     // Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, 1 );
    4084             : 
    4085      221229 :     Scale_sig( st->hTcxDec->old_syn_Overl, 320, ( -2 - st->hTcxDec->Q_old_syn_Overl ) ); // Scaling to Q-2
    4086      221229 :     st->hTcxDec->Q_old_syn_Overl = -2;
    4087      221229 : }
    4088             : 
    4089             : /*-------------------------------------------------------------------*
    4090             :  * decoder_tcx_invQ_fx
    4091             :  *
    4092             :  * TCX: inverse quantization
    4093             :  *-------------------------------------------------------------------*/
    4094      853209 : void decoder_tcx_invQ_fx(
    4095             :     Decoder_State *st, /* i/o: coder memory state                      */
    4096             :     int16_t prm[],     /* i  : parameters                              */
    4097             :     Word16 A[],        /* i  : coefficients NxAz[M+1]                  */
    4098             :     Word16 Aind[],     /* i  : frame-independent coefficients Az[M+1]  */
    4099             :     const Word16 L_spec,
    4100             :     const Word16 L_frame,
    4101             :     const Word16 L_frameTCX,
    4102             :     Word32 x[],
    4103             :     Word16 *x_e,
    4104             :     Word16 gainlpc2[],
    4105             :     Word16 gainlpc2_e[],
    4106             :     Word16 xn_buf[], /* Q14 */
    4107             :     Word16 *fUseTns, /* o  : flag that is set if TNS data is present */
    4108             :     STnsData *tnsData,
    4109             :     Word16 *gain_tcx,
    4110             :     Word16 *gain_tcx_e,
    4111             :     const Word16 **prm_sqQ1,
    4112             :     Word16 *nf_seed,
    4113             :     const Word16 bfi,      /* i  : Bad frame indicator                     */
    4114             :     const Word16 frame_cnt /* i  : frame counter in the super frame        */
    4115             : )
    4116             : {
    4117             :     Word16 i, index;
    4118             :     Word16 start_zeroing;
    4119             :     Word16 Ap[M + 2];
    4120             : 
    4121             :     Word16 noiseFillingSize;
    4122             :     Word16 tnsSize; /* number of tns parameters put into prm   */
    4123             : 
    4124             :     Word16 gamma1; /* Q15 */
    4125             :     Word16 gamma;  /* Q15 */
    4126             :     Word16 mem[M];
    4127             :     Word16 gainCompensate, gainCompensate_e;
    4128             :     Word16 h1[L_SUBFR + 1];
    4129             :     Word16 tmp1, tmp2;
    4130             :     Word32 tmp32;
    4131             :     Word16 s;
    4132             : 
    4133             :     Word16 arith_bits, signaling_bits;
    4134             :     Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_sqQ, *prm_target;
    4135      853209 :     TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
    4136      853209 :     TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
    4137      853209 :     TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
    4138             : 
    4139      853209 :     gainCompensate = 0;
    4140      853209 :     gainCompensate_e = 0;
    4141      853209 :     move16();
    4142      853209 :     move16();
    4143             : 
    4144             : 
    4145      853209 :     tnsSize = 0;
    4146      853209 :     move16();
    4147             :     /* just to suppress MSVC warnigs */
    4148      853209 :     prm_target = NULL;
    4149      853209 :     prm_ltp = NULL;
    4150      853209 :     prm_tns = NULL;
    4151      853209 :     prm_sqQ = NULL;
    4152             : 
    4153             :     /*-----------------------------------------------------------------*
    4154             :      * Initializations
    4155             :      *-----------------------------------------------------------------*/
    4156             : 
    4157             :     /* Init lengths */
    4158      853209 :     gamma1 = st->gamma;
    4159      853209 :     move16();
    4160             : 
    4161      853209 :     if ( hTcxDec->enableTcxLpc != 0 )
    4162             :     {
    4163       14170 :         gamma1 = MAX16B;
    4164       14170 :         move16();
    4165             :     }
    4166             : 
    4167      853209 :     noiseFillingSize = L_spec;
    4168      853209 :     move16();
    4169      853209 :     if ( st->igf != 0 )
    4170             :     {
    4171      574731 :         noiseFillingSize = st->hIGFDec->infoIGFStartLine;
    4172      574731 :         move16();
    4173             :     }
    4174             : 
    4175             : 
    4176      853209 :     gainCompensate = ONE_IN_Q14;
    4177      853209 :     move16();
    4178      853209 :     gainCompensate_e = 1;
    4179      853209 :     move16();
    4180             : 
    4181             :     /*-----------------------------------------------------------*
    4182             :      * Read TCX parameters                                       *
    4183             :      *-----------------------------------------------------------*/
    4184             : 
    4185      853209 :     index = 0;
    4186      853209 :     move16();
    4187             : 
    4188      853209 :     IF( !bfi )
    4189             :     {
    4190      844504 :         prm_ltp = &prm[1 + NOISE_FILL_RANGES];
    4191      844504 :         prm_tns = prm_ltp + LTPSIZE;
    4192      844504 :         index = prm[0];
    4193      844504 :         move16();
    4194             : 
    4195             :         /* read noise level (fac_ns) */
    4196      844504 :         st->hTcxDec->noise_filling_index[frame_cnt] = prm[1];
    4197      844504 :         move16();
    4198             :     }
    4199             : 
    4200             :     /* read TNS data */
    4201      853209 :     test();
    4202      853209 :     IF( !bfi && hTcxCfg->fIsTNSAllowed )
    4203             :     {
    4204      777484 :         *fUseTns = DecodeTnsData_ivas_fx( hTcxCfg->pCurrentTnsConfig, prm_tns, &tnsSize, tnsData );
    4205      777484 :         move16();
    4206             :     }
    4207             :     ELSE
    4208             :     {
    4209       75725 :         *fUseTns = 0;
    4210       75725 :         move16();
    4211             :     }
    4212             : 
    4213             : 
    4214             :     /*-----------------------------------------------------------*
    4215             :      * Spectrum data                                             *
    4216             :      *-----------------------------------------------------------*/
    4217             : 
    4218      853209 :     IF( !bfi )
    4219             :     {
    4220      844504 :         prm_hm = prm_tns + tnsSize;
    4221      844504 :         prm_sqQ = prm_hm + NPRM_CTX_HM;
    4222      844504 :         *prm_sqQ1 = prm_sqQ;
    4223             :         /*-----------------------------------------------------------*
    4224             :          * Context HM                                                *
    4225             :          *-----------------------------------------------------------*/
    4226      844504 :         test();
    4227      844504 :         test();
    4228      844504 :         IF( hTcxCfg->ctx_hm && ( ( st->last_core_from_bs != ACELP_CORE ) || ( frame_cnt > 0 ) ) )
    4229             :         {
    4230      171192 :             st->last_ctx_hm_enabled = prm_hm[0];
    4231      171192 :             move16();
    4232             : 
    4233   144860792 :             FOR( i = 0; i < L_spec; i++ )
    4234             :             {
    4235             :                 /* no context harmonic model, copy MDCT coefficients to x */
    4236   144689600 :                 x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
    4237   144689600 :                 move32();
    4238             :             }
    4239      171192 :             *x_e = SPEC_EXP_DEC;
    4240      171192 :             move16();
    4241             :         }
    4242             :         ELSE /* hTcxCfg->ctx_hm == 0 */
    4243             :         {
    4244      673312 :             IF( hTcxDec->tcx_lpc_shaped_ari ) /* low rates: envelope based arithmetic coder */
    4245             :             {
    4246       14023 :                 prm_target = prm_sqQ;
    4247       14023 :                 move16();
    4248       14023 :                 prm_sqQ = prm_target + 1;
    4249       14023 :                 move16();
    4250             : 
    4251       14023 :                 IF( GT_32( st->bwidth, WB ) )
    4252             :                 {
    4253       12741 :                     tcx_arith_decode_envelope_ivas_fx( st, x, x_e, L_frame, L_spec, Aind, *prm_target, prm_sqQ, (Word16) NE_16( st->last_core_from_bs, ACELP_CORE ), prm_hm, /* HM parameter area */ hTcxDec->tcx_hm_LtpPitchLag, &arith_bits, &signaling_bits, 1 );
    4254             :                 }
    4255             :                 ELSE
    4256             :                 {
    4257        1282 :                     tcx_arith_decode_envelope_ivas_fx( st, x, x_e, L_frame, L_spec, Aind, *prm_target, prm_sqQ, (Word16) NE_16( st->last_core_from_bs, ACELP_CORE ), prm_hm, /* HM parameter area */ hTcxDec->tcx_hm_LtpPitchLag, &arith_bits, &signaling_bits, 0 );
    4258             :                 }
    4259             : 
    4260       14023 :                 hTcxDec->resQBits[frame_cnt] = sub( *prm_target, arith_bits );
    4261       14023 :                 move16();
    4262             : 
    4263             :                 /* Noise filling seed */
    4264     2941415 :                 FOR( i = 0; i < noiseFillingSize; ++i )
    4265             :                 {
    4266     2927392 :                     tmp32 = L_shr( x[i], sub( 31, *x_e ) );
    4267     2927392 :                     *nf_seed = add_sat( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ) ); // abs( tmp32 ) * i * 2
    4268     2927392 :                     move16();
    4269             :                 }
    4270             :             }
    4271             :             ELSE /* TCX-only: context based arithmetic coder */
    4272             :             {
    4273   528194809 :                 FOR( i = 0; i < L_spec; i++ )
    4274             :                 {
    4275   527535520 :                     x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
    4276   527535520 :                     move32();
    4277             :                 }
    4278             : 
    4279      659289 :                 set32_fx( x + L_spec, 0, sub( L_frameTCX, L_spec ) );
    4280             : 
    4281      659289 :                 *x_e = SPEC_EXP_DEC;
    4282      659289 :                 move16();
    4283             :             }
    4284             : 
    4285             :         } /* else of if hTcxCfg->ctx_hm */
    4286             : 
    4287             :         // start_zeroing = ( st->last_core != st->last_core_from_bs ) ? min( L_spec, L_frame ) : L_spec;
    4288      844504 :         IF( NE_16( st->last_core, st->last_core_from_bs ) )
    4289             :         {
    4290          76 :             start_zeroing = s_min( L_spec, L_frame );
    4291             :         }
    4292             :         ELSE
    4293             :         {
    4294      844428 :             start_zeroing = L_spec;
    4295      844428 :             move16();
    4296             :         }
    4297      844504 :         test();
    4298      844504 :         test();
    4299      844504 :         IF( frame_cnt == 0 && EQ_16( st->last_core, ACELP_CORE ) && NE_16( st->last_core_from_bs, ACELP_CORE ) )
    4300             :         {
    4301             :             Word16 L_spec_con;
    4302          26 :             L_spec_con = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
    4303             : 
    4304       12346 :             FOR( i = start_zeroing; i < L_spec_con; i++ )
    4305             :             {
    4306       12320 :                 x[i] = 0;
    4307       12320 :                 move32();
    4308             :             }
    4309             : 
    4310          26 :             start_zeroing = L_spec_con;
    4311          26 :             move16();
    4312             :         }
    4313             : 
    4314    42814840 :         FOR( i = start_zeroing; i < s_max( L_frame, L_frameTCX ); i++ )
    4315             :         {
    4316    41970336 :             x[i] = 0;
    4317    41970336 :             move32();
    4318             :         }
    4319             : 
    4320             :         /*-----------------------------------------------------------*
    4321             :          * adaptive low frequency deemphasis.                        *
    4322             :          *-----------------------------------------------------------*/
    4323             : 
    4324      844504 :         IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    4325             :         {
    4326      219527 :             weight_a_fx( A, Ap, gamma1, M );
    4327      219527 :             lpc2mdct_2( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS );
    4328             :         }
    4329             : 
    4330             :         /* initialize LF deemphasis factors in xn_buf */
    4331      844504 :         test();
    4332      844504 :         test();
    4333      844504 :         IF( !st->tcxonly || ( hTcxCfg->resq && hTcxDec->tcx_lpc_shaped_ari ) )
    4334             :         {
    4335      116044 :             Word16 len = s_max( L_spec, L_frameTCX );
    4336   104330364 :             FOR( i = 0; i < len; i++ )
    4337             :             {
    4338   104214320 :                 xn_buf[i] = ONE_IN_Q14;
    4339   104214320 :                 move16();
    4340             :             }
    4341             :         }
    4342      844504 :         IF( !st->tcxonly )
    4343             :         {
    4344      116044 :             AdaptLowFreqDeemph( x, *x_e, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, gainlpc2_e, L_frame, xn_buf /* LF deemphasis factors */ );
    4345             :         }
    4346             :     }
    4347             : 
    4348      853209 :     hTcxDec->damping = 0;
    4349      853209 :     move16();
    4350             : 
    4351      853209 :     IF( bfi == 0 )
    4352             :     {
    4353             :         /*-----------------------------------------------------------*
    4354             :          * Compute global gain                                       *
    4355             :          *-----------------------------------------------------------*/
    4356             : 
    4357      844504 :         tmp32 = L_shl( L_mult0( index, 0x797D ), 7 );            /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
    4358      844504 :         *gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
    4359      844504 :         *gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, (Word32) 0xFE000000 ) ) );
    4360      844504 :         move16();
    4361      844504 :         move16();
    4362             : 
    4363      844504 :         tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    4364      844504 :         s = 15 - 5 - 7;
    4365      844504 :         move16();
    4366      844504 :         IF( GE_16( L_spec, 1024 ) ) /*reduce precision for avoiding overflow*/
    4367             :         {
    4368        3789 :             tmp1 = mult_r( shl( L_spec, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    4369        3789 :             s = 15 - 4 - 7;
    4370        3789 :             move16();
    4371             :         }
    4372      844504 :         tmp1 = ISqrt16( tmp1, &s );
    4373             : 
    4374      844504 :         *gain_tcx = mult( *gain_tcx, tmp1 );
    4375      844504 :         *gain_tcx_e = add( *gain_tcx_e, s );
    4376      844504 :         move16();
    4377      844504 :         move16();
    4378             : 
    4379      844504 :         hTcxDec->old_gaintcx_bfi = *gain_tcx;
    4380      844504 :         move16();
    4381      844504 :         hTcxDec->old_gaintcx_bfi_e = *gain_tcx_e;
    4382      844504 :         move16();
    4383             : 
    4384      844504 :         hTcxDec->cummulative_damping_tcx = MAX16B; // 1 in Q15
    4385      844504 :         move16();
    4386             :     }
    4387             :     ELSE /* bfi = 1 */
    4388             :     {
    4389             :         /* PLC: [TCX: Fade-out]
    4390             :          * derivation of damping factor */
    4391        8705 :         IF( st->use_partial_copy )
    4392             :         {
    4393           0 :             IF( EQ_16( st->rf_frame_type, RF_TCXFD ) )
    4394             :             {
    4395           0 :                 tmp32 = L_shl( L_mult0( hTcxDec->old_gaintcx_bfi, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
    4396           0 :                 *gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 );         /* get exponent */
    4397           0 :                 *gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, 0xFE000000 ) ) );
    4398           0 :                 move16();
    4399           0 :                 move16();
    4400             : 
    4401           0 :                 tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    4402           0 :                 s = 15 - 5 - 7;
    4403           0 :                 move16();
    4404           0 :                 tmp1 = ISqrt16( tmp1, &s );
    4405             : 
    4406           0 :                 *gain_tcx = mult( *gain_tcx, tmp1 );
    4407           0 :                 *gain_tcx_e = add( *gain_tcx_e, s );
    4408           0 :                 move16();
    4409           0 :                 move16();
    4410             : 
    4411           0 :                 hTcxDec->old_gaintcx_bfi = *gain_tcx;
    4412           0 :                 move16();
    4413           0 :                 hTcxDec->old_gaintcx_bfi_e = *gain_tcx_e;
    4414           0 :                 move16();
    4415             :             }
    4416             :             ELSE
    4417             :             {
    4418           0 :                 *gain_tcx = hTcxDec->old_gaintcx_bfi;
    4419           0 :                 move16();
    4420           0 :                 *gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
    4421           0 :                 move16();
    4422             :             }
    4423             : 
    4424           0 :             hTcxDec->damping = ONE_IN_Q14; // Q14
    4425           0 :             move16();
    4426             :         }
    4427             :         ELSE
    4428             :         {
    4429        8705 :             *gain_tcx = hTcxDec->old_gaintcx_bfi;
    4430        8705 :             move16();
    4431        8705 :             *gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
    4432        8705 :             move16();
    4433             : 
    4434       17410 :             hTcxDec->damping = Damping_fact_fx( st->coder_type, st->nbLostCmpt, st->last_good,
    4435        8705 :                                                 st->stab_fac_fx,
    4436             :                                                 &st->Mode2_lp_gainp,
    4437        8705 :                                                 st->last_core );
    4438        8705 :             move16();
    4439             :         }
    4440             : 
    4441        8705 :         hTcxDec->cummulative_damping_tcx = shl( mult( hTcxDec->cummulative_damping_tcx, hTcxDec->damping ), 1 ); /*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/
    4442        8705 :         move16();
    4443             :     }
    4444             : 
    4445      853209 :     IF( bfi )
    4446             :     {
    4447        8705 :         IF( hTcxDec->envWeighted )
    4448             :         {
    4449           0 :             gamma = st->gamma;
    4450           0 :             move16();
    4451             :         }
    4452             :         ELSE
    4453             :         {
    4454        8705 :             gamma = gamma1;
    4455        8705 :             move16();
    4456             :         }
    4457             : 
    4458             :         /* PLC: [TCX: Fade-out]
    4459             :          * PLC: invert LPC weighting in case of PLC */
    4460             : 
    4461        8705 :         IF( hTcxDec->enableTcxLpc )
    4462             :         {
    4463         147 :             gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( st->gamma, MAX16B ) ), MAX16B );
    4464             :         }
    4465             :         ELSE
    4466             :         {
    4467        8558 :             gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( gamma1, MAX16B ) ), MAX16B );
    4468             :         }
    4469             : 
    4470        8705 :         IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    4471             :         {
    4472        1702 :             weight_a_fx( A, Ap, gamma, M );
    4473        1702 :             lpc2mdct_2( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS );
    4474             :         }
    4475             :     }
    4476             : 
    4477      853209 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    4478             :     {
    4479      221229 :         set16_fx( h1, 0, L_SUBFR + 1 );
    4480      221229 :         set16_fx( mem, 0, M );
    4481      221229 :         h1[0] = ONE_IN_Q10;
    4482      221229 :         move16();
    4483      221229 :         E_UTIL_synthesis( 0, Ap, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC     */
    4484             : 
    4485      221229 :         tmp2 = 0;
    4486      221229 :         move16();
    4487      221229 :         deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp2 ); /* tmp2 in Q10 */
    4488             :     }
    4489             : 
    4490             :     /* impulse response level = gain introduced by synthesis+deemphasis */
    4491      853209 :     test();
    4492      853209 :     IF( !bfi )
    4493             :     {
    4494      844504 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    4495             :         {
    4496      624977 :             st->last_gain_syn_deemph = 0;
    4497      624977 :             move16();
    4498      624977 :             st->last_gain_syn_deemph_e = 0;
    4499      624977 :             move16();
    4500             :         }
    4501             :         ELSE
    4502             :         {
    4503      219527 :             tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e ) /*Q15, st->last_gain_syn_deemph_e*/;
    4504      219527 :             st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ );
    4505      219527 :             move16();
    4506      219527 :             tmp32 = Sqrt32( tmp32, &st->last_gain_syn_deemph_e );
    4507      219527 :             st->last_gain_syn_deemph = round_fx_sat( tmp32 ); // Q15
    4508      219527 :             move16();
    4509             :         }
    4510             : 
    4511             :         /*for avoiding compiler warnings*/
    4512      844504 :         hTcxDec->gainHelper = ONE_IN_Q14;
    4513      844504 :         move16();
    4514      844504 :         hTcxDec->gainHelper_e = 1;
    4515      844504 :         move16();
    4516      844504 :         hTcxDec->stepCompensate = 0;
    4517      844504 :         move16();
    4518      844504 :         hTcxDec->stepCompensate_e = 0;
    4519      844504 :         move16();
    4520             :     }
    4521             :     /* not instrumenting the additional test() here seems to be common practice */
    4522        8705 :     ELSE IF( EQ_16( TCX_20_CORE, st->core ) || EQ_16( frame_cnt, 1 ) )
    4523             :     {
    4524        8646 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    4525             :         {
    4526        6952 :             gainCompensate = ONE_IN_Q14;
    4527        6952 :             move16();
    4528        6952 :             gainCompensate_e = 1;
    4529        6952 :             move16();
    4530             :         }
    4531             :         ELSE
    4532             :         {
    4533        1694 :             tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gainCompensate_e ) /*Q15, gainCompensate_e*/;
    4534        1694 :             gainCompensate_e = add( gainCompensate_e, 10 /*scaling of h1[0] and E_UTIL:synthesis*/ );
    4535        1694 :             gainCompensate = round_fx_sat( Sqrt32( tmp32, &gainCompensate_e ) ) /*Q15, gainCompensate_e*/;
    4536        1694 :             BASOP_Util_Divide_MantExp( st->last_gain_syn_deemph,
    4537        1694 :                                        st->last_gain_syn_deemph_e,
    4538             :                                        gainCompensate,
    4539             :                                        gainCompensate_e,
    4540             :                                        &gainCompensate,
    4541             :                                        &gainCompensate_e );
    4542             :         }
    4543             : 
    4544        8646 :         tmp1 = T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )]; /* indexing for lookup table */
    4545             : 
    4546        8646 :         IF( EQ_16( st->nbLostCmpt, 1 ) )
    4547             :         {
    4548        4897 :             hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
    4549             :                 tmp1,
    4550             :                 -7,
    4551        4897 :                 negate( mult( gainCompensate, tmp1 ) ),
    4552        4897 :                 add( -7, gainCompensate_e ),
    4553             :                 &hTcxDec->stepCompensate );
    4554        4897 :             hTcxDec->gainHelper = ONE_IN_Q14;
    4555        4897 :             move16();
    4556        4897 :             hTcxDec->gainHelper_e = 1;
    4557        4897 :             move16();
    4558             :         }
    4559             :         ELSE
    4560             :         {
    4561        3749 :             hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
    4562        3749 :                 mult( tmp1, st->last_concealed_gain_syn_deemph ),
    4563        3749 :                 add( -7, st->last_concealed_gain_syn_deemph_e ),
    4564        3749 :                 negate( mult( tmp1, gainCompensate ) ),
    4565        3749 :                 add( -7, gainCompensate_e ),
    4566             :                 &hTcxDec->stepCompensate );
    4567             : 
    4568        3749 :             hTcxDec->gainHelper = st->last_concealed_gain_syn_deemph;
    4569        3749 :             move16();
    4570        3749 :             hTcxDec->gainHelper_e = st->last_concealed_gain_syn_deemph_e;
    4571        3749 :             move16();
    4572             :         }
    4573             : 
    4574        8646 :         st->last_concealed_gain_syn_deemph = gainCompensate;
    4575        8646 :         move16();
    4576        8646 :         st->last_concealed_gain_syn_deemph_e = gainCompensate_e;
    4577        8646 :         move16();
    4578             :     }
    4579             : 
    4580             :     /*-----------------------------------------------------------*
    4581             :      * Residual inv. Q.                                          *
    4582             :      *-----------------------------------------------------------*/
    4583      853209 :     test();
    4584      853209 :     IF( !bfi && hTcxCfg->resq )
    4585             :     {
    4586      373706 :         IF( hTcxDec->tcx_lpc_shaped_ari )
    4587             :         {
    4588             :             /* envelope based arithmetic coder */
    4589             :             const Word16 *prm_resq;
    4590       14023 :             prm_resq = prm_sqQ + sub( *prm_target /* = targetBits */, hTcxDec->resQBits[frame_cnt] );
    4591             : 
    4592       14023 :             i = tcx_ari_res_invQ_spec( x, *x_e, L_spec,
    4593             :                                        prm_resq,
    4594       14023 :                                        hTcxDec->resQBits[frame_cnt],
    4595             :                                        0,
    4596       14023 :                                        hTcxCfg->sq_rounding,
    4597             :                                        xn_buf /* LF deemphasis factors */ );
    4598             :         }
    4599             :         ELSE
    4600             :         {
    4601             :             /* context based arithmetic coder */
    4602      359683 :             i = tcx_res_invQ_gain( gain_tcx, gain_tcx_e, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt] );
    4603             : 
    4604      359683 :             Word16 *tmpP16 = xn_buf;
    4605      359683 :             if ( st->tcxonly != 0 )
    4606      257662 :                 tmpP16 = NULL;
    4607      359683 :             tcx_res_invQ_spec( x, *x_e, L_spec, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt], i, hTcxCfg->sq_rounding, tmpP16 /* LF deemphasis factors */ );
    4608             :         }
    4609             :     }
    4610             : 
    4611      853209 :     test();
    4612      853209 :     test();
    4613      853209 :     IF( !bfi && st->tcxonly && st->element_mode != IVAS_CPE_MDCT )
    4614             :     {
    4615      103483 :         test();
    4616      103483 :         test();
    4617      103483 :         IF( hTcxLtpDec->tcxltp && ( hTcxLtpDec->tcxltp_gain > 0 ) && !( *fUseTns ) )
    4618             :         {
    4619        3673 :             PsychAdaptLowFreqDeemph( x, gainlpc2, gainlpc2_e, NULL );
    4620             :         }
    4621             :     }
    4622      853209 :     test();
    4623      853209 :     IF( !bfi && !st->tcxonly )
    4624             :     {
    4625             :         /* Replication of ACELP formant enhancement for low rates */
    4626      116044 :         IF( LT_32( st->total_brate, ACELP_13k20 ) )
    4627             :         {
    4628       26479 :             IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    4629             :             {
    4630           0 :                 assert( !"Not adapted to warped scale" );
    4631             :             }
    4632             : 
    4633             :             Word16 xn_buf_e;
    4634       26479 :             tcxFormantEnhancement_with_shift( xn_buf, &xn_buf_e, gainlpc2, gainlpc2_e, x, x_e, L_frame, L_frameTCX );
    4635     1721135 :             FOR( i = 0; i < FDNS_NPTS; i++ )
    4636             :             {
    4637     1694656 :                 xn_buf[i] = shl( xn_buf[i], xn_buf_e - 1 );
    4638     1694656 :                 move16();
    4639             :             }
    4640             :         }
    4641             :     }
    4642             : 
    4643             :     /*-----------------------------------------------------------*
    4644             :      * Add gain to the lpc gains                                 *
    4645             :      *-----------------------------------------------------------*/
    4646             : 
    4647      853209 :     IF( st->VAD == 0 )
    4648             :     {
    4649      580291 :         *gain_tcx = mult_r( *gain_tcx, hTcxCfg->na_scale );
    4650      580291 :         move16();
    4651             :     }
    4652             : 
    4653      853209 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    4654             :     {
    4655      221229 :         i = norm_s( *gain_tcx );
    4656      221229 :         *gain_tcx = shl( *gain_tcx, i );
    4657      221229 :         *gain_tcx_e = sub( *gain_tcx_e, i );
    4658      221229 :         move16();
    4659      221229 :         move16();
    4660    14379885 :         FOR( i = 0; i < FDNS_NPTS; i++ )
    4661             :         {
    4662    14158656 :             gainlpc2[i] = mult( gainlpc2[i], *gain_tcx );
    4663    14158656 :             move16();
    4664    14158656 :             gainlpc2_e[i] = add( gainlpc2_e[i], *gain_tcx_e );
    4665    14158656 :             move16();
    4666             :         }
    4667             :     }
    4668             : 
    4669      853209 :     return;
    4670             : }
    4671             : 
    4672             : /*-------------------------------------------------------------------*
    4673             :  *  decoder_tcx_noisefilling()
    4674             :  *
    4675             :  *  TCX: core noise filling, IGF updates
    4676             :  *-------------------------------------------------------------------*/
    4677             : 
    4678      853209 : void decoder_tcx_noisefilling_fx(
    4679             :     Decoder_State *st, /* i/o: coder memory state          */
    4680             :     const Word32 concealment_noise[L_FRAME48k],
    4681             :     const Word16 concealment_noise_exp,
    4682             :     const Word16 A[], /* i  :  coefficients NxAz[M+1]     */
    4683             :     const Word16 L_frameTCX_glob,
    4684             :     const Word16 L_spec,
    4685             :     const Word16 L_frame,
    4686             :     const Word16 L_frameTCX,
    4687             :     Word32 x[],
    4688             :     Word16 *x_e,
    4689             :     Word16 *gainlpc2,
    4690             :     Word16 *gainlpc2_e,
    4691             :     Word16 *temp_concealment_method,
    4692             :     const Word16 gain_tcx,
    4693             :     const Word16 gain_tcx_e,
    4694             :     const Word16 *prm_sqQ,
    4695             :     Word16 nf_seed,
    4696             :     const Word16 bfi, /* i  :  Bad frame indicator            */
    4697             :     const Word16 MCT_flag,
    4698             :     const Word16 frame_cnt /* i  : frame counter in the super frame*/
    4699             : )
    4700             : {
    4701             :     Word16 i;
    4702             :     Word16 firstLine;
    4703             :     Word16 fac_ns;
    4704             :     Word16 noiseFillingSize;
    4705      853209 :     Word16 noiseTransWidth = MIN_NOISE_FILLING_HOLE;
    4706      853209 :     move16();
    4707             :     Word16 tmp, tmp1, tmp2;
    4708             :     Word16 sum_word16;
    4709             :     Word16 infoIGFStartLine;
    4710             :     Word16 f, noiseTiltFactor;
    4711             :     Word32 smooth_gain;
    4712      853209 :     TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
    4713      853209 :     TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
    4714      853209 :     TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
    4715             :     Word32 total_brate;
    4716             :     Word32 tmp32;
    4717             :     Word16 *pInfoTCXNoise;
    4718             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    4719      853209 :     Flag Overflow = 0;
    4720      853209 :     move32();
    4721      853209 :     Flag Carry = 0;
    4722      853209 :     move32();
    4723             : #endif
    4724      853209 :     total_brate = ( (Word16) EQ_16( st->element_mode, IVAS_CPE_MDCT ) ? st->element_brate : st->total_brate );
    4725      853209 :     move32();
    4726             :     /*-----------------------------------------------------------------*
    4727             :      * Initializations
    4728             :      *-----------------------------------------------------------------*/
    4729             : 
    4730             :     /* Init lengths */
    4731      853209 :     infoIGFStartLine = get_igf_startline( st, L_frame, L_frameTCX );
    4732             : 
    4733      853209 :     noiseFillingSize = L_spec;
    4734      853209 :     move16();
    4735      853209 :     if ( st->igf != 0 )
    4736             :     {
    4737      574731 :         noiseFillingSize = st->hIGFDec->infoIGFStartLine;
    4738      574731 :         move16();
    4739             :     }
    4740             : 
    4741      853209 :     IF( bfi == 0 )
    4742             :     {
    4743      844504 :         fac_ns = extract_l( L_shr( L_mult0( hTcxDec->noise_filling_index[frame_cnt], 0x6000 /* 0.75f in Q15 */ ), NBITS_NOISE_FILL_LEVEL ) );
    4744             :     }
    4745             :     ELSE
    4746             :     {
    4747        8705 :         fac_ns = 0;
    4748        8705 :         move16();
    4749             :     }
    4750             : 
    4751             :     /*-----------------------------------------------------------*
    4752             :      * Noise filling.                                            *
    4753             :      *-----------------------------------------------------------*/
    4754             : 
    4755      853209 :     test();
    4756      853209 :     IF( bfi == 0 && ( fac_ns > 0 ) )
    4757             :     {
    4758      805942 :         firstLine = tcxGetNoiseFillingTilt( A, M, L_frame, ( GE_32( total_brate, ACELP_13k20 ) && !st->rf_flag ), &noiseTiltFactor );
    4759             : 
    4760      805942 :         IF( st->tcxonly != 0 )
    4761             :         {
    4762      690263 :             tmp1 = 0;
    4763      690263 :             move16();
    4764      690263 :             test();
    4765      690263 :             test();
    4766      690263 :             if ( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) && ( st->last_ctx_hm_enabled != 0 ) )
    4767             :             {
    4768        4442 :                 tmp1 = 10240 /*0.3125f Q15*/;
    4769        4442 :                 move16();
    4770             :             }
    4771      690263 :             IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    4772             :             {
    4773      600386 :                 IF( frame_cnt == 0 )
    4774             :                 {
    4775      586790 :                     Copy( hTcxDec->ltpGainMemory_fx, &hTcxDec->ltpGainMemory_fx[1], N_LTP_GAIN_MEMS - 1 );
    4776      586790 :                     hTcxDec->ltpGainMemory_fx[0] = hTcxLtpDec->tcxltp_gain; /* Q15 */
    4777      586790 :                     move16();
    4778             :                 }
    4779      600386 :                 smooth_gain = Dot_product( hTcxDec->ltpGainMemory_fx, nf_tw_smoothing_coeffs_fx, N_LTP_GAIN_MEMS ); /* Q31 */
    4780      600386 :                 noiseTransWidth = HOLE_SIZE_FROM_LTP32( L_max( smooth_gain, L_deposit_h( tmp1 ) ) );                /* using 32-bit for increased precision. */
    4781             :             }
    4782             :             ELSE
    4783             :             {
    4784       89877 :                 noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( hTcxLtpDec->tcxltp_gain, tmp1 ) );
    4785             :             }
    4786             : 
    4787      690263 :             if ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) )
    4788             :             {
    4789       27554 :                 noiseTransWidth = 3; /* minimum transition fading for noise filling in TCX-10 */
    4790       27554 :                 move16();
    4791             :             }
    4792             :         }
    4793             : 
    4794      805942 :         IF( hTcxDec->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
    4795             :         {
    4796             :             /* noise filling seed */
    4797      792119 :             tmp32 = L_deposit_l( 0 );
    4798   646001879 :             FOR( i = 0; i < L_spec; i++ )
    4799             :             {
    4800   645209760 :                 tmp32 = L_macNs_co( tmp32, abs_s( prm_sqQ[i] ), i, &Carry, &Overflow );
    4801             :             }
    4802      792119 :             nf_seed = extract_l( tmp32 );
    4803             :         }
    4804      805942 :         pInfoTCXNoise = NULL;
    4805      805942 :         if ( st->igf )
    4806             :         {
    4807      554001 :             pInfoTCXNoise = st->hIGFDec->infoTCXNoise_ptr;
    4808             :         }
    4809      805942 :         tcx_noise_filling_with_shift( x, x_e, nf_seed, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor, fac_ns, pInfoTCXNoise, st->element_mode );
    4810      805942 :         st->seed_tcx_plc = nf_seed;
    4811      805942 :         move16();
    4812             :     }
    4813             : 
    4814      853209 :     IF( st->enablePlcWaveadjust )
    4815             :     {
    4816           0 :         IF( bfi )
    4817             :         {
    4818           0 :             IF( EQ_16( st->nbLostCmpt, 1 ) )
    4819             :             {
    4820           0 :                 st->hPlcInfo->concealment_method = TCX_NONTONAL;
    4821           0 :                 move16();
    4822             : 
    4823             :                 /* tonal/non-tonal decision */
    4824           0 :                 test();
    4825           0 :                 test();
    4826           0 :                 IF( EQ_16( st->hPlcInfo->Transient[0], 1 ) && EQ_16( st->hPlcInfo->Transient[1], 1 ) && EQ_16( st->hPlcInfo->Transient[2], 1 ) )
    4827             :                 {
    4828           0 :                     sum_word16 = 0;
    4829           0 :                     move16();
    4830             : 
    4831           0 :                     FOR( i = 9; i >= 0; i-- )
    4832             :                     {
    4833           0 :                         sum_word16 = add( sum_word16, st->hPlcInfo->TCX_Tonality[i] );
    4834             :                     }
    4835             : 
    4836           0 :                     if ( GE_16( sum_word16, 6 ) )
    4837             :                     {
    4838           0 :                         st->hPlcInfo->concealment_method = TCX_TONAL;
    4839           0 :                         move16();
    4840             :                     }
    4841             :                 }
    4842             : 
    4843           0 :                 if ( st->tonal_mdct_plc_active )
    4844             :                 {
    4845           0 :                     st->hPlcInfo->concealment_method = TCX_TONAL;
    4846           0 :                     move16();
    4847             :                 }
    4848             :             }
    4849             : 
    4850           0 :             if ( GT_16( L_frameTCX, hTcxDec->L_frameTCX ) )
    4851             :             {
    4852           0 :                 st->hPlcInfo->concealment_method = TCX_TONAL;
    4853           0 :                 move16();
    4854             :             }
    4855             : 
    4856           0 :             *temp_concealment_method = st->hPlcInfo->concealment_method;
    4857           0 :             move16();
    4858             : 
    4859           0 :             if ( EQ_16( st->core, TCX_10_CORE ) )
    4860             :             {
    4861           0 :                 *temp_concealment_method = TCX_TONAL;
    4862           0 :                 move16();
    4863             :             }
    4864             :         }
    4865             : 
    4866             :         /* get the starting location of the subframe in the frame */
    4867           0 :         IF( EQ_16( st->core, TCX_10_CORE ) )
    4868             :         {
    4869           0 :             st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) );
    4870           0 :             move16();
    4871             :         }
    4872             :     }
    4873             : 
    4874             :     /* PLC: [TCX: Tonal Concealment] */
    4875             :     /* PLC: [TCX: Fade-out]
    4876             :      * PLC: Fade out to white noise */
    4877      853209 :     IF( st->hTonalMDCTConc != NULL )
    4878             :     {
    4879      853209 :         test();
    4880      853209 :         IF( bfi == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    4881             :         {
    4882      219527 :             TonalMDCTConceal_SaveFreqSignal_ivas_fx( st->hTonalMDCTConc, x, *x_e, L_frameTCX, L_frame, gainlpc2, gainlpc2_e, gain_tcx_e, infoIGFStartLine );
    4883             :         }
    4884      633682 :         ELSE IF( bfi )
    4885             :         {
    4886        8705 :             test();
    4887        8705 :             IF( !st->enablePlcWaveadjust || EQ_16( *temp_concealment_method, TCX_TONAL ) )
    4888             :             {
    4889             :                 /* set f to 1 to not fade out */
    4890             :                 /* set f to 0 to immediately switch to white noise */
    4891        8705 :                 test();
    4892        8705 :                 test();
    4893        8705 :                 IF( st->tcxonly && ( NE_16( st->element_mode, IVAS_CPE_MDCT ) || MCT_flag ) )
    4894             :                 {
    4895        4365 :                     f = MAX16B;
    4896        4365 :                     move16();
    4897             :                 }
    4898             :                 ELSE
    4899             :                 {
    4900        4340 :                     f = hTcxDec->cummulative_damping_tcx;
    4901        4340 :                     move16();
    4902             :                 }
    4903             : 
    4904        8705 :                 test();
    4905        8705 :                 test();
    4906        8705 :                 test();
    4907        8705 :                 test();
    4908        8705 :                 test();
    4909        8705 :                 test();
    4910        8705 :                 IF( ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
    4911             :                 {
    4912             :                     Word16 exp1, exp2;
    4913          15 :                     exp1 = 0;
    4914          15 :                     exp2 = 0;
    4915             :                     Word64 E_2ndlast, E_last;
    4916          15 :                     E_2ndlast = E_last = EPSILON_FX;
    4917          15 :                     move16();
    4918          15 :                     move16();
    4919          15 :                     move64();
    4920          15 :                     move64();
    4921             : 
    4922             :                     Word16 tmp_len;
    4923          15 :                     IF( st->element_mode > EVS_MONO )
    4924             :                     {
    4925          15 :                         tmp_len = L_frameTCX;
    4926          15 :                         move16();
    4927             :                     }
    4928             :                     ELSE
    4929             :                     {
    4930           0 :                         tmp_len = infoIGFStartLine;
    4931           0 :                         move16();
    4932             :                     }
    4933             : 
    4934        2015 :                     FOR( i = 0; i < tmp_len; i = i + 2 )
    4935             :                     {
    4936        2000 :                         E_2ndlast = W_mac_16_16( E_2ndlast, st->hTonalMDCTConc->lastBlockData.spectralData[i], st->hTonalMDCTConc->lastBlockData.spectralData[i] );   /* Q(31 - 2 * st->hTonalMDCTConc->lastBlockData.spectralData_exp) */
    4937        2000 :                         E_last = W_mac_16_16( E_last, st->hTonalMDCTConc->lastBlockData.spectralData[i + 1], st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] ); /* Q(31 - 2 * st->hTonalMDCTConc->lastBlockData.spectralData_exp) */
    4938             :                     }
    4939             : 
    4940          15 :                     exp2 = W_norm( E_2ndlast );
    4941          15 :                     E_2ndlast = W_shl( E_2ndlast, exp2 );
    4942          15 :                     exp2 = sub( 63, add( sub( 31, shl( st->hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) ), exp2 ) );
    4943             : 
    4944          15 :                     exp1 = W_norm( E_last );
    4945          15 :                     E_last = W_shl( E_last, exp1 );
    4946          15 :                     exp1 = sub( 63, add( sub( 31, shl( st->hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) ), exp1 ) );
    4947             : 
    4948          15 :                     tmp1 = BASOP_Util_Divide3232_Scale( W_extract_h( E_2ndlast ), W_extract_h( E_last ), &tmp2 );
    4949          15 :                     tmp2 = add( tmp2, sub( exp2, exp1 ) );
    4950             : 
    4951          15 :                     tmp1 = shl_sat( tmp1, sub( tmp2, 2 ) );
    4952             : 
    4953             :                     /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */
    4954          15 :                     IF( st->element_mode > EVS_MONO )
    4955             :                     {
    4956          15 :                         tmp_len = L_frameTCX;
    4957          15 :                         move16();
    4958             :                     }
    4959             :                     ELSE
    4960             :                     {
    4961           0 :                         tmp_len = infoIGFStartLine;
    4962           0 :                         move16();
    4963             :                     }
    4964          15 :                     IF( GT_16( tmp1, ONE_IN_Q14 ) ) /* 2 in Q13 = 1 in Q14 */
    4965             :                     {
    4966           0 :                         FOR( i = 0; i < tmp_len; i += 2 )
    4967             :                         {
    4968           0 :                             move16();
    4969           0 :                             st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
    4970             :                         }
    4971             :                     }
    4972          15 :                     ELSE IF( LT_16( tmp1, ONE_IN_Q12 ) ) /*0.5 in Q13 = 1 in Q12*/
    4973             :                     {
    4974        1127 :                         FOR( i = 0; i < tmp_len; i += 2 )
    4975             :                         {
    4976        1120 :                             move16();
    4977        1120 :                             st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i];
    4978             :                         }
    4979             :                     }
    4980             :                 }
    4981             : 
    4982        8705 :                 noiseTiltFactor = MAX16B;
    4983        8705 :                 move16();
    4984             : 
    4985        8705 :                 tmp = 0;
    4986        8705 :                 move16();
    4987        8705 :                 test();
    4988        8705 :                 if ( GE_32( total_brate, ACELP_13k20 ) && st->rf_flag == 0 )
    4989             :                 {
    4990        8467 :                     tmp = 1;
    4991        8467 :                     move16();
    4992             :                 }
    4993             : 
    4994        8705 :                 tcxGetNoiseFillingTilt( A, M, L_frame, tmp, &noiseTiltFactor );
    4995             : 
    4996             :                 Word32 CngLevelBackgroundTrace_bfi_fx;
    4997        8705 :                 CngLevelBackgroundTrace_bfi_fx = L_deposit_l( hTcxDec->conCngLevelBackgroundTrace );
    4998             :                 Word16 CngLevelBackgroundTrace_bfi_exp;
    4999        8705 :                 CngLevelBackgroundTrace_bfi_exp = add( hTcxDec->conCngLevelBackgroundTrace_e, 16 );
    5000        8705 :                 test();
    5001        8705 :                 IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && MCT_flag == 0 )
    5002             :                 {
    5003        3201 :                     TonalMDCTConceal_InsertNoise_ivas_fx( st->hTonalMDCTConc, x, x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, concealment_noise_exp, CngLevelBackgroundTrace_bfi_fx, CngLevelBackgroundTrace_bfi_exp, infoIGFStartLine );
    5004             :                 }
    5005             :                 ELSE
    5006             :                 {
    5007        5504 :                     TonalMDCTConceal_InsertNoise_ivas_fx( st->hTonalMDCTConc, x, x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, 0, CngLevelBackgroundTrace_bfi_fx, CngLevelBackgroundTrace_bfi_exp, infoIGFStartLine );
    5008             :                 }
    5009             :             }
    5010             :         }
    5011             :     }
    5012             : 
    5013             :     /*------------------------- SPLIT 2 noise filling ------------------------*/
    5014      853209 :     IF( !bfi )
    5015             :     {
    5016      844504 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    5017             :         {
    5018   497570897 :             FOR( i = 0; i < L_spec; i++ )
    5019             :             {
    5020   496945920 :                 x[i] = Mpy_32_16_1( x[i], gain_tcx );
    5021   496945920 :                 move16();
    5022             :             }
    5023      624977 :             *x_e = add( *x_e, gain_tcx_e );
    5024      624977 :             move16();
    5025             :         }
    5026             :     }
    5027             : 
    5028      853209 :     IF( LT_16( L_spec, L_frame ) )
    5029             :     {
    5030           2 :         set32_fx( x + L_spec, 0, sub( L_frame, L_spec ) );
    5031             :     }
    5032      853207 :     ELSE IF( GT_16( L_spec, L_frameTCX ) )
    5033             :     {
    5034       69367 :         set32_fx( x + L_frameTCX, 0, sub( L_spec, L_frameTCX ) );
    5035             :     }
    5036      853209 :     test();
    5037      853209 :     test();
    5038      853209 :     test();
    5039      853209 :     test();
    5040      853209 :     test();
    5041      853209 :     test();
    5042      853209 :     test();
    5043      853209 :     test();
    5044      853209 :     test();
    5045      853209 :     test();
    5046      853209 :     test();
    5047      853209 :     test();
    5048      853209 :     test();
    5049      853209 :     IF( bfi && ( !st->enablePlcWaveadjust || EQ_16( *temp_concealment_method, TCX_TONAL ) ) && st->igf && ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
    5050             :     {
    5051           5 :         IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x, *x_e, IGF_GRID_LB_SHORT );
    5052             :         /* also replace flat spectrum for the second TCX10 sub frame */
    5053           5 :         IGFDecUpdateInfo_ivas_fx( st->hIGFDec, 1, IGF_GRID_LB_SHORT );
    5054           5 :         IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x, *x_e, IGF_GRID_LB_SHORT );
    5055           5 :         IGFDecUpdateInfo_ivas_fx( st->hIGFDec, 0, IGF_GRID_LB_SHORT );
    5056           5 :         Copy( st->hIGFDec->igfData.igf_curr_subframe[0][0], st->hIGFDec->igfData.igf_curr_subframe[1][0], IGF_MAX_SFB );
    5057             :     }
    5058      853204 :     ELSE IF( bfi && st->igf && ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
    5059             :     {
    5060             :         /* copy second to first subframe */
    5061          15 :         IGFDecReplicateTCX10State_fx( st->hIGFDec );
    5062             :     }
    5063             : 
    5064      853209 :     IF( st->element_mode != EVS_MONO )
    5065             :     {
    5066      853209 :         IF( bfi )
    5067             :         {
    5068        8705 :             nf_seed = st->seed_tcx_plc;
    5069        8705 :             move16();
    5070             :         }
    5071      844504 :         ELSE IF( nf_seed == 0 )
    5072             :         {
    5073       39982 :             nf_seed = *st->hIGFDec->igfData.igfInfo.nfSeed;
    5074       39982 :             move16();
    5075             :         }
    5076             :     }
    5077             : 
    5078      853209 :     IF( st->igf )
    5079             :     {
    5080      574731 :         *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l( L_add( L_mult0( nf_seed, 31821 ), 13849 ) );
    5081      574731 :         move16();
    5082             :     }
    5083             : 
    5084      853209 :     return;
    5085             : }
    5086             : 
    5087             : /*-------------------------------------------------------------------*
    5088             :  * decoder_tcx_noiseshaping_igf_fx()
    5089             :  *
    5090             :  * TCX: FDNS and IGF application
    5091             :  *-------------------------------------------------------------------*/
    5092             : 
    5093      853209 : void decoder_tcx_noiseshaping_igf_fx(
    5094             :     Decoder_State *st, /* i/o: coder memory state          */
    5095             :     const Word16 L_spec,
    5096             :     const Word16 L_frame,
    5097             :     const Word16 L_frameTCX,
    5098             :     const Word16 left_rect,
    5099             :     Word32 *x_fx,
    5100             :     Word16 *x_e,
    5101             :     Word16 *x_len,
    5102             :     const Word16 gainlpc2_fx[],
    5103             :     const Word16 gainlpc2_e[],
    5104             :     Word16 *temp_concealment_method,
    5105             :     const Word16 bfi /* i  : Bad frame indicator                 */
    5106             : )
    5107             : {
    5108             :     TCX_DEC_HANDLE hTcxDec;
    5109             :     Word16 i;
    5110             :     Word32 tmp32;
    5111             :     Word8 tmp8;
    5112             : 
    5113             :     /*-----------------------------------------------------------*
    5114             :      * Noise shaping in frequency domain (1/Wz)                  *
    5115             :      *-----------------------------------------------------------*/
    5116      853209 :     hTcxDec = st->hTcxDec;
    5117             : 
    5118      853209 :     test();
    5119      853209 :     test();
    5120      853209 :     test();
    5121      853209 :     IF( st->igf && ( !bfi || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->prev_bfi ) ) )
    5122             :     {
    5123      572158 :         test();
    5124      572158 :         IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) )
    5125             :         {
    5126       22358 :             IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_SHORT );
    5127             :         }
    5128             :         ELSE
    5129             :         {
    5130      549800 :             IF( st->last_core == ACELP_CORE )
    5131             :             {
    5132        7669 :                 IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_TRAN );
    5133             :             }
    5134             :             ELSE
    5135             :             {
    5136      542131 :                 IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_NORM );
    5137             :             }
    5138             :         }
    5139             :     }
    5140             :     /* LPC gains already available */
    5141             : 
    5142      853209 :     test();
    5143      853209 :     test();
    5144      853209 :     test();
    5145      853209 :     test();
    5146      853209 :     test();
    5147      853209 :     IF( gainlpc2_fx && gainlpc2_e && NE_16( st->element_mode, IVAS_CPE_MDCT ) && ( !st->enablePlcWaveadjust || !bfi || ( EQ_16( *temp_concealment_method, TCX_TONAL ) ) ) )
    5148             :     {
    5149             :         Word16 spec_side_x_e, frame_side_x_e;
    5150             : 
    5151      221229 :         spec_side_x_e = *x_e;
    5152      221229 :         move16();
    5153             : 
    5154             :         /* NOTE: this function updates x till L_frame. From L_frame to L_spec, the exponent needs to be updated. */
    5155      221229 :         mdct_noiseShaping_ivas_fx( x_fx, x_e, L_frame, gainlpc2_fx, gainlpc2_e );
    5156             : 
    5157      221229 :         frame_side_x_e = *x_e;
    5158      221229 :         move16();
    5159             : 
    5160      221229 :         IF( bfi == 0 )
    5161             :         {
    5162    85596071 :             FOR( i = L_frame; i < L_spec; i++ )
    5163             :             {
    5164    85376544 :                 x_fx[i] = Mpy_32_16_1( x_fx[i], gainlpc2_fx[FDNS_NPTS - 1] );
    5165    85376544 :                 move32();
    5166             :             }
    5167      219527 :             spec_side_x_e = add( spec_side_x_e, gainlpc2_e[FDNS_NPTS - 1] );
    5168             :         }
    5169             : 
    5170      221229 :         IF( LT_16( spec_side_x_e, frame_side_x_e ) )
    5171             :         {
    5172             :             /* If the exponent on the spec side (i>L_frame) is lesser, then shift all the values in the
    5173             :             spec side by the difference to make both sides have the same exponent. */
    5174      199767 :             Word16 diff_e = sub( frame_side_x_e, spec_side_x_e );
    5175    78807559 :             FOR( i = L_frame; i < L_spec; i++ )
    5176             :             {
    5177    78607792 :                 x_fx[i] = L_shr( x_fx[i], diff_e );
    5178    78607792 :                 move32();
    5179             :             }
    5180             :         }
    5181       21462 :         ELSE IF( GT_16( spec_side_x_e, frame_side_x_e ) )
    5182             :         {
    5183             :             /* If the exponent on the spec side (i>L_frame) is greater, then shift all the values in the
    5184             :             frame side (i<L_frame) by the difference to make both sides have the same exponent. */
    5185           0 :             Word16 diff_e = sub( spec_side_x_e, frame_side_x_e );
    5186           0 :             FOR( i = 0; i < L_frame; i++ )
    5187             :             {
    5188           0 :                 x_fx[i] = L_shr( x_fx[i], diff_e );
    5189           0 :                 move32();
    5190             :             }
    5191             :         }
    5192      221229 :         *x_e = s_max( spec_side_x_e, frame_side_x_e );
    5193      221229 :         move16();
    5194             : 
    5195      221229 :         set32_fx( x_fx + L_spec, 0, sub( L_frameTCX, L_spec ) );
    5196             :     }
    5197             : 
    5198             :     /* PLC: [TCX: Tonal Concealment] */
    5199      853209 :     test();
    5200      853209 :     test();
    5201      853209 :     IF( bfi && st->tonal_mdct_plc_active && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    5202             :     {
    5203         201 :         TonalMDCTConceal_Apply_ivas_fx( st->hTonalMDCTConc, x_fx, *x_e, st->hTcxCfg->psychParamsCurrent );
    5204             : 
    5205             :         /* If exponent has been updated after TonalMDCTConceal_Apply, then shift the spectrum to common exponent. */
    5206             :     }
    5207             : 
    5208      853209 :     test();
    5209      853209 :     IF( st->hTonalMDCTConc != NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    5210             :     {
    5211      221229 :         tmp32 = L_deposit_h( 0 );
    5212      221229 :         if ( hTcxDec->tcxltp_last_gain_unmodified > 0 )
    5213             :         {
    5214      106680 :             tmp32 = st->old_fpitch;
    5215      106680 :             move32();
    5216             :         }
    5217             : 
    5218      221229 :         tmp8 = 0;
    5219      221229 :         move16();
    5220      221229 :         test();
    5221      221229 :         if ( bfi && st->tonal_mdct_plc_active )
    5222             :         {
    5223         201 :             tmp8 = 1;
    5224         201 :             move16();
    5225             :         }
    5226             : 
    5227      221229 :         TonalMDCTConceal_UpdateState( st->hTonalMDCTConc,
    5228             :                                       L_frameTCX,
    5229             :                                       tmp32,
    5230             :                                       bfi,
    5231             :                                       tmp8 );
    5232             :     }
    5233             : 
    5234      853209 :     *x_len = L_frameTCX;
    5235      853209 :     move16();
    5236             : 
    5237      853209 :     IF( st->enablePlcWaveadjust != 0 )
    5238             :     {
    5239           0 :         test();
    5240             :         /* spectrum concealment */
    5241           0 :         IF( bfi && EQ_16( *temp_concealment_method, TCX_NONTONAL ) )
    5242             :         {
    5243           0 :             concealment_decode_fix( st->core, x_fx, x_e, st->hPlcInfo );
    5244             :         }
    5245             : 
    5246             :         /* update spectrum buffer, tonality flag, etc. */
    5247           0 :         concealment_update_x( bfi, st->core, st->tonality_flag, x_fx, x_e, st->hPlcInfo );
    5248             : 
    5249           0 :         *x_len = s_max( *x_len, st->hPlcInfo->L_frameTCX );
    5250           0 :         move16();
    5251             :     }
    5252             : 
    5253             :     /*-----------------------------------------------------------*
    5254             :      * IGF                                                       *
    5255             :      *-----------------------------------------------------------*/
    5256             : 
    5257      853209 :     test();
    5258      853209 :     test();
    5259      853209 :     IF( st->igf && !( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
    5260             :     {
    5261      552337 :         IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    5262             :         {
    5263             :             Word16 igfGridIdx;
    5264             : 
    5265      206693 :             test();
    5266      206693 :             IF( ( EQ_16( st->last_core, ACELP_CORE ) ) || ( left_rect && bfi ) )
    5267             :             {
    5268             :                 /* packet loss after first TCX must be handled like transition frame */
    5269        6789 :                 igfGridIdx = IGF_GRID_LB_TRAN;
    5270        6789 :                 move16();
    5271             :             }
    5272             :             ELSE
    5273             :             {
    5274      199904 :                 igfGridIdx = IGF_GRID_LB_NORM;
    5275      199904 :                 move16();
    5276             :             }
    5277             : 
    5278      206693 :             IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, igfGridIdx, bfi, st->element_mode );
    5279             : 
    5280      206693 :             *x_len = s_max( *x_len, st->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine );
    5281      206693 :             move16();
    5282             :         }
    5283             :     }
    5284      853209 :     test();
    5285      853209 :     test();
    5286      853209 :     IF( st->igf && ( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
    5287             :     {
    5288       22394 :         IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    5289             :         {
    5290        3768 :             IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, IGF_GRID_LB_SHORT, bfi, st->element_mode );
    5291             : 
    5292        3768 :             *x_len = s_max( *x_len, st->hIGFDec->igfData.igfInfo.grid[IGF_GRID_LB_SHORT].stopLine );
    5293        3768 :             move16();
    5294             :         }
    5295             :     }
    5296             : 
    5297      853209 :     return;
    5298             : }
    5299             : 
    5300             : 
    5301             : /*-------------------------------------------------------------------*
    5302             :  *  decoder_tcx_tns()
    5303             :  *
    5304             :  *  TCX: TNS application
    5305             :  *-------------------------------------------------------------------*/
    5306             : 
    5307     1477701 : void decoder_tcx_tns_fx(
    5308             :     Decoder_State *st,         /* i/o: coder memory state                      */
    5309             :     const Word16 L_frame_glob, /* i  : frame length                            */
    5310             :     const Word16 L_spec,
    5311             :     const Word16 L_frame,
    5312             :     const Word16 L_frameTCX,
    5313             :     Word32 x_fx[N_MAX],   // Qx
    5314             :     const Word16 fUseTns, /* i  : flag that is set if TNS data is present */
    5315             :     STnsData *tnsData,
    5316             :     const Word16 bfi,       /* i  : Bad frame indicator                     */
    5317             :     const Word16 frame_cnt, /* i  : frame counter in the super frame        */
    5318             :     const Word16 whitenedDomain,
    5319             :     Word16 *length )
    5320             : {
    5321             :     Word16 index, isTCX5, L, tmp;
    5322     1477701 :     TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
    5323             : 
    5324     1477701 :     index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    5325     1477701 :     move16();
    5326             : 
    5327     1477701 :     isTCX5 = 0;
    5328     1477701 :     move16();
    5329     1477701 :     L = L_frameTCX;
    5330     1477701 :     move16();
    5331     1477701 :     tmp = L;
    5332     1477701 :     move16();
    5333             : 
    5334     1477701 :     test();
    5335     1477701 :     IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 )
    5336             :     {
    5337       60470 :         test();
    5338       60470 :         test();
    5339       60470 :         IF( frame_cnt != 0 && bfi == 0 && st->last_core != ACELP_CORE )
    5340             :         {
    5341             :             /* fix sub-window overlap */
    5342       30125 :             hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
    5343       30125 :             move16();
    5344             :         }
    5345             : 
    5346       60470 :         test();
    5347       60470 :         test();
    5348       60470 :         test();
    5349       60470 :         test();
    5350       60470 :         IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && whitenedDomain ) || GT_16( L_spec, L_frameTCX ) )
    5351             :         {
    5352       20838 :             L = L_spec;
    5353       20838 :             move16();
    5354       20838 :             tmp = L;
    5355       20838 :             move16();
    5356             :         }
    5357             : 
    5358       60470 :         test();
    5359       60470 :         test();
    5360       60470 :         test();
    5361       60470 :         test();
    5362       60470 :         test();
    5363       60470 :         test();
    5364       60470 :         test();
    5365       60470 :         IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ||
    5366             :                                    ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) ||
    5367             :             ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) &&
    5368             :                                    NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) )
    5369             :         {
    5370       31297 :             isTCX5 = 1;
    5371       31297 :             move16();
    5372             : 
    5373       31297 :             tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx );
    5374             :         }
    5375             :     }
    5376             : 
    5377             :     /*-----------------------------------------------------------*
    5378             :      * Temporal Noise Shaping Synthesis                          *
    5379             :      *-----------------------------------------------------------*/
    5380             : 
    5381             : 
    5382     1477701 :     test();
    5383     1477701 :     test();
    5384     1477701 :     test();
    5385     1477701 :     IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && fUseTns != 0 && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) )
    5386             :     {
    5387             :         /* Apply TNS to get the reconstructed signal */
    5388       86562 :         SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
    5389             : 
    5390       86562 :         test();
    5391       86562 :         test();
    5392       86562 :         IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 )
    5393             :         {
    5394       12772 :             tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx );
    5395             :         }
    5396             : 
    5397       86562 :         ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 );
    5398             : 
    5399       86562 :         test();
    5400       86562 :         test();
    5401       86562 :         IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 )
    5402             :         {
    5403       12772 :             test();
    5404       12772 :             test();
    5405       12772 :             IF( st->element_mode == EVS_MONO || ( LT_16( L_spec, L_frameTCX ) && !whitenedDomain ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */
    5406             :             {
    5407        1197 :                 tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC );
    5408        1197 :                 tmp = L_frameTCX;
    5409        1197 :                 move16();
    5410             :             }
    5411             :             ELSE
    5412             :             {
    5413       11575 :                 tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC );
    5414             :             }
    5415             :         }
    5416             :     }
    5417     1477701 :     test();
    5418     1477701 :     IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) )
    5419             :     {
    5420       14611 :         tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx );
    5421             :     }
    5422             : 
    5423             :     /* restore index */
    5424     1477701 :     test();
    5425     1477701 :     test();
    5426     1477701 :     test();
    5427     1477701 :     test();
    5428     1477701 :     IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) )
    5429             :     {
    5430             :         /* restore sub-window overlap */
    5431       30125 :         hTcxCfg->tcx_last_overlap_mode = index;
    5432       30125 :         move16();
    5433             :     }
    5434             : 
    5435     1477701 :     if ( length != NULL )
    5436             :     {
    5437     1256472 :         *length = tmp;
    5438     1256472 :         move16();
    5439             :     }
    5440             : 
    5441     1477701 :     return;
    5442             : }
    5443             : 
    5444             : 
    5445      849465 : void decoder_tcx_imdct_fx(
    5446             :     Decoder_State *st,         /* i/o: coder memory state                      */
    5447             :     const Word16 L_frame_glob, /* i  : frame length                            */
    5448             :     const Word16 L_frameTCX_glob,
    5449             :     const Word16 L_spec,
    5450             :     const Word16 tcx_offset,
    5451             :     const Word16 tcx_offsetFB,
    5452             :     const Word16 L_frame,
    5453             :     const Word16 L_frameTCX,
    5454             :     const Word16 left_rect,
    5455             :     Word32 x_fx[N_MAX], // Q(11)
    5456             :     Word16 q_x,
    5457             :     Word16 xn_buf_fx[], // Q(-2)
    5458             :     Word16 *q_win,
    5459             :     Word16 *q_winFB,
    5460             :     const UWord16 kernelType,          /* i  : TCX transform kernel type               */
    5461             :     const Word16 fUseTns,              /* i  : flag that is set if TNS data is present */
    5462             :     Word16 synth_fx[],                 // Q(-2)             /* i/o: synth[-M..L_frame]                      */
    5463             :     Word16 synthFB_fx[],               // Q(-2)
    5464             :     const Word16 bfi,                  /* i  :  Bad frame indicator                    */
    5465             :     const Word16 frame_cnt,            /* i  : frame counter in the super frame        */
    5466             :     const Word16 sba_dirac_stereo_flag /* i  : signal stereo output for SBA DirAC      */
    5467             : )
    5468             : {
    5469             :     Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5;
    5470             :     Word16 overlapFB;
    5471             :     Word32 x_tmp_fx[L_FRAME_PLUS];
    5472      849465 :     Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 };
    5473             :     Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
    5474             :     Word16 acelp_zir_fx[L_FRAME_MAX / 2];
    5475             :     Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN];
    5476      849465 :     Word16 index, proc = 0;
    5477      849465 :     TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
    5478      849465 :     TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
    5479      849465 :     TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
    5480             :     Word16 predictionGain_fx;
    5481             :     Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf
    5482      849465 :     Word16 q_a_itf = 15;
    5483      849465 :     Word16 x_e = sub( 31, q_x );
    5484      849465 :     move16();
    5485      849465 :     Word16 q_acelp_zir_fx = 0;
    5486      849465 :     set16_fx( acelp_zir_fx, 0, L_FRAME_MAX / 2 );
    5487             : 
    5488             :     /*-----------------------------------------------------------------*
    5489             :      * Initializations
    5490             :      *-----------------------------------------------------------------*/
    5491             : 
    5492             :     /* Init lengths */
    5493      849465 :     overlap = hTcxCfg->tcx_mdct_window_length;
    5494      849465 :     move16();
    5495      849465 :     overlapFB = hTcxCfg->tcx_mdct_window_lengthFB;
    5496      849465 :     move16();
    5497             : 
    5498      849465 :     index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    5499      849465 :     move16();
    5500      849465 :     test();
    5501      849465 :     test();
    5502      849465 :     test();
    5503      849465 :     test();
    5504      849465 :     IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) )
    5505             :     {
    5506             :         /* fix sub-window overlap */
    5507       16032 :         hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
    5508       16032 :         move16();
    5509             :     }
    5510             : 
    5511      849465 :     IF( st->igf != 0 )
    5512             :     {
    5513      573352 :         proc = st->hIGFDec->flatteningTrigger;
    5514      573352 :         move16();
    5515             : 
    5516      573352 :         test();
    5517      573352 :         IF( proc && fUseTns != 0 )
    5518             :         {
    5519       57699 :             proc = 0;
    5520       57699 :             move16();
    5521             :         }
    5522             : 
    5523      573352 :         IF( proc )
    5524             :         {
    5525             : 
    5526      496332 :             startLine = st->hIGFDec->infoIGFStartLine;
    5527      496332 :             move16();
    5528      496332 :             endLine = st->hIGFDec->infoIGFStopLine;
    5529      496332 :             move16();
    5530      496332 :             curr_order = 0;
    5531      496332 :             move16();
    5532      496332 :             predictionGain_fx = 0;
    5533      496332 :             move16();
    5534      496332 :             L = L_frameTCX;
    5535      496332 :             move16();
    5536      496332 :             isTCX5 = 0;
    5537      496332 :             move16();
    5538             : 
    5539             :             /* interleave again for ITF */
    5540      496332 :             test();
    5541      496332 :             IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly )
    5542             :             {
    5543        9274 :                 test();
    5544        9274 :                 test();
    5545        9274 :                 test();
    5546        9274 :                 IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) )
    5547             :                 {
    5548        1436 :                     L = L_spec;
    5549        1436 :                     move16();
    5550             :                 }
    5551             : 
    5552        9274 :                 test();
    5553        9274 :                 test();
    5554        9274 :                 test();
    5555        9274 :                 test();
    5556        9274 :                 test();
    5557        9274 :                 test();
    5558        9274 :                 test();
    5559        9274 :                 test();
    5560        9274 :                 test();
    5561        9274 :                 test();
    5562        9274 :                 IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
    5563             :                                         ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) ||
    5564             :                     ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) &&
    5565             :                                         ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) )
    5566             :                 {
    5567        2201 :                     isTCX5 = 1;
    5568        2201 :                     move16();
    5569             : 
    5570        2201 :                     tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx );
    5571             :                 }
    5572             :             }
    5573             : 
    5574   146355536 :             FOR( j = startLine; j < endLine; j++ )
    5575             :             {
    5576   145859204 :                 IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) )
    5577             :                 {
    5578       20689 :                     x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x
    5579       20689 :                     move32();
    5580       20689 :                     x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN];
    5581       20689 :                     move32();
    5582             :                 }
    5583             :             }
    5584             : 
    5585      496332 :             ITF_Detect_ivas_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, q_x );
    5586             : 
    5587      496332 :             ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order );
    5588             : 
    5589   146355536 :             FOR( j = startLine; j < endLine; j++ )
    5590             :             {
    5591   145859204 :                 IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) )
    5592             :                 {
    5593       20689 :                     x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x
    5594       20689 :                     move32();
    5595             :                 }
    5596             :             }
    5597             : 
    5598             :             /* deinterleave */
    5599      496332 :             IF( NE_16( isTCX5, 0 ) )
    5600             :             {
    5601        2201 :                 tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx );
    5602             :             }
    5603             :         }
    5604             :     }
    5605             : 
    5606             :     /*-----------------------------------------------------------*
    5607             :      * Prepare OLA buffer after waveadjustment.                  *
    5608             :      * Compute inverse MDCT of x[].                              *
    5609             :      *-----------------------------------------------------------*/
    5610             : 
    5611             : 
    5612      849465 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    5613             :     {
    5614      628236 :         Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) );
    5615      628236 :         set32_fx( x_tmp_fx, 0, L_FRAME_PLUS );
    5616      628236 :         Copy32( x_fx, x_tmp_fx, copy_len );    // q_x
    5617      628236 :         Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x
    5618             :     }
    5619      221229 :     ELSE IF( ( st->element_mode == EVS_MONO ) )
    5620             :     {
    5621           0 :         Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x
    5622             :     }
    5623             :     ELSE
    5624             :     {
    5625      221229 :         Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) );
    5626      221229 :         Copy32( x_fx, x_tmp_fx, copy_len );    // q_x
    5627      221229 :         Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x
    5628             :     }
    5629             : 
    5630      849465 :     IF( ( st->igf != 0 ) )
    5631             :     {
    5632      573352 :         set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine );
    5633             :     }
    5634             : 
    5635      849465 :     test();
    5636      849465 :     IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag )
    5637             :     {
    5638             : 
    5639     1665550 :         IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, &hTcxDec->Q_syn_Overl, hTcxDec->syn_Overl_TDAC, &hTcxDec->Q_syn_Overl_TDAC, xn_buf_fx, *q_win, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2,
    5640      832775 :                        hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index,
    5641      832775 :                        kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, &st->hHQ_core->Q_old_wtda_LB, 0, st, 0, acelp_zir_fx, &q_acelp_zir_fx, q_win );
    5642             :     }
    5643             : 
    5644             :     /* Generate additional comfort noise to mask potential coding artefacts */
    5645      849465 :     test();
    5646      849465 :     test();
    5647      849465 :     test();
    5648      849465 :     IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) )
    5649             :     {
    5650       23452 :         generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom );
    5651     6904924 :         FOR( Word16 ind = 0; ind < L_frame; ind++ )
    5652             :         {
    5653     6881472 :             x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x
    5654             :         }
    5655             :     }
    5656             : 
    5657      849465 :     test();
    5658      849465 :     IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) )
    5659             :     {
    5660       16690 :         Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x
    5661       16690 :         IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, &hTcxDec->Q_syn_Overl, hTcxDec->syn_Overl_TDAC, &hTcxDec->Q_syn_Overl_TDAC, xn_buf_fx, *q_win, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index,
    5662       16690 :                        kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, &st->hHQ_core->Q_old_wtda_LB, 0, st, 0, acelp_zir_fx, &q_acelp_zir_fx, q_win );
    5663             :     }
    5664             : 
    5665             :     Word16 shift_q, q_x16;
    5666             : 
    5667      849465 :     shift_q = L_norm_arr( xn_bufFB_fx, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX );
    5668      849465 :     shift_q = sub( 16, shift_q );
    5669      849465 :     q_x16 = sub( q_x, shift_q );
    5670             : 
    5671  1733758065 :     FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ )
    5672             :     {
    5673  1732908600 :         assert( extract_h( L_shr( xn_bufFB_fx[ind], shift_q ) ) == 0 || extract_h( L_shr( xn_bufFB_fx[ind], shift_q ) ) == -1 );
    5674  1732908600 :         xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x16
    5675  1732908600 :         move16();
    5676             :     }
    5677             : 
    5678             :     Word16 ratio_e;
    5679      849465 :     Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9)
    5680      849465 :     ratio = shr( ratio, sub( 6, ratio_e ) );
    5681             : 
    5682      849465 :     IF( st->element_mode != EVS_MONO )
    5683             :     {
    5684     1698930 :         IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, &hTcxDec->Q_syn_OverlFB, hTcxDec->syn_Overl_TDACFB, &hTcxDec->Q_syn_Overl_TDACFB, xn_bufFB_fx_16, q_x16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB,
    5685      849465 :                        hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index,
    5686      849465 :                        kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, 1, st, ratio, acelp_zir_fx, &q_acelp_zir_fx, q_winFB );
    5687             :     }
    5688             :     ELSE
    5689             :     {
    5690           0 :         IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, &hTcxDec->Q_syn_OverlFB, hTcxDec->syn_Overl_TDACFB, &hTcxDec->Q_syn_Overl_TDACFB, xn_bufFB_fx_16, q_x16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index,
    5691           0 :                        kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, 1, st, ratio, acelp_zir_fx, &q_acelp_zir_fx, q_winFB );
    5692             :     }
    5693             : 
    5694      849465 :     shift_q = 16;
    5695      849465 :     move16();
    5696             : 
    5697  1733758065 :     FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ )
    5698             :     {
    5699  1732908600 :         xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // q_winFB
    5700             :     }
    5701             : 
    5702      849465 :     IF( ( bfi == 0 ) )
    5703             :     {
    5704      840760 :         Word16 res_m, res_e = 0;
    5705      840760 :         move16();
    5706      840760 :         st->second_last_tns_active = st->last_tns_active;
    5707      840760 :         move16();
    5708      840760 :         st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns;
    5709      840760 :         move16();
    5710      840760 :         hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch;
    5711      840760 :         move32();
    5712      840760 :         hTcxDec->tcxltp_second_last_pitch = st->old_fpitch;
    5713      840760 :         move32();
    5714      840760 :         res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e );
    5715      840760 :         st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) );
    5716             : 
    5717      840760 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    5718             :         {
    5719             :             // Using sat as a single instruction shifts and extracts
    5720      621233 :             st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8
    5721      621233 :             move32();
    5722             :         }
    5723             : 
    5724      840760 :         IF( GT_16( st->element_mode, EVS_MONO ) )
    5725             :         {
    5726      840760 :             res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e );
    5727      840760 :             st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e );
    5728      840760 :             move32();
    5729             :         }
    5730             :         ELSE
    5731             :         {
    5732           0 :             res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e );
    5733           0 :             st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e );
    5734           0 :             move32();
    5735             :         }
    5736             :     }
    5737             : 
    5738             :     /* Update old_syn_overl */
    5739      849465 :     IF( hTcxCfg->last_aldo == 0 )
    5740             :     {
    5741       21724 :         Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // q_win
    5742     7722004 :         FOR( Word16 ind = 0; ind < overlapFB; ind++ )
    5743             :         {
    5744     7700280 :             assert( extract_h( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ) == 0 || extract_h( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ) == -1 );
    5745     7700280 :             hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_winFB
    5746             :         }
    5747             :     }
    5748             : 
    5749             :     /* Output */
    5750      849465 :     Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // q_win
    5751   698369465 :     FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ )
    5752             :     {
    5753   697520000 :         assert( extract_h( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ) == 0 ||
    5754             :                 extract_h( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ) == -1 );
    5755   697520000 :         synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_winFB
    5756             :     }
    5757             : 
    5758             : 
    5759      849465 :     return;
    5760             : }

Generated by: LCOV version 1.14