LCOV - code coverage report
Current view: top level - lib_dec - dec_tcx_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e0be88e06c25f79c221b2595d2ee00b3ed6d605a Lines: 2121 2709 78.3 %
Date: 2025-11-22 02:05:22 Functions: 20 21 95.2 %

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

Generated by: LCOV version 1.14