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

Generated by: LCOV version 1.14