LCOV - code coverage report
Current view: top level - lib_enc - cod_tcx_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 3fe45f3a13339b229bdd4169e742797bb5eb1c89 Lines: 2124 2607 81.5 %
Date: 2025-10-27 01:59:47 Functions: 16 17 94.1 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : 
       6             : #include <stdlib.h>
       7             : #include <stdio.h>
       8             : #include <assert.h>
       9             : #include "rom_com.h"
      10             : #include "stat_com.h"
      11             : #include "prot_fx.h"
      12             : #include "basop_util.h"
      13             : #include "stl.h"
      14             : #include "prot_fx_enc.h"
      15             : #include <math.h>
      16             : #include "ivas_prot_fx.h"
      17             : #include "ivas_rom_com.h"
      18             : #ifdef DEBUGGING
      19             : #include "debug.h"
      20             : #endif
      21             : 
      22             : 
      23             : #define SIMILAR_TNS_THRESHOLD_FX_IN_Q15        ( 1311 )
      24             : #define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7  ( 384 )
      25             : #define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ( 25165824 )
      26             : 
      27             : /* Up to the Autocorrelation it is the same code as in GetMDCT, with the difference in the parameters in the call to tcx_windowing_analysis */
      28      108948 : void HBAutocorrelation_fx(
      29             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
      30             :     Word16 left_overlap_mode,  /* input: overlap mode of left window half   */
      31             :     Word16 right_overlap_mode, /* input: overlap mode of right window half  */
      32             :     Word16 speech[],           /* input: speech[-LFAC..L_frame+LFAC]   Qx*/
      33             :     Word16 L_frame,            /* input: frame length                  */
      34             :     Word32 *r,                 /* output: autocorrelations vector */
      35             :     Word16 m                   /* input : order of LP filter      */
      36             : )
      37             : {
      38             :     Word16 i, j, left_overlap, right_overlap;
      39             :     Word16 len, norm, shift, fact;
      40             :     Word32 L_tmp, L_sum;
      41             :     Word16 y[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
      42             : 
      43             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      44      108948 :     Flag Overflow = 0;
      45      108948 :     move32();
      46             : #endif
      47             : 
      48             :     /*-----------------------------------------------------------*
      49             :      * Windowing                                                 *
      50             :      *-----------------------------------------------------------*/
      51             : 
      52      108948 :     WindowSignal( hTcxCfg, hTcxCfg->tcx_offset, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, speech, &L_frame, y, 1, 0 );
      53             : 
      54             :     /*-----------------------------------------------------------*
      55             :      * Autocorrelation                                           *
      56             :      *-----------------------------------------------------------*/
      57             : 
      58      108948 :     len = add( L_frame, shr( add( left_overlap, right_overlap ), 1 ) );
      59             : 
      60             :     /* calculate shift */
      61      108948 :     shift = 0;
      62      108948 :     move16();
      63      108948 :     L_sum = L_deposit_l( 0 );
      64      108948 :     Overflow = 0;
      65      108948 :     move32();
      66    96671397 :     FOR( i = 0; i < len; i += 1 )
      67             :     {
      68             :         /* Test Addition */
      69    96562451 :         L_mac0_o( L_sum, y[i], y[i], &Overflow );
      70    96562451 :         IF( Overflow )
      71             :         {
      72           2 :             Overflow = 0;
      73           2 :             move32();
      74           2 :             shift = 1;
      75           2 :             move16();
      76           2 :             L_tmp = L_msu0( 0, y[i], y[i] );
      77           2 :             L_tmp = L_shr( L_tmp, 1 );
      78           2 :             L_sum = L_add( L_shr( L_sub_o( L_sum, 1, &Overflow ), 1 ), 1 );
      79           2 :             L_sum = L_sub_o( L_sum, L_tmp, &Overflow );
      80         375 :             FOR( j = i + 1; j < len; j++ )
      81             :             {
      82         373 :                 L_tmp = L_msu0( 0, y[j], y[j] );
      83         373 :                 L_tmp = L_shr( L_tmp, shift );
      84             : 
      85             :                 /* Test Addition */
      86         373 :                 L_sub_o( L_sum, L_tmp, &Overflow );
      87         373 :                 IF( Overflow )
      88             :                 {
      89           0 :                     Overflow = 0;
      90           0 :                     move32();
      91           0 :                     shift = add( shift, 1 );
      92           0 :                     L_tmp = L_shr( L_tmp, 1 );
      93           0 :                     L_sum = L_add( L_shr( L_sub_o( L_sum, 1, &Overflow ), 1 ), 1 );
      94             :                 }
      95         373 :                 L_sum = L_sub_o( L_sum, L_tmp, &Overflow );
      96             :             }
      97           2 :             BREAK;
      98             :         }
      99             :         /* Perform Addition */
     100    96562449 :         L_sum = L_mac0_o( L_sum, y[i], y[i], &Overflow );
     101             :     }
     102             : 
     103             :     /* scale signal to avoid overflow in autocorrelation */
     104      108948 :     IF( shift > 0 )
     105             :     {
     106           2 :         fact = lshr( -32768, shift );
     107        1474 :         FOR( i = 0; i < len; i++ )
     108             :         {
     109        1472 :             y[i] = mult_r( y[i], fact );
     110        1472 :             move16();
     111             :         }
     112             :     }
     113             : 
     114             :     /* Compute and normalize r[0] */
     115      108948 :     L_sum = L_mac0( 1, y[0], y[0] );
     116    96562824 :     FOR( i = 1; i < len; i++ )
     117             :     {
     118    96453876 :         L_sum = L_mac0( L_sum, y[i], y[i] );
     119             :     }
     120             : 
     121      108948 :     norm = norm_l( L_sum );
     122      108948 :     L_sum = L_shl( L_sum, norm );
     123      108948 :     r[0] = L_sum;
     124      108948 :     move32();
     125             : 
     126             :     /* Compute r[1] to r[m] */
     127     1852116 :     FOR( i = 1; i <= m; i++ )
     128             :     {
     129     1743168 :         L_sum = L_mult0( y[0], y[i] );
     130  1530188256 :         FOR( j = 1; j < len - i; j++ )
     131             :         {
     132  1528445088 :             L_sum = L_mac0( L_sum, y[j], y[j + i] );
     133             :         }
     134             : 
     135     1743168 :         L_sum = L_shl( L_sum, norm );
     136     1743168 :         r[i] = L_sum;
     137     1743168 :         move32();
     138             :     }
     139      108948 : }
     140             : 
     141         372 : void TNSAnalysis_fx(
     142             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
     143             :     Word16 L_frame,            /* input: frame length */
     144             :     Word16 L_spec,
     145             :     Word16 tcxMode,        /* input: TCX mode for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */
     146             :     Word8 isAfterACELP,    /* input: Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0  */
     147             :     Word32 spectrum[],     /* input: MDCT spectrum  Qx*/
     148             :     STnsData *pTnsData,    /* output: Tns data */
     149             :     Word8 *pfUseTns,       /* output: Flag indicating if TNS is used */
     150             :     Word16 *predictionGain /*Q7*/
     151             : )
     152             : {
     153             :     Word32 buff[8];
     154         372 :     Word16 tmp = 0;  /* initialization only to avoid compiler warning, not counted */
     155         372 :     Word16 tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
     156         372 :     move16();
     157         372 :     move16();
     158             : 
     159             :     /* Init TNS */
     160         372 :     *pfUseTns = 0;
     161         372 :     move16();
     162             : 
     163         372 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
     164             :     {
     165         372 :         hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( tcxMode - TCX_20 ) == 0][isAfterACELP];
     166         372 :         L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
     167         372 :         move16();
     168             : 
     169             :         /*-----------------------------------------------------------*
     170             :          * Temporal Noise Shaping analysis                           *
     171             :          *-----------------------------------------------------------*/
     172             : 
     173         372 :         IF( EQ_16( tcxMode, TCX_5 ) )
     174             :         {
     175           0 :             tmp = shr( L_frame, 2 );
     176             : 
     177             :             /* rearrange LF sub-window lines prior to TNS analysis & filtering */
     178           0 :             tmp2 = shr( L_spec, 1 );
     179             : 
     180           0 :             IF( LT_16( tmp2, tmp ) )
     181             :             {
     182           0 :                 Copy32( spectrum + 8, spectrum + 16, sub( tmp2, 8 ) );
     183           0 :                 Copy32( spectrum + tmp, spectrum + 8, 8 );
     184           0 :                 Copy32( spectrum + tmp + 8, spectrum + tmp2 + 8, sub( tmp2, 8 ) );
     185             :             }
     186             :             ELSE
     187             :             {
     188           0 :                 Copy32( spectrum + tmp, buff, 8 );
     189           0 :                 Copy32( spectrum + 8, spectrum + 16, sub( tmp, 8 ) );
     190           0 :                 Copy32( buff, spectrum + 8, 8 );
     191             :             }
     192             :         }
     193             : 
     194         372 :         move16();
     195         372 :         *pfUseTns = (Word8) DetectTnsFilt_fx( hTcxCfg->pCurrentTnsConfig, spectrum, pTnsData, predictionGain );
     196             : 
     197             :         /* If TNS should be used then get the residual after applying it inplace in spectrum */
     198         372 :         IF( *pfUseTns != 0 )
     199             :         {
     200           4 :             ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
     201             :         }
     202             : 
     203         372 :         IF( EQ_16( tcxMode, TCX_5 ) )
     204             :         {
     205             :             /* undo rearrangement of LF sub-window lines prior to TNS analysis */
     206           0 :             IF( LT_16( tmp2, tmp ) )
     207             :             {
     208           0 :                 Copy32( spectrum + tmp2 + 8, spectrum + tmp + 8, sub( tmp2, 8 ) );
     209           0 :                 Copy32( spectrum + 8, spectrum + tmp, 8 );
     210           0 :                 Copy32( spectrum + 16, spectrum + 8, sub( tmp2, 8 ) );
     211           0 :                 set32_fx( spectrum + tmp2, 0, sub( tmp, tmp2 ) );
     212           0 :                 set32_fx( spectrum + tmp + tmp2, 0, sub( tmp, tmp2 ) );
     213             :             }
     214             :             ELSE
     215             :             {
     216           0 :                 Copy32( spectrum + 8, buff, 8 );
     217           0 :                 Copy32( spectrum + 16, spectrum + 8, sub( tmp, 8 ) );
     218           0 :                 Copy32( buff, spectrum + tmp, 8 );
     219             :             }
     220             :         }
     221             :     }
     222         372 : }
     223             : 
     224      238521 : void TNSAnalysis_ivas_fx(
     225             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
     226             :     Word16 L_frame,            /* i  : frame length */
     227             :     Word16 L_spec,             /* i  : length of the spectrum                                                                  */
     228             :     Word16 transform_type,     /* i  : transform type for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5)        */
     229             :     Word8 isAfterACELP,        /* i  : Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0  */
     230             :     Word32 spectrum[],         /* i  : MDCT spectrum  Q=Qx*/
     231             :     TRAN_DET_HANDLE hTranDet,  /* i  : handle transient detection                                                              */
     232             :     Word16 ltp_gain,           /* i  : ltp gain  Q=15*/
     233             :     STnsData *pTnsData,        /* o  : Tns data */
     234             :     Word8 *pfUseTns,           /* o  : Flag indicating if TNS is used */
     235             :     Word16 *predictionGain     /* o  : TNS prediction gain      Q=7      */
     236             : )
     237             : {
     238             :     Word32 buff[8];
     239      238521 :     Word16 tmp = 0;  /* initialization only to avoid compiler warning, not counted */
     240      238521 :     Word16 tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
     241      238521 :     move16();
     242      238521 :     move16();
     243             : 
     244             :     /* Init TNS */
     245      238521 :     *pfUseTns = 0;
     246      238521 :     move16();
     247             : 
     248      238521 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
     249             :     {
     250      161673 :         hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( transform_type - TCX_20 ) == 0][isAfterACELP];
     251      161673 :         L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
     252      161673 :         move16();
     253             : 
     254             :         /*-----------------------------------------------------------*
     255             :          * Temporal Noise Shaping analysis                           *
     256             :          *-----------------------------------------------------------*/
     257             : 
     258      161673 :         IF( EQ_16( transform_type, TCX_5 ) )
     259             :         {
     260        2197 :             tmp = shr( L_frame, 2 );
     261             : 
     262             :             /* rearrange LF sub-window lines prior to TNS analysis & filtering */
     263        2197 :             tmp2 = shr( L_spec, 1 );
     264             : 
     265        2197 :             IF( LT_16( tmp2, tmp ) )
     266             :             {
     267        2129 :                 Copy32( spectrum + 8, spectrum + 16, sub( tmp2, 8 ) );
     268        2129 :                 Copy32( spectrum + tmp, spectrum + 8, 8 );
     269        2129 :                 Copy32( spectrum + tmp + 8, spectrum + tmp2 + 8, sub( tmp2, 8 ) );
     270             :             }
     271             :             ELSE
     272             :             {
     273          68 :                 Copy32( spectrum + tmp, buff, 8 );
     274          68 :                 Copy32( spectrum + 8, spectrum + 16, sub( tmp, 8 ) );
     275          68 :                 Copy32( buff, spectrum + 8, 8 );
     276             :             }
     277             :         }
     278             : 
     279      161673 :         move16();
     280      161673 :         *pfUseTns = (Word8) DetectTnsFilt_ivas_fx( hTcxCfg->pCurrentTnsConfig, spectrum, pTnsData, hTranDet, (Word8) NE_16( transform_type, TCX_20 ), ltp_gain, predictionGain );
     281             : 
     282             :         /* If TNS should be used then get the residual after applying it inplace in spectrum */
     283      161673 :         IF( *pfUseTns != 0 )
     284             :         {
     285       17593 :             ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
     286             :         }
     287             : 
     288      161673 :         IF( EQ_16( transform_type, TCX_5 ) )
     289             :         {
     290             :             /* undo rearrangement of LF sub-window lines prior to TNS analysis */
     291        2197 :             IF( LT_16( tmp2, tmp ) )
     292             :             {
     293        2129 :                 Copy32( spectrum + tmp2 + 8, spectrum + tmp + 8, sub( tmp2, 8 ) );
     294        2129 :                 Copy32( spectrum + 8, spectrum + tmp, 8 );
     295        2129 :                 Copy32( spectrum + 16, spectrum + 8, sub( tmp2, 8 ) );
     296        2129 :                 set32_fx( spectrum + tmp2, 0, sub( tmp, tmp2 ) );
     297        2129 :                 set32_fx( spectrum + tmp + tmp2, 0, sub( tmp, tmp2 ) );
     298             :             }
     299             :             ELSE
     300             :             {
     301          68 :                 Copy32( spectrum + 8, buff, 8 );
     302          68 :                 Copy32( spectrum + 16, spectrum + 8, sub( tmp, 8 ) );
     303          68 :                 Copy32( buff, spectrum + tmp, 8 );
     304             :             }
     305             :         }
     306             :     }
     307      238521 : }
     308             : 
     309         634 : void ShapeSpectrum_fx(
     310             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
     311             :     Word16 A[],                /* input: quantized coefficients NxAz_q[M+1]  Q = 14 - norm(A[0])*/
     312             :     Word16 gainlpc[],          /* output: MDCT gains for the previous frame Q(15-gainlpc_e)*/
     313             :     Word16 gainlpc_e[],        /* output: MDCT gains exponents */
     314             :     Word16 L_frame_glob,       /* input: frame length             */
     315             :     Word16 L_spec,
     316             :     Word32 spectrum[], /* i/o: MDCT spectrum */
     317             :     Word8 pfUseTns,    /* output: Flag indicating if TNS is used */
     318             :     Encoder_State *st )
     319             : {
     320             :     Word16 L_frame;
     321             :     Word16 Ap[M + 2];
     322             :     Word16 gamma1;
     323             :     Word16 gainlpc_noinv[FDNS_NPTS];
     324             :     Word16 gainlpc_noinv_e[FDNS_NPTS];
     325             :     Word16 i;
     326         634 :     Word32 max_low_pre = 0, max_high_pre = 0;
     327         634 :     move32();
     328         634 :     move32();
     329         634 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     330             : 
     331             :     /*-----------------------------------------------------------*
     332             :      * Init                                                      *
     333             :      *-----------------------------------------------------------*/
     334             : 
     335             :     /* Init lengths */
     336         634 :     L_frame = L_frame_glob;
     337         634 :     move16();
     338         634 :     gamma1 = st->gamma;
     339         634 :     move16();
     340         634 :     if ( st->enableTcxLpc != 0 )
     341             :     {
     342           0 :         gamma1 = 0x7FFF;
     343           0 :         move16();
     344             :     }
     345             : 
     346             :     /* if past frame is ACELP */
     347             : 
     348         634 :     IF( st->last_core == ACELP_CORE )
     349             :     {
     350          38 :         L_frame = add( L_frame, hTcxCfg->tcx_offset );
     351          38 :         L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
     352          38 :         if ( hTcxCfg->lfacNext < 0 )
     353             :         {
     354          38 :             L_frame = sub( L_frame, hTcxCfg->lfacNext );
     355          38 :             move16();
     356             :         }
     357             :     }
     358             : 
     359         634 :     test();
     360         634 :     tcxGetNoiseFillingTilt( A,
     361             :                             M,
     362             :                             L_frame,
     363         634 :                             ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 ),
     364             :                             &hTcxEnc->noiseTiltFactor );
     365             : 
     366             :     /* Calculate Spectrum Flatness Measure for the TCX Concealment */
     367         634 :     IF( st->enablePlcWaveadjust )
     368             :     {
     369           0 :         hTcxCfg->SFM2 = SFM_Cal_fx( spectrum, s_min( 200, L_frame ) );
     370           0 :         move32();
     371             :     }
     372             : 
     373         634 :     test();
     374         634 :     test();
     375         634 :     test();
     376         634 :     IF( ( EQ_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->bwidth, SWB ) ) ||
     377             :         ( EQ_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) )
     378             :     {
     379         262 :         max_low_pre = 0;
     380         262 :         move32();
     381       68294 :         FOR( i = 0; i < L_frame; i++ )
     382             :         {
     383       68032 :             Word32 tmp = L_abs( spectrum[i] );
     384       68032 :             if ( GT_32( tmp, max_low_pre ) )
     385             :             {
     386        1624 :                 max_low_pre = tmp;
     387        1624 :                 move32();
     388             :             }
     389             :         }
     390             : 
     391         262 :         max_high_pre = 0;
     392         262 :         move32();
     393      102310 :         FOR( i = 0; i < L_spec - L_frame; i++ )
     394             :         {
     395      102048 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     396      102048 :             if ( GT_32( tmp, max_high_pre ) )
     397             :             {
     398           2 :                 max_high_pre = tmp;
     399           2 :                 move32();
     400             :             }
     401             :         }
     402             :     }
     403             : 
     404             :     /*-----------------------------------------------------------*
     405             :      * Pre-shaping in frequency domain using weighted LPC (Wz)   *
     406             :      *-----------------------------------------------------------*/
     407             : 
     408         634 :     weight_a_fx( A, Ap, gamma1, M );
     409             : 
     410         634 :     lpc2mdct( Ap, M, gainlpc_noinv, gainlpc_noinv_e, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
     411             : 
     412         634 :     mdct_shaping( spectrum, L_frame, gainlpc_noinv, gainlpc_noinv_e );
     413      223562 :     FOR( i = L_frame; i < L_spec; i++ )
     414             :     {
     415      222928 :         spectrum[i] = L_shl( Mpy_32_16_1( spectrum[i], gainlpc_noinv[FDNS_NPTS - 1] ), gainlpc_noinv_e[FDNS_NPTS - 1] );
     416      222928 :         move32();
     417             :     }
     418             : 
     419             :     /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
     420         634 :     test();
     421         634 :     test();
     422         634 :     test();
     423         634 :     IF( ( EQ_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->bwidth, SWB ) ) ||
     424             :         ( EQ_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) )
     425             :     {
     426             :         Word16 sf_width;
     427             :         Word16 dist_low, dist_high;
     428             :         Word16 max_fac_s, max_fac_m;
     429             :         Word32 max_low, max_low1, max_low2, max_high;
     430             :         Word16 headroom, shift, tmp16;
     431             : 
     432             : 
     433         262 :         max_fac_m = 24576;
     434         262 :         move16();
     435             :         /* max_fac = 3 */
     436         262 :         max_fac_s = 2;
     437         262 :         move16();
     438         262 :         if ( hTcxEnc->tcx_lpc_shaped_ari )
     439             :         {
     440             :             /* max_fac = 1.5 */
     441           0 :             max_fac_s = 1;
     442           0 :             move16();
     443             :         }
     444             : 
     445         262 :         sf_width = shr( L_frame, 1 );
     446             : 
     447         262 :         max_low2 = 0;
     448         262 :         move32();
     449         262 :         dist_low = 0;
     450         262 :         move16();
     451       34278 :         FOR( i = 0; i < sf_width; i++ )
     452             :         {
     453       34016 :             Word32 tmp = L_abs( spectrum[L_frame - 1 - i] );
     454       34016 :             IF( GT_32( tmp, max_low2 ) )
     455             :             {
     456        1490 :                 max_low2 = tmp;
     457        1490 :                 move32();
     458        1490 :                 dist_low = i;
     459        1490 :                 move16();
     460             :             }
     461             :         }
     462             : 
     463         262 :         max_low1 = 0;
     464         262 :         move32();
     465       34278 :         FOR( i = 0; i < ( L_frame - sf_width ); i++ )
     466             :         {
     467       34016 :             Word32 tmp = L_abs( spectrum[L_frame - sf_width - 1 - i] );
     468       34016 :             if ( GT_32( tmp, max_low1 ) )
     469             :             {
     470        2350 :                 max_low1 = tmp;
     471        2350 :                 move32();
     472             :             }
     473       34016 :             if ( GT_32( tmp, max_low2 ) )
     474             :             {
     475        3886 :                 dist_low = add( sf_width, i );
     476             :             }
     477             :         }
     478             : 
     479         262 :         max_low = L_max( max_low1, max_low2 );
     480             : 
     481         262 :         max_high = 0;
     482         262 :         move32();
     483         262 :         dist_high = 0;
     484         262 :         move16();
     485      102310 :         FOR( i = 0; i < ( L_spec - L_frame ); i++ )
     486             :         {
     487      102048 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     488      102048 :             IF( GT_32( tmp, max_high ) )
     489             :             {
     490           2 :                 max_high = tmp;
     491           2 :                 move32();
     492           2 :                 dist_high = i;
     493           2 :                 move16();
     494             :             }
     495             :         }
     496             : 
     497             :         /* at least 9 bits headroom are needed for below multiplicitions */
     498         262 :         shift = 0;
     499         262 :         move16();
     500         262 :         headroom = 31;
     501         262 :         move16();
     502             : 
     503         262 :         tmp16 = norm_l( max_low );
     504         262 :         if ( max_low != 0 )
     505         262 :             headroom = s_min( headroom, tmp16 );
     506             : 
     507         262 :         tmp16 = norm_l( max_low2 );
     508         262 :         if ( max_low2 != 0 )
     509         262 :             headroom = s_min( headroom, tmp16 );
     510             : 
     511         262 :         tmp16 = norm_l( max_high );
     512         262 :         if ( max_high != 0 )
     513           1 :             headroom = s_min( headroom, tmp16 );
     514             : 
     515         262 :         if ( LT_16( headroom, 9 ) )
     516             :         {
     517           0 :             shift = sub( 9, headroom );
     518             :         }
     519         262 :         max_low = L_shr( max_low, shift );
     520         262 :         max_low2 = L_shr( max_low2, shift );
     521         262 :         max_high = L_shr( max_high, shift );
     522             : 
     523         262 :         test();
     524         262 :         test();
     525         262 :         IF( GT_32( imult3216( max_high, dist_high ), imult3216( L_shr( max_low, 2 ), dist_low ) ) && ( GT_32( max_low_pre, L_shr( max_high_pre, 4 ) ) ) && ( GT_32( max_high, L_shl( Mpy_32_16_r( max_low2, max_fac_m ), max_fac_s ) ) ) )
     526             :         {
     527             :             Word16 fac;
     528           1 :             fac = divide3232( max_low2, max_high );
     529           1 :             fac = shl( mult_r( fac, max_fac_m ), max_fac_s );
     530             : 
     531         385 :             FOR( i = 0; i < sub( L_spec, L_frame ); i++ )
     532             :             {
     533         384 :                 spectrum[L_frame + i] = Mpy_32_16_1( spectrum[L_frame + i], fac );
     534         384 :                 move32();
     535             :             }
     536             :         }
     537             :     }
     538             : 
     539             : 
     540         634 :     test();
     541         634 :     test();
     542         634 :     test();
     543         634 :     IF( st->tcxonly && hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !pfUseTns )
     544             :     {
     545           0 :         PsychAdaptLowFreqEmph_fx( spectrum, gainlpc, gainlpc_e );
     546             :     }
     547         634 : }
     548     1482636 : void ShapeSpectrum_ivas_fx(
     549             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
     550             :     Word16 A[],                /* input: quantized coefficients NxAz_q[M+1], Q = 14 - norm(A[0]) */
     551             :     Word16 gainlpc[],          /* output: MDCT gains for the previous frame Q(15-gainlpc_e)*/
     552             :     Word16 gainlpc_e[],        /* output: MDCT gains exponents */
     553             :     Word16 L_frame_glob,       /* input: frame length             */
     554             :     Word16 L_spec,
     555             :     Word32 spectrum[],  /* i/o: MDCT spectrum Q(31-spectrum_e) */
     556             :     Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */
     557             :     Word8 pfUseTns,     /* output: Flag indicating if TNS is used */
     558             :     Encoder_State *st,
     559             :     Word32 *scf /* Q16 */
     560             : )
     561             : {
     562             :     Word16 L_frame;
     563             :     Word16 Ap[M + 2];
     564             :     Word16 gamma1;
     565             :     Word16 gainlpc_noinv[FDNS_NPTS];
     566             :     Word16 gainlpc_noinv_e[FDNS_NPTS];
     567             :     Word32 sns_int_scf[FDNS_NPTS];
     568             :     Word16 i;
     569             :     Word16 q_spectrum;
     570     1482636 :     Word32 max_low_pre = 0, max_high_pre = 0;
     571     1482636 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     572     1482636 :     move32();
     573     1482636 :     move32();
     574     1482636 :     Word32 total_brate = st->total_brate;
     575     1482636 :     move32();
     576     1482636 :     if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
     577             :     {
     578     1244115 :         total_brate = st->element_brate;
     579     1244115 :         move32();
     580             :     }
     581             : 
     582             :     /*-----------------------------------------------------------*
     583             :      * Init                                                      *
     584             :      *-----------------------------------------------------------*/
     585             : 
     586             :     /* Init lengths */
     587     1482636 :     L_frame = L_frame_glob;
     588     1482636 :     move16();
     589     1482636 :     gamma1 = st->gamma;
     590     1482636 :     move16();
     591     1482636 :     if ( st->enableTcxLpc != 0 )
     592             :     {
     593       17444 :         gamma1 = 0x7FFF;
     594       17444 :         move16();
     595             :     }
     596             : 
     597             :     /* if past frame is ACELP */
     598     1482636 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) /* in MDCT, this is already done outside the function */
     599             :     {
     600      238521 :         IF( st->last_core == ACELP_CORE )
     601             :         {
     602        7931 :             L_frame = add( L_frame, hTcxCfg->tcx_offset );
     603        7931 :             L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
     604        7931 :             if ( hTcxCfg->lfacNext < 0 )
     605             :             {
     606        7931 :                 L_frame = sub( L_frame, hTcxCfg->lfacNext );
     607        7931 :                 move16();
     608             :             }
     609             :         }
     610             :     }
     611             : 
     612     1482636 :     test();
     613     1482636 :     tcxGetNoiseFillingTilt( A,
     614             :                             M,
     615             :                             L_frame,
     616     1482636 :                             ( GE_32( total_brate, ACELP_13k20 ) && st->rf_mode == 0 ),
     617             :                             &hTcxEnc->noiseTiltFactor );
     618             : 
     619             :     /* Calculate Spectrum Flatness Measure for the TCX Concealment */
     620     1482636 :     IF( st->enablePlcWaveadjust )
     621             :     {
     622           0 :         hTcxCfg->SFM2 = SFM_Cal_fx( spectrum, s_min( 200, L_frame ) );
     623           0 :         move32();
     624             :     }
     625             : 
     626     1482636 :     test();
     627     1482636 :     IF( LE_32( total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) )
     628             :     {
     629       31081 :         max_low_pre = 0;
     630       31081 :         move32();
     631     8129001 :         FOR( i = 0; i < L_frame; i++ )
     632             :         {
     633     8097920 :             Word32 tmp = L_abs( spectrum[i] );
     634     8097920 :             if ( GT_32( tmp, max_low_pre ) )
     635             :             {
     636      137411 :                 max_low_pre = tmp;
     637      137411 :                 move32();
     638             :             }
     639             :         }
     640             : 
     641       31081 :         max_high_pre = 0;
     642       31081 :         move32();
     643    12177961 :         FOR( i = 0; i < L_spec - L_frame; i++ )
     644             :         {
     645    12146880 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     646    12146880 :             if ( GT_32( tmp, max_high_pre ) )
     647             :             {
     648        2470 :                 max_high_pre = tmp;
     649        2470 :                 move32();
     650             :             }
     651             :         }
     652             :     }
     653             : 
     654     1482636 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
     655             :     {
     656             :         Word64 W_tmp;
     657             :         Word16 len;
     658     1244115 :         q_spectrum = sub( 31, *spectrum_e );
     659     1244115 :         sns_interpolate_scalefactors_fx( &sns_int_scf[0], scf, ENC );
     660     1244115 :         sns_shape_spectrum_fx( spectrum, &q_spectrum, st->hTcxCfg->psychParamsCurrent, &sns_int_scf[0], Q16, L_frame, &len ); // The output spectrum from sns_shape_spectrum_fx has Q = q_spectrum + 1
     661             : 
     662     1244115 :         test();
     663     1244115 :         test();
     664     1244115 :         IF( NE_16( len, L_spec ) && LT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) )
     665             :         {
     666         113 :             scale_sig32( spectrum + len, sub( L_spec, len ), sub( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) ); // Q31
     667             :         }
     668     1244002 :         ELSE IF( NE_16( len, L_spec ) && GT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) )
     669             :         {
     670      995561 :             scale_sig32( spectrum, len, sub( sub( 31, *spectrum_e ), add( q_spectrum, 1 ) ) ); // Q(30-specturm_e)
     671      995561 :             q_spectrum = sub( 31 - 1, *spectrum_e );
     672             :         }
     673             : 
     674   314798115 :         FOR( i = L_frame; i < L_spec; i++ )
     675             :         {
     676   313554000 :             W_tmp = W_mult0_32_32( spectrum[i], sns_int_scf[hTcxCfg->psychParamsCurrent->nBands - 1] );
     677   313554000 :             spectrum[i] = W_extract_h( W_shl( W_tmp, Q16 ) );
     678   313554000 :             move32();
     679             :         }
     680     1244115 :         *spectrum_e = sub( 31 - 1, q_spectrum ); // As the output spectrum from sns_shape_spectrum_fx has Q = q_spectrum + 1
     681     1244115 :         move16();
     682             :     }
     683             :     ELSE
     684             :     {
     685             :         /*-----------------------------------------------------------*
     686             :          * Pre-shaping in frequency domain using weighted LPC (Wz)   *
     687             :          *-----------------------------------------------------------*/
     688             : 
     689      238521 :         weight_a_fx( A, Ap, gamma1, M );
     690             : 
     691      238521 :         lpc2mdct( Ap, M, gainlpc_noinv, gainlpc_noinv_e, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
     692             : 
     693      238521 :         mdct_shaping( spectrum, L_frame, gainlpc_noinv, gainlpc_noinv_e );
     694    93147577 :         FOR( i = L_frame; i < L_spec; i++ )
     695             :         {
     696    92909056 :             spectrum[i] = L_shl( Mpy_32_16_1( spectrum[i], gainlpc_noinv[FDNS_NPTS - 1] ), gainlpc_noinv_e[FDNS_NPTS - 1] );
     697    92909056 :             move32();
     698             :         }
     699             :     }
     700             : 
     701             :     /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
     702     1482636 :     test();
     703     1482636 :     IF( LE_32( total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) )
     704             :     {
     705             :         Word16 sf_width;
     706             :         Word16 dist_low, dist_high;
     707             :         Word16 max_fac_s, max_fac_m;
     708             :         Word32 max_low, max_low1, max_low2, max_high;
     709             :         Word16 headroom, shift, tmp16;
     710             : 
     711             : 
     712       31081 :         max_fac_m = 24576;
     713       31081 :         move16();
     714             :         /* max_fac = 3 */
     715       31081 :         max_fac_s = 2;
     716       31081 :         move16();
     717       31081 :         if ( hTcxEnc->tcx_lpc_shaped_ari )
     718             :         {
     719             :             /* max_fac = 1.5 */
     720       13419 :             max_fac_s = 1;
     721       13419 :             move16();
     722             :         }
     723             : 
     724       31081 :         sf_width = shr( L_frame, 1 );
     725             : 
     726       31081 :         max_low2 = 0;
     727       31081 :         move32();
     728       31081 :         dist_low = 0;
     729       31081 :         move16();
     730     4080041 :         FOR( i = 0; i < sf_width; i++ )
     731             :         {
     732     4048960 :             Word32 tmp = L_abs( spectrum[L_frame - 1 - i] );
     733     4048960 :             IF( GT_32( tmp, max_low2 ) )
     734             :             {
     735      187618 :                 max_low2 = tmp;
     736      187618 :                 move32();
     737      187618 :                 dist_low = i;
     738      187618 :                 move16();
     739             :             }
     740             :         }
     741             : 
     742       31081 :         max_low1 = 0;
     743       31081 :         move32();
     744     4080041 :         FOR( i = 0; i < sub( L_frame, sf_width ); i++ )
     745             :         {
     746     4048960 :             Word32 tmp = L_abs( spectrum[L_frame - sf_width - 1 - i] );
     747     4048960 :             if ( GT_32( tmp, max_low1 ) )
     748             :             {
     749      285747 :                 max_low1 = tmp;
     750      285747 :                 move32();
     751             :             }
     752     4048960 :             if ( GT_32( tmp, max_low2 ) )
     753             :             {
     754      555300 :                 dist_low = add( sf_width, i );
     755             :             }
     756             :         }
     757             : 
     758       31081 :         max_low = L_max( max_low1, max_low2 );
     759             : 
     760       31081 :         max_high = 0;
     761       31081 :         move32();
     762       31081 :         dist_high = 0;
     763       31081 :         move16();
     764    12177961 :         FOR( i = 0; i < ( L_spec - L_frame ); i++ )
     765             :         {
     766    12146880 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     767    12146880 :             IF( GT_32( tmp, max_high ) )
     768             :             {
     769        2470 :                 max_high = tmp;
     770        2470 :                 move32();
     771        2470 :                 dist_high = i;
     772        2470 :                 move16();
     773             :             }
     774             :         }
     775             : 
     776             :         /* at least 9 bits headroom are needed for below multiplicitions */
     777       31081 :         shift = 0;
     778       31081 :         move16();
     779       31081 :         headroom = 31;
     780       31081 :         move16();
     781             : 
     782       31081 :         tmp16 = norm_l( max_low );
     783       31081 :         if ( max_low != 0 )
     784       31077 :             headroom = s_min( headroom, tmp16 );
     785             : 
     786       31081 :         tmp16 = norm_l( max_low2 );
     787       31081 :         if ( max_low2 != 0 )
     788       31077 :             headroom = s_min( headroom, tmp16 );
     789             : 
     790       31081 :         tmp16 = norm_l( max_high );
     791       31081 :         if ( max_high != 0 )
     792         841 :             headroom = s_min( headroom, tmp16 );
     793             : 
     794       31081 :         if ( LT_16( headroom, 9 ) )
     795             :         {
     796       30014 :             shift = sub( 9, headroom );
     797             :         }
     798       31081 :         max_low = L_shr( max_low, shift );
     799       31081 :         max_low2 = L_shr( max_low2, shift );
     800       31081 :         max_high = L_shr( max_high, shift );
     801             : 
     802       31081 :         test();
     803       31081 :         test();
     804       31081 :         IF( GT_32( imult3216( max_high, dist_high ), imult3216( L_shr( max_low, 2 ), dist_low ) ) && ( GT_32( max_low_pre, L_shr( max_high_pre, 4 ) ) ) && ( GT_32( max_high, L_shl( Mpy_32_16_r( max_low2, max_fac_m ), max_fac_s ) ) ) )
     805             :         {
     806             :             Word16 fac;
     807         605 :             fac = divide3232( max_low2, max_high );
     808         605 :             IF( GE_16( norm_s( fac ), max_fac_s ) )
     809             :             {
     810         537 :                 fac = shl( mult_r( fac, max_fac_m ), max_fac_s );
     811      211641 :                 FOR( i = 0; i < ( L_spec - L_frame ); i++ )
     812             :                 {
     813      211104 :                     spectrum[L_frame + i] = Mpy_32_16_1( spectrum[L_frame + i], fac );
     814      211104 :                     move32();
     815             :                 }
     816             :             }
     817             :             ELSE
     818             :             {
     819          68 :                 fac = mult_r( fac, max_fac_m );
     820       26852 :                 FOR( i = 0; i < ( L_spec - L_frame ); i++ )
     821             :                 {
     822       26784 :                     spectrum[L_frame + i] = L_shl( Mpy_32_16_1( spectrum[L_frame + i], fac ), max_fac_s );
     823       26784 :                     move32();
     824             :                 }
     825             :             }
     826             :         }
     827             :     }
     828             : 
     829             : 
     830     1482636 :     test();
     831     1482636 :     test();
     832     1482636 :     test();
     833     1482636 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) && st->tcxonly && hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !pfUseTns )
     834             :     {
     835        3730 :         PsychAdaptLowFreqEmph_fx( spectrum, gainlpc, gainlpc_e );
     836             :     }
     837     1482636 : }
     838             : 
     839             : /*-------------------------------------------------------------------*
     840             :  * GetTransWidth()
     841             :  *
     842             :  *
     843             :  *-------------------------------------------------------------------*/
     844             : 
     845     1079624 : static Word16 GetTransWidth_ivas_fx(
     846             :     const Word16 tcxonly,
     847             :     const Word16 tcx10,
     848             :     const Word16 tcxltp_gain, // Q15
     849             :     const Word16 hm_active )
     850             : {
     851     1079624 :     Word16 noiseTransWidth = MIN_NOISE_FILLING_HOLE;
     852     1079624 :     move16();
     853             : 
     854     1079624 :     IF( tcxonly )
     855             :     {
     856      820945 :         IF( hm_active )
     857             :         {
     858        8954 :             noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( tcxltp_gain, 10240 /*0.3125f Q15*/ ) );
     859             :         }
     860             :         ELSE
     861             :         {
     862      811991 :             noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( tcxltp_gain, 0 ) );
     863             :         }
     864             : 
     865      820945 :         if ( tcx10 )
     866             :         {
     867       35349 :             noiseTransWidth = 3; /* minimum transition for noise filling in TCX-10 */
     868       35349 :             move16();
     869             :         }
     870             :     }
     871             : 
     872     1079624 :     return noiseTransWidth;
     873             : }
     874             : 
     875             : /*-----------------------------------------------------------*
     876             :  * EstimateTCXNoiseLevel()
     877             :  *
     878             :  * Estimate and quantize noise factor                        *
     879             :  *-----------------------------------------------------------*/
     880             : 
     881      238521 : static void EstimateTCXNoiseLevel_ivas_fx(
     882             :     Encoder_State *st,               /* i  : encoder state handle                            */
     883             :     Word32 x_orig[],                 /* i  : shaped MDCT spectrum         Q(31-x_orig_e)     */
     884             :     Word16 x_orig_e,                 /* i  : shaped MDCT spectrum exponent                   */
     885             :     Word32 spectrum[],               /* i/o: quantized MDCT spectrum                         */
     886             :     const Word16 gain_tcx,           /* i  : global gain              Q(15-gain_tcx_e)       */
     887             :     const Word16 gain_tcx_e,         /* i  : global gain exponent                            */
     888             :     const Word16 L_frame,            /* i  : frame length                                    */
     889             :     const Word16 noiseFillingBorder, /* i  : noise filling border                            */
     890             :     const Word16 hm_active,          /* i  : flag indicating if the harmonic model is active */
     891             :     Word16 *fac_ns,                  /* o  : noise filling level, fac_ns_q                       */
     892             :     Word16 *fac_ns_q                 /* o  : quantized noise filling level, Q0               */
     893             : )
     894             : {
     895             :     Word16 maxNfCalcBw, iStart, noiseTransWidth;
     896      238521 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     897             : 
     898      238521 :     maxNfCalcBw = s_min( noiseFillingBorder, round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame ), 1 ) ) );
     899             : 
     900      238521 :     IF( GE_32( st->total_brate, HQ_96k ) )
     901             :     {
     902       18139 :         *fac_ns = 0;
     903       18139 :         *fac_ns_q = 0;
     904       18139 :         move16();
     905       18139 :         move16();
     906             :     }
     907             :     ELSE
     908             :     {
     909             :         Word16 minLevel;
     910      220382 :         minLevel = 1;
     911      220382 :         move16();
     912      220382 :         test();
     913      220382 :         if ( hTcxEnc->tcx_lpc_shaped_ari && GT_16( st->element_mode, IVAS_SCE ) )
     914             :         {
     915        4740 :             minLevel = 0;
     916        4740 :             move16();
     917             :         }
     918             : 
     919             :         /* noise filling start bin */
     920      220382 :         iStart = shr( L_frame, 3 );
     921      220382 :         test();
     922      220382 :         IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
     923             :         {
     924      187209 :             iStart = idiv1616U( L_frame, 6 );
     925             :         }
     926             : 
     927      220382 :         noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame, shr( st->L_frame, 1 ) ), st->hTcxEnc->tcxltp_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) );
     928             : 
     929      220382 :         tcx_noise_factor_ivas_fx( x_orig, x_orig_e, spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame, gain_tcx, gain_tcx_e, hTcxEnc->noiseTiltFactor, fac_ns, fac_ns_q, st->element_mode );
     930             : 
     931             :         /* hysteresis for very tonal passages (more stationary noise filling level) */
     932      220382 :         IF( EQ_16( *fac_ns_q, minLevel ) )
     933             :         {
     934       11403 :             hTcxEnc->noiseLevelMemory_cnt = s_min( INT16_MAX, add( 1, abs_s( hTcxEnc->noiseLevelMemory_cnt ) ) ); /* update counter */
     935       11403 :             move16();
     936             :         }
     937             :         ELSE
     938             :         {
     939      208979 :             test();
     940      208979 :             IF( EQ_16( *fac_ns_q, add( minLevel, 1 ) ) && GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) )
     941             :             {
     942         728 :                 *fac_ns_q = minLevel; /* reduce noise filling level by one step */
     943         728 :                 *fac_ns = 0;
     944         728 :                 move16();
     945         728 :                 move16();
     946         728 :                 IF( minLevel != 0 )
     947             :                 {
     948         728 :                     *fac_ns = shr( 0x6000, NBITS_NOISE_FILL_LEVEL );
     949         728 :                     move16();
     950             :                 }
     951             :                 /* signal that noise level is changed by inverting sign of level memory */
     952         728 :                 IF( hTcxEnc->noiseLevelMemory_cnt < 0 )
     953             :                 {
     954         235 :                     hTcxEnc->noiseLevelMemory_cnt = 5;
     955         235 :                     move16();
     956             :                 }
     957             :                 ELSE
     958             :                 {
     959         493 :                     hTcxEnc->noiseLevelMemory_cnt = negate( add( 1, hTcxEnc->noiseLevelMemory_cnt ) );
     960         493 :                     move16();
     961             :                 }
     962             :             }
     963             :             ELSE
     964             :             {
     965      208251 :                 hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
     966      208251 :                 move16();
     967             :             }
     968             :         }
     969             :     } /* bitrate */
     970             : 
     971      238521 :     return;
     972             : }
     973             : 
     974             : 
     975             : /*-------------------------------------------------------------------*
     976             :  * QuantizeSpectrum()
     977             :  *
     978             :  *
     979             :  *-------------------------------------------------------------------*/
     980             : 
     981      238521 : void QuantizeSpectrum_ivas_fx(
     982             :     Encoder_State *st,          /* i/o: encoder state structure                                      */
     983             :     const Word16 A_fx[],        /* i  : quantized coefficients NxAz_q[M+1], Q = 14 - norm_s(A_fx[0]) */
     984             :     const Word16 Aqind[],       /* i  : frame-independent quantized coefficients (M+1)               */
     985             :     Word16 gainlpc_fx[],        /* i  : MDCT gains of the previous frame    Q(15-gainlpc_e)          */
     986             :     Word16 gainlpc_e[],         /* i  : exponents of MDCT gains of the previous frame                */
     987             :     Word16 synth[],             /* o  : synthesis buffer, Q0                                         */
     988             :     const Word16 nb_bits,       /* i  : bit budget                                                   */
     989             :     const Word16 tnsSize,       /* i  : number of tns parameters put into prm                        */
     990             :     Word16 prm[],               /* o  : tcx parameters                                               */
     991             :     const Word16 frame_cnt,     /* i  : frame counter in the super_frame                             */
     992             :     CONTEXT_HM_CONFIG *hm_cfg,  /* i  : HM configuration                                             */
     993             :     const Word16 vad_hover_flag /* i  : VAD hangover flag                                            */
     994             : )
     995             : {
     996             :     Word16 L_frameTCX;                                                          /* full frame length */
     997             :     Word16 L_frame;                                                             /* frame length */
     998             :     Word16 L_spec;                                                              /* length of the coded spectrum */
     999             :     Word16 tcx_offset;                                                          /* folding point offset relative to the end of the previous frame */
    1000             :     Word16 noiseFillingBorder;                                                  /* noise filling border */
    1001             :     Word32 quantized_spectrum_fx[N_MAX];                                        /* quantized MDCT spectrum */
    1002             :     Word16 quantized_spectrum_e;                                                /* quantized MDCT spectrum */
    1003             :     Word16 lf_deemph_fact_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* low frequency deemphasis factors */
    1004             :     Word16 hm_active;                                                           /* flag indicating if the harmonic model is active */
    1005             :     Word16 fac_ns_fx;                                                           /* noise filling level, Q15 */
    1006             :     Word16 nf_seed;                                                             /* noise filling random seed */
    1007             :     Word32 ener_fx;                                                             /* energy of the quantized spectrum */
    1008             :     Word16 ener_e;                                                              /* energy of the quantized spectrum */
    1009             :     Word16 gain_tcx_fx;                                                         /* global gain */
    1010             :     Word16 gain_tcx_e;                                                          /* global gain */
    1011             : 
    1012      238521 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1013             : 
    1014      238521 :     set32_fx( quantized_spectrum_fx, 0, N_MAX );
    1015             : 
    1016             :     /*-----------------------------------------------------------*
    1017             :      * Quantize the MDCT spectrum                                *
    1018             :      *-----------------------------------------------------------*/
    1019             : 
    1020      238521 :     QuantizeTCXSpectrum_fx( st, frame_cnt, hTcxEnc->spectrum_fx[frame_cnt], hTcxEnc->spectrum_e[frame_cnt], gainlpc_fx, gainlpc_e, Aqind, tnsSize, nb_bits, vad_hover_flag,
    1021             :                             &L_frameTCX, &L_frame, &L_spec, &tcx_offset, &noiseFillingBorder, quantized_spectrum_fx, &quantized_spectrum_e, hm_cfg, &hm_active, lf_deemph_fact_fx, &nf_seed, &ener_fx, &ener_e, &gain_tcx_fx, &gain_tcx_e, prm );
    1022      238521 :     if ( hTcxEnc->spectrum_e[frame_cnt] < 0 )
    1023             :     {
    1024             :         /*buffer is already scaled inside QuantizeTCXSpectrum_fx*/
    1025           0 :         hTcxEnc->spectrum_e[frame_cnt] = 0;
    1026           0 :         move16();
    1027             :     }
    1028             : 
    1029      238521 :     Word16 s1 = sub( getScaleFactor32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame ), 6 );
    1030      238521 :     Word16 s2 = getScaleFactor32( quantized_spectrum_fx, s_max( L_frame, L_spec ) );
    1031      238521 :     Word16 max_e = s_max( sub( hTcxEnc->spectrum_e[frame_cnt], s1 ), sub( quantized_spectrum_e, s2 ) );
    1032             : 
    1033      238521 :     scale_sig32( quantized_spectrum_fx, s_max( L_frame, L_spec ), sub( quantized_spectrum_e, max_e ) );        // max_e
    1034      238521 :     scale_sig32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame, sub( hTcxEnc->spectrum_e[frame_cnt], max_e ) ); // max_e
    1035      238521 :     hTcxEnc->spectrum_e[frame_cnt] = max_e;
    1036      238521 :     move16();
    1037             : 
    1038             :     /*-----------------------------------------------------------*
    1039             :      * Estimate and quantize noise factor                        *
    1040             :      *-----------------------------------------------------------*/
    1041             : 
    1042      238521 :     EstimateTCXNoiseLevel_ivas_fx( st, hTcxEnc->spectrum_fx[frame_cnt], hTcxEnc->spectrum_e[frame_cnt], quantized_spectrum_fx, gain_tcx_fx, gain_tcx_e, L_frame, noiseFillingBorder, hm_active, &fac_ns_fx, &prm[1] );
    1043             : 
    1044             :     /*-----------------------------------------------------------*
    1045             :      * Internal decoder                                          *
    1046             :      *-----------------------------------------------------------*/
    1047             : 
    1048      238521 :     InternalTCXDecoder_fx( st, frame_cnt, L_frameTCX, L_frame, L_spec, tcx_offset, noiseFillingBorder, quantized_spectrum_fx, ener_fx, ener_e, lf_deemph_fact_fx, fac_ns_fx, nf_seed, A_fx, gainlpc_fx, gainlpc_e, hm_active, gain_tcx_fx, &gain_tcx_e, hTcxEnc->spectrum_fx[frame_cnt], &hTcxEnc->spectrum_e[frame_cnt], synth, &prm[0] );
    1049             : 
    1050             :     /* Update L_frame_past */
    1051      238521 :     st->L_frame_past = L_frame;
    1052      238521 :     move16();
    1053             : 
    1054             :     /* Update overlap */
    1055      238521 :     test();
    1056      238521 :     test();
    1057      238521 :     test();
    1058      238521 :     if ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) || EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
    1059             :     {
    1060        8907 :         st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
    1061        8907 :         move16();
    1062             :     }
    1063             : 
    1064             : 
    1065      238521 :     return;
    1066             : }
    1067             : 
    1068      356091 : void EstimateStereoTCXNoiseLevel_fx(
    1069             :     Encoder_State **sts,                      /* i  : state handle                                    */
    1070             :     Word32 *q_spectrum[CPE_CHANNELS][NB_DIV], /* i  : quantized MDCT spectrum    Qx                   */
    1071             :     Word16 gain_tcx[][NB_DIV],                /* i  : global gain                Q(15-gain_tcx_e)     */
    1072             :     Word16 gain_tcx_e[][NB_DIV],              /* i  : global gain exponent                            */
    1073             :     Word16 L_frame[][NB_DIV],                 /* i  : frame length                                    */
    1074             :     Word16 noiseFillingBorder[][NB_DIV],      /* i  : noise filling border                            */
    1075             :     Word16 hm_active[][NB_DIV],               /* i  : flag indicating if the harmonic model is active */
    1076             :     const Word16 ignore_chan[],               /* i  : flag indicating whether the channel should be ignored */
    1077             :     Word16 fac_ns[][NB_DIV],                  /* o  : noise filling level                        Q15  */
    1078             :     Word16 param_core[][NB_DIV * NPRM_DIV],   /* o  : quantized noise filling level                   */
    1079             :     const Word16 MCT_flag                     /* i  : hMCT handle allocated (1) or not (0)            */
    1080             : )
    1081             : {
    1082             :     Word16 ch, n, i;
    1083             :     Word16 nSubframes, maxNfCalcBw, iStart, noiseTransWidth;
    1084             :     Word16 smooth_gain;
    1085             :     Word32 combined_q_spectrum[N_MAX];
    1086             :     Word16 *fac_ns_q;
    1087             :     Word32 total_brate;
    1088             : 
    1089      356091 :     set32_fx( combined_q_spectrum, 0, N_MAX );
    1090             : 
    1091     1068273 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    1092             :     {
    1093      712182 :         Encoder_State *st = sts[ch];
    1094      712182 :         TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1095             : 
    1096      712182 :         IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
    1097             :         {
    1098      697356 :             nSubframes = 1;
    1099      697356 :             move16();
    1100             :         }
    1101             :         ELSE
    1102             :         {
    1103       14826 :             nSubframes = NB_DIV;
    1104       14826 :             move16();
    1105             :         }
    1106             : 
    1107      712182 :         IF( ignore_chan[ch] )
    1108             :         {
    1109       68223 :             CONTINUE;
    1110             :         }
    1111             : 
    1112      643959 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag )
    1113             :         {
    1114      167566 :             total_brate = st->element_brate;
    1115      167566 :             move32();
    1116             :         }
    1117             :         ELSE
    1118             :         {
    1119      476393 :             total_brate = st->total_brate;
    1120      476393 :             move32();
    1121             :         }
    1122             : 
    1123     1302738 :         FOR( n = 0; n < nSubframes; n++ )
    1124             :         {
    1125      658779 :             fac_ns_q = param_core[ch] + add( i_mult( n, NPRM_DIV ), 1 );
    1126             : 
    1127      658779 :             maxNfCalcBw = s_min( noiseFillingBorder[ch][n], round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame[ch][n] ), 1 ) ) );
    1128             : 
    1129      658779 :             test();
    1130      658779 :             test();
    1131      658779 :             test();
    1132      658779 :             IF( ( GE_32( total_brate, HQ_96k ) && ( LE_16( st->element_mode, IVAS_SCE ) || LT_16( st->bwidth, SWB ) ) ) || GT_32( total_brate, IVAS_192k ) )
    1133             :             {
    1134       19447 :                 fac_ns[ch][n] = 0;
    1135       19447 :                 move16();
    1136       19447 :                 *fac_ns_q = 0;
    1137       19447 :                 move16();
    1138             :             }
    1139             :             ELSE
    1140             :             {
    1141      639332 :                 test();
    1142      639332 :                 IF( GE_32( total_brate, ACELP_13k20 ) && !st->rf_mode )
    1143             :                 {
    1144      616823 :                     iStart = idiv1616( L_frame[ch][n], 6 );
    1145             :                 }
    1146             :                 ELSE
    1147             :                 {
    1148       22509 :                     iStart = shr( L_frame[ch][n], 3 );
    1149             :                 }
    1150             : 
    1151      639332 :                 IF( n == 0 )
    1152             :                 {
    1153      624961 :                     Copy( hTcxEnc->ltpGainMemory_fx, &hTcxEnc->ltpGainMemory_fx[1], N_LTP_GAIN_MEMS - 1 );
    1154      624961 :                     hTcxEnc->ltpGainMemory_fx[0] = st->hTcxEnc->tcxltp_gain;
    1155      624961 :                     move16();
    1156             :                 }
    1157             : 
    1158      639332 :                 Word32 temp = L_mult0( hTcxEnc->ltpGainMemory_fx[0], nf_tw_smoothing_coeffs_fx[0] );
    1159             : 
    1160     2557328 :                 FOR( i = 1; i < N_LTP_GAIN_MEMS; i++ )
    1161             :                 {
    1162     1917996 :                     temp = L_mac0( temp, hTcxEnc->ltpGainMemory_fx[i], nf_tw_smoothing_coeffs_fx[i] );
    1163             :                 }
    1164      639332 :                 smooth_gain = round_fx( L_shl( temp, 1 ) );
    1165      639332 :                 noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame[ch][n], shr( st->L_frame, 1 ) ), smooth_gain, ( st->hTcxCfg->ctx_hm && NE_16( st->last_core, ACELP_CORE ) && hm_active[ch][n] ) );
    1166             : 
    1167      639332 :                 Copy32( q_spectrum[ch][n], combined_q_spectrum, L_frame[ch][n] );
    1168             : 
    1169             :                 /* Scaling down 1-bit to resolve crashes during accumulation in tcx_noise_factor_ivas_fx() */
    1170             :                 Word32 L_tmp, L_tmp1;
    1171      639332 :                 maximum_abs_32_fx( hTcxEnc->spectrum_fx[n], L_frame[ch][n], &L_tmp );
    1172      639332 :                 maximum_abs_32_fx( combined_q_spectrum, L_frame[ch][n], &L_tmp1 );
    1173      639332 :                 test();
    1174      639332 :                 IF( L_tmp != 0 || L_tmp1 != 0 )
    1175             :                 {
    1176      639143 :                     scale_sig32( hTcxEnc->spectrum_fx[n], L_frame[ch][n], -Q1 ); // Q(31-(spectrum_e+1)
    1177      639143 :                     scale_sig32( combined_q_spectrum, L_frame[ch][n], -Q1 );     // Q(31-(spectrum_e+1)
    1178      639143 :                     hTcxEnc->spectrum_e[n] = add( hTcxEnc->spectrum_e[n], Q1 );
    1179      639143 :                     move16();
    1180             :                 }
    1181      639332 :                 tcx_noise_factor_ivas_fx( hTcxEnc->spectrum_fx[n], hTcxEnc->spectrum_e[n], combined_q_spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame[ch][n], gain_tcx[ch][n], gain_tcx_e[ch][n], hTcxEnc->noiseTiltFactor, &fac_ns[ch][n], fac_ns_q, st->element_mode );
    1182             : 
    1183             :                 /* hysteresis for very tonal passages (more stationary noise filling level) */
    1184      639332 :                 IF( EQ_16( *fac_ns_q, 1 ) )
    1185             :                 {
    1186       74585 :                     hTcxEnc->noiseLevelMemory_cnt = s_min( INT16_MAX, 1 + abs_s( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
    1187       74585 :                     move16();
    1188             :                 }
    1189             :                 ELSE
    1190             :                 {
    1191      564747 :                     test();
    1192      564747 :                     IF( EQ_16( *fac_ns_q, 2 ) && GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) )
    1193             :                     {
    1194        5898 :                         *fac_ns_q = 1;        /* reduce noise filling level by one step */
    1195        5898 :                         fac_ns[ch][n] = 3072; /* 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL ) in Q15*/
    1196        5898 :                         move16();
    1197        5898 :                         move16();
    1198             :                         /* signal that noise level is changed by inverting sign of level memory */
    1199        5898 :                         IF( ( hTcxEnc->noiseLevelMemory_cnt < 0 ) )
    1200             :                         {
    1201        1972 :                             hTcxEnc->noiseLevelMemory_cnt = 5;
    1202        1972 :                             move16();
    1203             :                         }
    1204             :                         ELSE
    1205             :                         {
    1206        3926 :                             hTcxEnc->noiseLevelMemory_cnt = sub( -1, hTcxEnc->noiseLevelMemory_cnt );
    1207        3926 :                             move16();
    1208             :                         }
    1209             :                     }
    1210             :                     ELSE
    1211             :                     {
    1212      558849 :                         hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
    1213      558849 :                         move16();
    1214             :                     }
    1215             :                 }
    1216             :             } /* bitrate */
    1217             :         }
    1218             :     }
    1219             : 
    1220      356091 :     return;
    1221             : }
    1222             : 
    1223         634 : void QuantizeSpectrum_fx(
    1224             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    1225             :     Word16 A[],                /* input: quantized coefficients NxAz_q[M+1] */
    1226             :     Word16 Aqind[],            /* input: frame-independent quantized coefficients (M+1) */
    1227             :     Word16 gainlpc[],          /* input: MDCT gains of the previous frame  Q(15-gainlpc_e)*/
    1228             :     Word16 gainlpc_e[],        /* input: MDCT gains exponents */
    1229             :     Word16 synth[],
    1230             :     Word16 L_frame_glob, /* input: frame length             */
    1231             :     Word16 L_frameTCX_glob,
    1232             :     Word16 L_spec,
    1233             :     Word16 nb_bits,     /*input: bit budget*/
    1234             :     Word8 tcxonly,      /*input: only TCX flag*/
    1235             :     Word32 spectrum[],  /* i/o: MDCT spectrum, input is shaped MDCT spectrum Q(31-spectrum_e) */
    1236             :     Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */
    1237             :     STnsData *pTnsData, /* input: Tns data */
    1238             :     Word8 fUseTns,      /* input: Flag indicating if TNS is used */
    1239             :     Word16 tnsSize,     /* input: number of tns parameters put into prm */
    1240             :     Word16 prm[],       /* output: tcx parameters          */
    1241             :     Word16 frame_cnt,   /* input: frame counter in the super_frame */
    1242             :     Encoder_State *st,
    1243             :     CONTEXT_HM_CONFIG *hm_cfg )
    1244             : {
    1245             :     Word16 i, L_frame, tcx_offset;
    1246             :     Word16 stop;
    1247             :     Word16 tmp1, tmp2, tmp3, tmp4, s;
    1248             :     Word32 tmp32;
    1249             :     Word8 tmp8;
    1250             :     Word16 *tmpP16;
    1251             :     Word16 L_frameTCX;
    1252             :     Word16 fac_ns;
    1253             :     Word16 nf_seed;
    1254             :     Word32 ener;
    1255             :     Word16 ener_e;
    1256             :     Word16 gain_tcx, gain_tcx_e;
    1257             :     Word16 sqBits;
    1258             :     Word16 overlap;
    1259             :     Word16 noiseFillingSize;
    1260             :     Word16 noiseTransWidth;
    1261             :     Word32 *OriginalSpectrum;
    1262             :     Word16 OriginalSpectrum_e;
    1263             :     Word16 ctxHmBits;
    1264             :     Word16 resQBits;
    1265             :     Word16 *signs;
    1266             :     Word16 signaling_bits;
    1267             :     Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_lastnz, *prm_target;
    1268             :     Word16 Aq_old[M + 1];
    1269             :     Word32 SFM;
    1270             :     Word32 K, K2;
    1271             :     Word16 aldo; /* ALDO flag in current frame*/
    1272             :     Word16 nz;   /* non-zero length in ALDO window*/
    1273             :     CONTEXT_HM_CONFIG *phm_cfg;
    1274         634 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1275             : 
    1276             :     /* Stack memory is split between encoder and internal decoder to reduce max
    1277             :        stack memory usage. */
    1278             :     {
    1279             :         Word16 sqTargetBits;
    1280             :         Word16 gain_tcx_opt, gain_tcx_opt_e;
    1281             :         Word16 sqGain, sqGain_e;
    1282             :         Word16 sqBits_noStop;
    1283             :         Word16 nEncoded;
    1284             :         Word16 maxNfCalcBw;
    1285             :         Word16 PeriodicityIndex;
    1286             :         Word16 NumIndexBits;
    1287             :         Word16 nEncodedCtxHm, stopCtxHm, sqBitsCtxHm, Selector;
    1288             :         Word16 lastnz, lastnzCtxHm;
    1289             :         Word16 RelativeScore;
    1290             :         Word32 x_orig[N_MAX];
    1291             :         Word16 x_orig_e;
    1292             :         Word16 resQTargetBits;
    1293             :         Word16 xn_buf16[L_FRAME_PLUS];
    1294             :         Word16 *sqQ;
    1295             :         Word16 LtpPitchLag;
    1296             : 
    1297             : 
    1298         634 :         sqGain = 0x4000;
    1299         634 :         move16();
    1300         634 :         sqGain_e = 1;
    1301         634 :         move16();
    1302         634 :         noiseTransWidth = MIN_NOISE_FILLING_HOLE;
    1303         634 :         move16();
    1304         634 :         resQTargetBits = 0;
    1305         634 :         move16();
    1306             : 
    1307             :         /*-----------------------------------------------------------*
    1308             :          * Init                                                      *
    1309             :          *-----------------------------------------------------------*/
    1310             : 
    1311             :         /* Init lengths */
    1312         634 :         L_frame = L_frame_glob;
    1313         634 :         move16();
    1314         634 :         L_frameTCX = L_frameTCX_glob;
    1315         634 :         move16();
    1316         634 :         overlap = hTcxCfg->tcx_mdct_window_length;
    1317         634 :         move16();
    1318         634 :         aldo = 0;
    1319         634 :         move16();
    1320         634 :         nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS );
    1321         634 :         move16();
    1322             :         /* Modified the overlap to the delay in case of short blocks*/
    1323         634 :         tcx_offset = hTcxCfg->tcx_offset;
    1324         634 :         move16();
    1325             : 
    1326         634 :         OriginalSpectrum = NULL;
    1327         634 :         signs = NULL; /* silence warning */
    1328         634 :         NumIndexBits = 0;
    1329         634 :         move16();
    1330         634 :         sqBits = 0;
    1331         634 :         move16();
    1332         634 :         ctxHmBits = 0;
    1333         634 :         move16();
    1334         634 :         resQBits = 0;
    1335         634 :         move16();
    1336         634 :         prm_ltp = &prm[1 + NOISE_FILL_RANGES];
    1337         634 :         move16();
    1338         634 :         prm_tns = prm_ltp + LTPSIZE;
    1339         634 :         move16();
    1340         634 :         prm_hm = prm_tns + tnsSize;
    1341         634 :         move16();
    1342         634 :         prm_lastnz = prm_hm + 2;
    1343         634 :         move16();
    1344         634 :         sqQ = prm_hm + NPRM_CTX_HM;
    1345         634 :         move16();
    1346             : 
    1347             :         /* if past frame is ACELP */
    1348             : 
    1349         634 :         IF( st->last_core == ACELP_CORE )
    1350             :         {
    1351          38 :             hTcxCfg->last_aldo = 0;
    1352          38 :             move16();
    1353             : 
    1354          38 :             L_frame = add( L_frame, tcx_offset );
    1355          38 :             L_frameTCX = add( L_frameTCX, hTcxCfg->tcx_offsetFB );
    1356          38 :             L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
    1357          38 :             tcx_offset = 0;
    1358          38 :             move16();
    1359          38 :             IF( hTcxCfg->lfacNext < 0 )
    1360             :             {
    1361          38 :                 L_frame = sub( L_frame, hTcxCfg->lfacNext );
    1362          38 :                 L_frameTCX = sub( L_frameTCX, hTcxCfg->lfacNextFB );
    1363          38 :                 tcx_offset = hTcxCfg->lfacNext;
    1364          38 :                 move16();
    1365             :             }
    1366          38 :             hTcxEnc->noiseLevelMemory_cnt = 0;
    1367          38 :             move16();
    1368             :         }
    1369             : 
    1370             : 
    1371         634 :         E_LPC_f_lsp_a_conversion( st->lsp_old_fx, Aq_old, M );
    1372             : 
    1373             :         /* target bitrate for SQ */
    1374         634 :         sqTargetBits = sub( nb_bits, 7 + NBITS_NOISE_FILL_LEVEL );
    1375             : 
    1376             :         /*Unquantized spectrum here*/
    1377         634 :         IF( st->enablePlcWaveadjust )
    1378             :         {
    1379             : 
    1380             : 
    1381           0 :             SFM = SFM_Cal_fx( spectrum, s_min( 200, L_frame_glob ) );
    1382           0 :             test();
    1383           0 :             IF( LE_16( L_frame_glob, 256 ) )
    1384             :             {
    1385           0 :                 K = 0x33333333;
    1386           0 :                 move32();
    1387           0 :                 K2 = 0xCCCCCCD;
    1388           0 :                 move32();
    1389             :             }
    1390           0 :             ELSE IF( EQ_16( L_frame_glob, 320 ) || EQ_16( L_frame_glob, 512 ) )
    1391             :             {
    1392           0 :                 K = 0x33333333;
    1393           0 :                 move32();
    1394           0 :                 K2 = 0xCCCCCCD;
    1395           0 :                 move32();
    1396             :             }
    1397             :             ELSE /*FrameSize_Core == 640*/
    1398             :             {
    1399           0 :                 K = 0x2CCCCCCD;
    1400           0 :                 move32();
    1401           0 :                 K2 = 0x51EB852;
    1402           0 :                 move32();
    1403             :             }
    1404             : 
    1405             : 
    1406           0 :             IF( LT_32( SFM, K ) )
    1407             :             {
    1408           0 :                 st->Tonal_SideInfo = 1;
    1409           0 :                 move16();
    1410             :             }
    1411             :             ELSE
    1412             :             {
    1413           0 :                 st->Tonal_SideInfo = 0;
    1414           0 :                 move16();
    1415             :             }
    1416             : 
    1417           0 :             if ( LT_32( hTcxCfg->SFM2, K2 ) )
    1418             :             {
    1419           0 :                 st->Tonal_SideInfo = 1;
    1420           0 :                 move16();
    1421             :             }
    1422             :         }
    1423             : 
    1424             :         /* Save pre-shaped spectrum*/
    1425         634 :         Copy32( spectrum, x_orig, L_spec );
    1426         634 :         x_orig_e = *spectrum_e;
    1427         634 :         move16();
    1428             : 
    1429             :         /*-----------------------------------------------------------*
    1430             :          * Bandwidth Limitation                                      *
    1431             :          *-----------------------------------------------------------*/
    1432             : 
    1433         634 :         noiseFillingSize = L_spec;
    1434         634 :         move16();
    1435         634 :         IF( st->igf != 0 )
    1436             :         {
    1437         634 :             noiseFillingSize = st->hIGFEnc->infoStartLine;
    1438         634 :             move16();
    1439             :         }
    1440             :         ELSE
    1441             :         {
    1442           0 :             st->hIGFEnc->infoStopLine = noiseFillingSize;
    1443           0 :             move16();
    1444             :         }
    1445             : 
    1446      141172 :         FOR( i = st->hIGFEnc->infoStopLine; i < L_frameTCX; i++ )
    1447             :         {
    1448      140538 :             spectrum[i] = L_deposit_l( 0 );
    1449      140538 :             move32();
    1450             :         }
    1451             : 
    1452             :         /*-----------------------------------------------------------*
    1453             :          * Quantization                                              *
    1454             :          *-----------------------------------------------------------*/
    1455             : 
    1456         634 :         IF( hTcxEnc->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
    1457             :         {
    1458             : 
    1459             :             /* Fast estimation of the scalar quantizer step size */
    1460         634 :             test();
    1461         634 :             IF( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) )
    1462             :             {
    1463         596 :                 LtpPitchLag = -1;
    1464         596 :                 move16();
    1465             : 
    1466         596 :                 test();
    1467         596 :                 IF( ( tcxonly == 0 ) && ( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) ) )
    1468             :                 {
    1469         432 :                     tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
    1470         432 :                     tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
    1471         432 :                     LtpPitchLag = div_l( tmp32, tmp1 );
    1472             :                 }
    1473             : 
    1474         596 :                 ctxHmBits = add( ctxHmBits, 1 );       /* ContextHM flag */
    1475         596 :                 sqTargetBits = sub( sqTargetBits, 1 ); /* ContextHM flag */
    1476             : 
    1477         596 :                 OriginalSpectrum = spectrum;
    1478         596 :                 OriginalSpectrum_e = *spectrum_e;
    1479         596 :                 move16();
    1480             : 
    1481         596 :                 tmp1 = -1;
    1482         596 :                 move16();
    1483         596 :                 if ( hTcxEnc->tcxltp != 0 )
    1484             :                 {
    1485         596 :                     tmp1 = hTcxEnc->tcxltp_gain;
    1486         596 :                     move16();
    1487             :                 }
    1488         596 :                 PeriodicityIndex = SearchPeriodicityIndex_fx(
    1489             :                     OriginalSpectrum,
    1490             :                     NULL,
    1491             :                     L_spec,
    1492             :                     sqTargetBits,
    1493             :                     LtpPitchLag,
    1494             :                     tmp1,
    1495             :                     &RelativeScore );
    1496             : 
    1497         596 :                 ConfigureContextHm(
    1498             :                     L_spec,
    1499             :                     sqTargetBits,
    1500             :                     PeriodicityIndex,
    1501             :                     LtpPitchLag,
    1502             :                     hm_cfg );
    1503             : 
    1504         596 :                 tmp1 = 1;
    1505         596 :                 move16();
    1506         596 :                 if ( LT_16( L_spec, 256 ) )
    1507             :                 {
    1508           0 :                     tmp1 = 0;
    1509           0 :                     move16();
    1510             :                 }
    1511         596 :                 NumIndexBits = CountIndexBits( tmp1, PeriodicityIndex );
    1512             : 
    1513             : 
    1514             :                 /* Quantize original spectrum */
    1515             : 
    1516         596 :                 sqGain = SQ_gain_fx( OriginalSpectrum, OriginalSpectrum_e,
    1517         596 :                                      shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ),
    1518             :                                      L_spec,
    1519             :                                      &sqGain_e );
    1520             : 
    1521         596 :                 tcx_scalar_quantization_fx( OriginalSpectrum, OriginalSpectrum_e,
    1522             :                                             sqQ,
    1523             :                                             L_spec,
    1524             :                                             sqGain, sqGain_e,
    1525         596 :                                             hTcxCfg->sq_rounding,
    1526         596 :                                             hTcxEnc->memQuantZeros,
    1527             :                                             tcxonly );
    1528             : 
    1529             :                 /* Estimate original bitrate */
    1530         596 :                 stop = 0;
    1531         596 :                 move16();
    1532             : 
    1533         596 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1534             :                                                                              L_spec,
    1535             :                                                                              &lastnz,
    1536             :                                                                              &nEncoded,
    1537             :                                                                              sqTargetBits,
    1538             :                                                                              &stop,
    1539             :                                                                              NULL );
    1540             : 
    1541             :                 /* Estimate context mapped bitrate */
    1542             : 
    1543         596 :                 stopCtxHm = 0;
    1544         596 :                 move16();
    1545             : 
    1546             :                 /* Context Mapping */
    1547         596 :                 sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1548             :                                                                                   L_spec,
    1549             :                                                                                   &lastnzCtxHm,
    1550             :                                                                                   &nEncodedCtxHm,
    1551         596 :                                                                                   sub( sqTargetBits, NumIndexBits ),
    1552             :                                                                                   &stopCtxHm,
    1553             :                                                                                   hm_cfg );
    1554             : 
    1555             :                 /* Decide whether or not to use context mapping */
    1556         596 :                 Selector = sub( s_max( stop, sqBits ), add( s_max( stopCtxHm, sqBitsCtxHm ), NumIndexBits ) );
    1557             : 
    1558         596 :                 test();
    1559         596 :                 test();
    1560         596 :                 IF( ( GT_16( Selector, 2 ) ) || ( ( LE_16( abs_s( Selector ), 2 ) ) &&
    1561             :                                                   ( LT_16( kCtxHmOlRSThr, RelativeScore ) ) ) )
    1562             :                 {
    1563             :                     /* CtxHm is likely better */
    1564          47 :                     sqTargetBits = sub( sqTargetBits, NumIndexBits );
    1565          47 :                     ctxHmBits = add( ctxHmBits, NumIndexBits );
    1566          47 :                     prm_hm[0] = 1;
    1567          47 :                     move16();
    1568          47 :                     prm_hm[1] = PeriodicityIndex;
    1569          47 :                     move16();
    1570          47 :                     *prm_lastnz = lastnzCtxHm;
    1571          47 :                     move16();
    1572          47 :                     sqBits_noStop = sqBits = sqBitsCtxHm;
    1573          47 :                     move16();
    1574          47 :                     move16();
    1575          47 :                     nEncoded = nEncodedCtxHm;
    1576          47 :                     move16();
    1577          47 :                     stop = stopCtxHm;
    1578          47 :                     move16();
    1579             :                 }
    1580             :                 ELSE /* Original is better or not much difference */
    1581             :                 {
    1582         549 :                     prm_hm[0] = 0;
    1583         549 :                     move16();
    1584         549 :                     prm_hm[1] = PeriodicityIndex;
    1585         549 :                     move16();
    1586         549 :                     *prm_lastnz = lastnz;
    1587         549 :                     move16();
    1588         549 :                     PeriodicityIndex = -1;
    1589         549 :                     move16();
    1590             : 
    1591         549 :                     sqBits_noStop = sqBits;
    1592         549 :                     move16();
    1593             :                 }
    1594             : 
    1595             : 
    1596         596 :                 if ( stop != 0 )
    1597             :                 {
    1598             : 
    1599         216 :                     sqBits = stop;
    1600         216 :                     move16();
    1601             :                 }
    1602             :             }
    1603             :             ELSE /* no context hm*/
    1604             :             {
    1605          38 :                 PeriodicityIndex = -1;
    1606          38 :                 move16();
    1607             : 
    1608          38 :                 sqGain = SQ_gain_fx( spectrum, *spectrum_e,
    1609          38 :                                      shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ),
    1610             :                                      L_spec,
    1611             :                                      &sqGain_e );
    1612             : 
    1613             :                 /* Quantize spectrum */
    1614             : 
    1615          38 :                 tcx_scalar_quantization_fx( spectrum, *spectrum_e,
    1616             :                                             sqQ,
    1617             :                                             L_spec,
    1618             :                                             sqGain, sqGain_e,
    1619          38 :                                             hTcxCfg->sq_rounding,
    1620          38 :                                             hTcxEnc->memQuantZeros,
    1621             :                                             tcxonly );
    1622             : 
    1623             :                 /* Estimate bitrate */
    1624          38 :                 stop = 0;
    1625          38 :                 move16();
    1626          38 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1627             :                                                                              L_spec,
    1628             :                                                                              prm_lastnz, /* lastnz */
    1629             :                                                                              &nEncoded,
    1630             :                                                                              sqTargetBits,
    1631             :                                                                              &stop,
    1632             :                                                                              NULL );
    1633             : 
    1634          38 :                 sqBits_noStop = sqBits;
    1635          38 :                 move16();
    1636             : 
    1637          38 :                 if ( stop != 0 )
    1638             :                 {
    1639           7 :                     sqBits = stop;
    1640           7 :                     move16();
    1641             :                 }
    1642             :             } /* end of if (ctx_hm) */
    1643             : 
    1644             :             /* Adjust correction factor */
    1645         634 :             tmp1 = sqBits;
    1646         634 :             move16();
    1647             : 
    1648         634 :             if ( s_and( L_spec, sub( L_spec, 1 ) ) == 0 ) /* power-of-2 */
    1649             :             {
    1650           0 :                 tmp1 = add( tmp1, 1 );
    1651             :             }
    1652             : 
    1653         634 :             tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 );
    1654             :             BASOP_SATURATE_WARNING_OFF_EVS
    1655         634 :             hTcxEnc->tcx_target_bits_fac = shl_sat( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2 );
    1656         634 :             move16();
    1657             :             BASOP_SATURATE_WARNING_ON_EVS
    1658             : 
    1659         634 :             if ( GT_16( hTcxEnc->tcx_target_bits_fac, 0x5000 ) )
    1660             :             {
    1661         205 :                 hTcxEnc->tcx_target_bits_fac = 0x5000;
    1662         205 :                 move16();
    1663             :             }
    1664         634 :             if ( LT_16( hTcxEnc->tcx_target_bits_fac, 0x3000 ) )
    1665             :             {
    1666           0 :                 hTcxEnc->tcx_target_bits_fac = 0x3000;
    1667           0 :                 move16();
    1668             :             }
    1669             : 
    1670             :             /* Refine quantizer step size with a rate-control-loop (optional) */
    1671         634 :             phm_cfg = NULL;
    1672         634 :             move16();
    1673         634 :             if ( PeriodicityIndex >= 0 )
    1674             :             {
    1675          47 :                 phm_cfg = hm_cfg;
    1676          47 :                 move16();
    1677             :             }
    1678        1268 :             sqBits = tcx_scalar_quantization_rateloop_fx( spectrum, *spectrum_e,
    1679             :                                                           sqQ,
    1680             :                                                           L_spec,
    1681             :                                                           &sqGain, &sqGain_e,
    1682         634 :                                                           hTcxCfg->sq_rounding,
    1683         634 :                                                           hTcxEnc->memQuantZeros,
    1684             :                                                           prm_lastnz, /* lastnz */
    1685             :                                                           sqTargetBits,
    1686             :                                                           &nEncoded,
    1687             :                                                           &stop,
    1688             :                                                           sqBits_noStop,
    1689             :                                                           sqBits,
    1690         634 :                                                           hTcxCfg->tcxRateLoopOpt,
    1691             :                                                           tcxonly,
    1692             :                                                           phm_cfg );
    1693             : 
    1694         634 :             IF( ctxHmBits > 0 ) /* Mapping tool is enabled */
    1695             :             {
    1696             :                 /* Truncate spectrum */
    1697         596 :                 set16_fx( sqQ + nEncoded, 0, sub( L_spec, nEncoded ) );
    1698             : 
    1699         596 :                 IF( PeriodicityIndex >= 0 ) /* Mapping is used */
    1700             :                 {
    1701             :                     /* Estimate non-mapped bitrate */
    1702          47 :                     stopCtxHm = 1;
    1703          47 :                     move16();
    1704             : 
    1705          47 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1706             :                                                                                       L_spec,
    1707             :                                                                                       &lastnz,
    1708             :                                                                                       &nEncodedCtxHm,
    1709             :                                                                                       sqTargetBits,
    1710             :                                                                                       &stopCtxHm,
    1711             :                                                                                       NULL );
    1712             : 
    1713             :                     /* Decide whether or not to revert mapping */
    1714          47 :                     Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    1715             : 
    1716          47 :                     test();
    1717          47 :                     IF( stopCtxHm == 0 && Selector > 0 ) /* Non-mapped is better */
    1718             :                     {
    1719           1 :                         sqTargetBits = add( sqTargetBits, NumIndexBits );
    1720           1 :                         ctxHmBits = sub( ctxHmBits, NumIndexBits );
    1721           1 :                         prm_hm[0] = 0;
    1722           1 :                         move16();
    1723           1 :                         *prm_lastnz = lastnz;
    1724           1 :                         move16();
    1725           1 :                         PeriodicityIndex = -1;
    1726           1 :                         move16();
    1727           1 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    1728           1 :                         move16();
    1729           1 :                         move16();
    1730           1 :                         nEncoded = nEncodedCtxHm;
    1731           1 :                         move16();
    1732           1 :                         stop = stopCtxHm;
    1733           1 :                         move16();
    1734             :                     }
    1735             :                 }
    1736             :                 ELSE /* Mapping is not used */
    1737             :                 {
    1738             :                     /* Estimate mapped bitrate */
    1739         549 :                     stopCtxHm = 1;
    1740         549 :                     move16();
    1741         549 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1742             :                                                                                       L_spec,
    1743             :                                                                                       &lastnzCtxHm,
    1744             :                                                                                       &nEncodedCtxHm,
    1745         549 :                                                                                       sub( sqTargetBits, NumIndexBits ),
    1746             :                                                                                       &stopCtxHm,
    1747             :                                                                                       hm_cfg );
    1748             : 
    1749             :                     /* Decide whether or not to use mapping */
    1750         549 :                     Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    1751             : 
    1752         549 :                     test();
    1753         549 :                     IF( stopCtxHm == 0 && Selector > 0 ) /* Mapped is better */
    1754             :                     {
    1755           8 :                         sqTargetBits = sub( sqTargetBits, NumIndexBits );
    1756           8 :                         ctxHmBits = add( ctxHmBits, NumIndexBits );
    1757           8 :                         prm_hm[0] = 1;
    1758           8 :                         move16();
    1759           8 :                         *prm_lastnz = lastnzCtxHm;
    1760           8 :                         move16();
    1761           8 :                         PeriodicityIndex = prm_hm[1];
    1762           8 :                         move16();
    1763           8 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    1764           8 :                         move16();
    1765           8 :                         move16();
    1766           8 :                         nEncoded = nEncodedCtxHm;
    1767           8 :                         move16();
    1768           8 :                         stop = stopCtxHm;
    1769           8 :                         move16();
    1770             :                     }
    1771             :                 }
    1772             :             }
    1773             : 
    1774             :             /* Limit low sqGain for avoiding saturation of the gain quantizer*/
    1775         634 :             tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    1776         634 :             s = 15 - 5 - 7;
    1777         634 :             IF( L_spec >= 1024 )
    1778             :             {
    1779             :                 /*reduce precision for avoiding overflow*/
    1780           0 :                 tmp1 = mult_r( shl( L_spec, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    1781           0 :                 s = 15 - 4 - 7;
    1782             :             }
    1783         634 :             tmp1 = ISqrt16( tmp1, &s );
    1784             : 
    1785         634 :             tmp2 = sub( sqGain_e, s );
    1786         634 :             IF( tmp2 >= 0 )
    1787             :             {
    1788             :                 BASOP_SATURATE_WARNING_OFF_EVS;
    1789         634 :                 tmp2 = sub_sat( sqGain, shr_sat( tmp1, tmp2 ) );
    1790             :                 BASOP_SATURATE_WARNING_ON_EVS;
    1791             :             }
    1792             :             ELSE
    1793             :             {
    1794           0 :                 tmp2 = sub( shl( sqGain, s_max( -15, tmp2 ) ), tmp1 );
    1795             :             }
    1796             : 
    1797         634 :             IF( tmp2 < 0 )
    1798             :             {
    1799           0 :                 sqGain = tmp1;
    1800           0 :                 sqGain_e = s;
    1801             : 
    1802           0 :                 tcx_scalar_quantization_fx( spectrum, *spectrum_e,
    1803             :                                             sqQ,
    1804             :                                             L_spec,
    1805             :                                             sqGain, sqGain_e,
    1806           0 :                                             hTcxCfg->sq_rounding,
    1807           0 :                                             hTcxEnc->memQuantZeros,
    1808             :                                             tcxonly );
    1809             : 
    1810           0 :                 move16();
    1811           0 :                 stop = 1;
    1812             : 
    1813           0 :                 phm_cfg = NULL;
    1814           0 :                 move16();
    1815           0 :                 if ( PeriodicityIndex >= 0 )
    1816             :                 {
    1817           0 :                     phm_cfg = hm_cfg;
    1818           0 :                     move16();
    1819             :                 }
    1820           0 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1821             :                                                                              L_spec,
    1822             :                                                                              prm_lastnz,
    1823             :                                                                              &nEncoded,
    1824             :                                                                              sqTargetBits,
    1825             :                                                                              &stop,
    1826             :                                                                              phm_cfg );
    1827             :             }
    1828             : 
    1829             :             /* Truncate spectrum (for CBR) */
    1830         634 :             IF( stop != 0 )
    1831             :             {
    1832          63 :                 set16_fx( sqQ + nEncoded, 0, sub( L_spec, nEncoded ) );
    1833             :             }
    1834             : 
    1835             :             /* Save quantized Values */
    1836         634 :             tmp32 = L_deposit_l( 0 );
    1837         634 :             move16();
    1838         634 :             Word64 seed = 0;
    1839         634 :             move64();
    1840      412474 :             FOR( i = 0; i < L_spec; i++ )
    1841             :             {
    1842      411840 :                 spectrum[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) );
    1843      411840 :                 move32();
    1844             :                 /* noise filling seed */
    1845      411840 :                 seed = W_mac_16_16( seed, abs_s( sqQ[i] ), i );
    1846             :             }
    1847         634 :             *spectrum_e = SPEC_EXP_DEC;
    1848         634 :             move16();
    1849             : 
    1850         634 :             nf_seed = extract_l( W_extract_l( seed ) ); // Q0
    1851             :         }
    1852             :         ELSE /* low rates: new arithmetic coder */
    1853             :         {
    1854           0 :             AdaptLowFreqEmph_fx( spectrum, *spectrum_e,
    1855             :                                  NULL,
    1856             :                                  0, 0,
    1857           0 :                                  hTcxEnc->tcx_lpc_shaped_ari,
    1858             :                                  gainlpc, gainlpc_e,
    1859             :                                  L_frame );
    1860             : 
    1861           0 :             prm_target = sqQ;
    1862           0 :             move16();
    1863           0 :             sqQ = prm_target + 1;
    1864           0 :             move16();
    1865           0 :             signs = hm_cfg->indexBuffer;
    1866           0 :             move16();
    1867             : 
    1868           0 :             LtpPitchLag = -1;
    1869           0 :             move16();
    1870             : 
    1871           0 :             IF( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) )
    1872             :             {
    1873           0 :                 tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
    1874           0 :                 tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
    1875           0 :                 LtpPitchLag = div_l( tmp32, tmp1 );
    1876             :             }
    1877             : 
    1878           0 :             tmp8 = 1;
    1879           0 :             move16();
    1880           0 :             if ( st->last_core == ACELP_CORE )
    1881             :             {
    1882           0 :                 tmp8 = 0;
    1883           0 :                 move16();
    1884             :             }
    1885             : 
    1886           0 :             tcx_arith_encode_envelope_fx(
    1887             :                 spectrum,
    1888             :                 spectrum_e,
    1889             :                 signs,
    1890             :                 L_frame,
    1891             :                 L_spec,
    1892             :                 st,
    1893             :                 Aqind,
    1894             :                 sqTargetBits,
    1895             :                 sqQ,
    1896             :                 tmp8,
    1897             :                 prm_hm, /* HM parameter area */
    1898             :                 LtpPitchLag,
    1899             :                 &sqBits,
    1900             :                 &signaling_bits,
    1901           0 :                 &nf_seed, shr( st->bwidth, 1 ) /* equivalent to: (st->bwidth > WB)?1:0 */
    1902             :             );
    1903             : 
    1904           0 :             sqTargetBits = sub( sqTargetBits, signaling_bits );
    1905           0 :             *prm_target = sqTargetBits;
    1906           0 :             move16();
    1907             :         }
    1908             : 
    1909             :         /*-----------------------------------------------------------*
    1910             :          * Compute optimal TCX gain.                                 *
    1911             :          *-----------------------------------------------------------*/
    1912             :         /* initialize LF deemphasis factors in xn_buf */
    1913         634 :         set16_fx( xn_buf16, 0x4000, L_spec );
    1914             : 
    1915         634 :         IF( tcxonly == 0 )
    1916             :         {
    1917             : 
    1918         634 :             AdaptLowFreqDeemph( spectrum, *spectrum_e,
    1919         634 :                                 hTcxEnc->tcx_lpc_shaped_ari,
    1920             :                                 gainlpc, gainlpc_e,
    1921             :                                 L_frame,
    1922             :                                 xn_buf16 /* LF deemphasis factors */
    1923             :             );
    1924             :         }
    1925             : 
    1926         634 :         tcx_get_gain( x_orig, x_orig_e,
    1927         634 :                       spectrum, *spectrum_e,
    1928             :                       L_spec,
    1929             :                       &gain_tcx_opt, &gain_tcx_opt_e,
    1930             :                       &ener, &ener_e );
    1931             : 
    1932         634 :         IF( gain_tcx_opt <= 0 )
    1933             :         {
    1934           0 :             gain_tcx_opt = sqGain;
    1935           0 :             move16();
    1936           0 :             gain_tcx_opt_e = sqGain_e;
    1937           0 :             move16();
    1938             :         }
    1939         634 :         gain_tcx = gain_tcx_opt;
    1940         634 :         move16();
    1941         634 :         gain_tcx_e = gain_tcx_opt_e;
    1942         634 :         move16();
    1943             : 
    1944             :         /* Save gains for FAC and Residual Q*/
    1945             : 
    1946             :         /*-----------------------------------------------------------*
    1947             :          * Quantize TCX gain                                         *
    1948             :          *-----------------------------------------------------------*/
    1949         634 :         test();
    1950         634 :         IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    1951             :         {
    1952         634 :             QuantizeGain( L_spec, &gain_tcx, &gain_tcx_e, &prm[0] );
    1953             :         }
    1954             : 
    1955             : 
    1956             :         /*-----------------------------------------------------------*
    1957             :          * Residual Quantization                                     *
    1958             :          *-----------------------------------------------------------*/
    1959             : 
    1960         634 :         IF( hTcxCfg->resq )
    1961             :         {
    1962             : 
    1963         634 :             resQTargetBits = sub( sqTargetBits, sqBits );
    1964             : 
    1965         634 :             IF( hTcxEnc->tcx_lpc_shaped_ari ) /* new arithmetic coder */
    1966             :             {
    1967             :                 Word16 *prm_resq;
    1968             : 
    1969           0 :                 prm_resq = sqQ + sqTargetBits - resQTargetBits;
    1970             : 
    1971           0 :                 resQBits = tcx_ari_res_Q_spec_fx( x_orig, x_orig_e, signs, spectrum, *spectrum_e, L_spec, gain_tcx, gain_tcx_e,
    1972             :                                                   prm_resq,
    1973             :                                                   resQTargetBits,
    1974             :                                                   resQBits,
    1975           0 :                                                   hTcxCfg->sq_rounding,
    1976             :                                                   xn_buf16 /* LF deemphasis factors */ );
    1977             : 
    1978             :                 /* Transmit zeros when there bits remain after RESQ */
    1979           0 :                 set16_fx( prm_resq + resQBits, 0, sub( resQTargetBits, resQBits ) );
    1980             :             }
    1981             :             ELSE /* old arithmetic coder */
    1982             :             {
    1983         634 :                 move16();
    1984         634 :                 tmpP16 = NULL;
    1985         634 :                 if ( tcxonly == 0 )
    1986             :                 {
    1987         634 :                     move16();
    1988         634 :                     tmpP16 = xn_buf16;
    1989             :                 }
    1990             : 
    1991         634 :                 resQBits = tcx_res_Q_gain_fx( gain_tcx_opt, gain_tcx_opt_e,
    1992             :                                               &gain_tcx, &gain_tcx_e,
    1993         634 :                                               &sqQ[L_spec],
    1994             :                                               resQTargetBits );
    1995             : 
    1996         634 :                 resQBits = tcx_res_Q_spec_fx( x_orig, x_orig_e,
    1997         634 :                                               spectrum, *spectrum_e,
    1998             :                                               L_spec,
    1999             :                                               gain_tcx, gain_tcx_e,
    2000         634 :                                               &sqQ[L_spec],
    2001             :                                               resQTargetBits,
    2002             :                                               resQBits,
    2003         634 :                                               hTcxCfg->sq_rounding,
    2004             :                                               tmpP16 /* LF deemphasis factors */ );
    2005             :             }
    2006             :         }
    2007             : 
    2008             : 
    2009             :         /*-----------------------------------------------------------*
    2010             :          * ALFE tcx only bitrates                                    *
    2011             :          *-----------------------------------------------------------*/
    2012             : 
    2013         634 :         IF( st->tcxonly != 0 )
    2014             :         {
    2015           0 :             test();
    2016           0 :             test();
    2017           0 :             IF( hTcxEnc->tcxltp != 0 && ( hTcxEnc->tcxltp_gain > 0 ) && fUseTns == 0 )
    2018             :             {
    2019             : 
    2020           0 :                 PsychAdaptLowFreqDeemph( spectrum, gainlpc, gainlpc_e, NULL );
    2021             :             }
    2022             :         }
    2023             : 
    2024             :         /*-----------------------------------------------------------*
    2025             :          * TCX SNR for Analysis purposes                             *
    2026             :          *-----------------------------------------------------------*/
    2027             : 
    2028             :         {
    2029         634 :             maxNfCalcBw = s_min( noiseFillingSize, round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame ), 1 ) ) );
    2030             : 
    2031             :             /*-----------------------------------------------------------*
    2032             :              * Estimate and quantize noise factor                        *
    2033             :              *-----------------------------------------------------------*/
    2034             : 
    2035         634 :             IF( GE_32( st->total_brate, HQ_96k ) )
    2036             :             {
    2037           0 :                 fac_ns = 0;
    2038           0 :                 move16();
    2039           0 :                 prm[1] = 0;
    2040           0 :                 move16();
    2041             :             }
    2042             :             ELSE
    2043             :             {
    2044             :                 /* noise filling start bin */
    2045         634 :                 i = shr( L_frame, 3 );
    2046         634 :                 test();
    2047         634 :                 IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    2048             :                 {
    2049         634 :                     i = idiv1616U( L_frame, 6 );
    2050             :                 }
    2051             : 
    2052         634 :                 IF( tcxonly )
    2053             :                 {
    2054           0 :                     tmp1 = 0;
    2055           0 :                     move16();
    2056           0 :                     test();
    2057           0 :                     test();
    2058           0 :                     if ( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) && ( prm_hm[0] != 0 ) )
    2059             :                     {
    2060           0 :                         tmp1 = 10240 /*0.3125f Q15*/;
    2061           0 :                         move16();
    2062             :                     }
    2063           0 :                     noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( hTcxEnc->tcxltp_gain, tmp1 ) );
    2064             : 
    2065           0 :                     if ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) )
    2066             :                     {
    2067             :                         /* minimum transition for noise filling in TCX-10 */
    2068           0 :                         noiseTransWidth = 3;
    2069           0 :                         move16();
    2070             :                     }
    2071             :                 }
    2072             : 
    2073         634 :                 tcx_noise_factor_fx( x_orig, x_orig_e,
    2074             :                                      spectrum,
    2075             :                                      i,
    2076             :                                      maxNfCalcBw,
    2077             :                                      noiseTransWidth,
    2078             :                                      L_frame,
    2079             :                                      gain_tcx, gain_tcx_e,
    2080         634 :                                      hTcxEnc->noiseTiltFactor,
    2081             :                                      &fac_ns, &prm[NOISE_FILL_RANGES] );
    2082             : 
    2083             :                 /* hysteresis for very tonal passages (more stationary noise filling level) */
    2084             : 
    2085         634 :                 IF( EQ_16( prm[NOISE_FILL_RANGES], 1 ) )
    2086             :                 {
    2087          55 :                     hTcxEnc->noiseLevelMemory_cnt = add( 1, abs_s( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
    2088          55 :                     move16();
    2089             :                 }
    2090             :                 ELSE
    2091             :                 {
    2092         579 :                     test();
    2093         579 :                     IF( ( EQ_16( prm[NOISE_FILL_RANGES], 2 ) ) &&
    2094             :                         ( GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) ) )
    2095             :                     {
    2096             :                         /* reduce noise filling level by one step */
    2097           3 :                         prm[NOISE_FILL_RANGES] = 1;
    2098           3 :                         move16();
    2099           3 :                         fac_ns = shr( 0x6000, NBITS_NOISE_FILL_LEVEL );
    2100             : 
    2101             :                         /* signal that noise level is changed by inverting sign of level memory */
    2102           3 :                         tmp1 = 5;
    2103           3 :                         move16();
    2104           3 :                         if ( hTcxEnc->noiseLevelMemory_cnt >= 0 )
    2105             :                         {
    2106           3 :                             tmp1 = sub( -1, hTcxEnc->noiseLevelMemory_cnt );
    2107             :                         }
    2108           3 :                         hTcxEnc->noiseLevelMemory_cnt = tmp1;
    2109           3 :                         move16();
    2110             :                     }
    2111             :                     ELSE
    2112             :                     {
    2113             :                         /* reset memory since level is too different */
    2114         576 :                         hTcxEnc->noiseLevelMemory_cnt = 0;
    2115         576 :                         move16();
    2116             :                     }
    2117             :                 }
    2118             : 
    2119             :             } /* bitrate */
    2120             :         }
    2121             : 
    2122             :         /* Free encoder specific stack to use it below for the internal TCX decoder. */
    2123             :     }
    2124             : 
    2125             :     /*-----------------------------------------------------------*
    2126             :      * Internal TCX decoder                                      *
    2127             :      *-----------------------------------------------------------*/
    2128             :     {
    2129             :         /* Overlay of a 16-bit buffer xn_buf16 with a 32-bit buffer xn_buf32 */
    2130             :         /* The size is determined by the requirements of the 16-bit buffer.  */
    2131             :         Word32 xn_buf32[( L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    2132         634 :         Word16 *xn_buf16 = (Word16 *) xn_buf32;
    2133             : 
    2134             :         /*Enable internal TCX decoder to run always to update LPD memory for rate switching */
    2135             : 
    2136             :         IF( tcxonly == 0 )
    2137             :         {
    2138             :         }
    2139             : 
    2140             :         /*-----------------------------------------------------------*
    2141             :          * Noise Filling.                                            *
    2142             :          *-----------------------------------------------------------*/
    2143             : 
    2144         634 :         test();
    2145             :         /* Replication of ACELP formant enhancement for low rates */
    2146         634 :         IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 )
    2147             :         {
    2148           0 :             tcxFormantEnhancement( xn_buf16, gainlpc, gainlpc_e, spectrum, spectrum_e, L_frame, L_spec );
    2149             :         }
    2150             : 
    2151         634 :         IF( fac_ns > 0 )
    2152             :         {
    2153         634 :             tmp1 = 0;
    2154         634 :             move16();
    2155         634 :             test();
    2156         634 :             if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    2157             :             {
    2158         634 :                 tmp1 = 1;
    2159         634 :                 move16();
    2160             :             }
    2161             : 
    2162         634 :             i = tcxGetNoiseFillingTilt( A,
    2163             :                                         M,
    2164             :                                         L_frame,
    2165             :                                         tmp1,
    2166             :                                         &hTcxEnc->noiseTiltFactor );
    2167             : 
    2168         634 :             tcx_noise_filling( spectrum, *spectrum_e, nf_seed /* seed */, i, noiseFillingSize, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns, NULL, st->element_mode );
    2169             :         }
    2170         634 :         test();
    2171         634 :         IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 )
    2172             :         {
    2173             :             /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */
    2174           0 :             s = sub( getScaleFactor32( spectrum, L_spec ), 4 );
    2175           0 :             tmp32 = L_deposit_l( 1 );
    2176             : 
    2177           0 :             FOR( i = 0; i < L_spec; i++ )
    2178             :             {
    2179           0 :                 tmp1 = round_fx( L_shl( spectrum[i], s ) );
    2180           0 :                 tmp32 = L_mac0( tmp32, tmp1, tmp1 );
    2181             :             }
    2182             : 
    2183           0 :             tmp1 = BASOP_Util_Divide3232_Scale( ener, tmp32, &tmp2 );
    2184           0 :             tmp2 = add( tmp2, sub( ener_e, add( shl( sub( *spectrum_e, s ), 1 ), 1 ) ) );
    2185           0 :             tmp1 = Sqrt16( tmp1, &tmp2 );
    2186             : 
    2187           0 :             gain_tcx = mult( gain_tcx, tmp1 );
    2188           0 :             gain_tcx_e = add( gain_tcx_e, tmp2 );
    2189             : 
    2190           0 :             QuantizeGain( L_spec, &gain_tcx, &gain_tcx_e, &prm[0] );
    2191             :         }
    2192             : 
    2193             :         /*end of noise filling*/
    2194             : 
    2195             :         /*-----------------------------------------------------------*
    2196             :          * Noise shaping in frequency domain (1/Wz)                  *
    2197             :          *-----------------------------------------------------------*/
    2198             : 
    2199             :         /* LPC gains already available */
    2200         634 :         mdct_shaping( spectrum, L_frame, gainlpc, gainlpc_e );
    2201             : 
    2202             :         /*-----------------------------------------------------------*
    2203             :          * Apply gain                                                *
    2204             :          *-----------------------------------------------------------*/
    2205         634 :         IF( st->hTcxCfg->coder_type == INACTIVE )
    2206             :         {
    2207          10 :             gain_tcx = mult_r( gain_tcx, hTcxCfg->na_scale );
    2208             :         }
    2209             : 
    2210      412474 :         FOR( i = 0; i < L_spec; i++ )
    2211             :         {
    2212      411840 :             spectrum[i] = Mpy_32_16_1( spectrum[i], gain_tcx ); // Q(31-(spectrum_e+gain_tcx_e))
    2213      411840 :             move32();
    2214             :         }
    2215         634 :         *spectrum_e = add( *spectrum_e, gain_tcx_e );
    2216         634 :         move16();
    2217             : 
    2218         634 :         stop = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    2219         634 :         move16();
    2220             : 
    2221         634 :         test();
    2222         634 :         IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( tcxonly != 0 ) )
    2223             :         {
    2224           0 :             Word16 L = L_frame;
    2225           0 :             move16();
    2226             : 
    2227           0 :             test();
    2228           0 :             test();
    2229           0 :             if ( ( ( hTcxCfg->fIsTNSAllowed != 0 ) && ( fUseTns != 0 ) ) || ( GT_16( L_spec, L_frame ) ) )
    2230             :             {
    2231           0 :                 L = L_spec;
    2232           0 :                 move16();
    2233             :             }
    2234             : 
    2235           0 :             tcxInvertWindowGrouping( hTcxCfg,
    2236             :                                      xn_buf32,
    2237             :                                      spectrum,
    2238             :                                      L,
    2239             :                                      fUseTns,
    2240           0 :                                      st->last_core,
    2241             :                                      stop,
    2242             :                                      frame_cnt,
    2243             :                                      0 );
    2244             :         }
    2245             : 
    2246             :         /*-----------------------------------------------------------*
    2247             :          * Temporal Noise Shaping Synthesis                          *
    2248             :          *-----------------------------------------------------------*/
    2249             : 
    2250         634 :         IF( hTcxCfg->fIsTNSAllowed != 0 )
    2251             :         {
    2252         372 :             test();
    2253         372 :             SetTnsConfig( hTcxCfg, sub( L_frame_glob, st->L_frame ) == 0, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
    2254             : 
    2255             :             /* Apply TNS to get the reconstructed signal */
    2256         372 :             IF( fUseTns != 0 )
    2257             :             {
    2258           4 :                 ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 0 );
    2259             : 
    2260           4 :                 test();
    2261           4 :                 IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( tcxonly != 0 ) )
    2262             :                 {
    2263           0 :                     test();
    2264           0 :                     test();
    2265           0 :                     test();
    2266           0 :                     IF( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
    2267             :                         ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( stop == 0 ) ) )
    2268             :                     {
    2269           0 :                         tmp1 = shr( L_spec, 1 );
    2270             :                         /* undo rearrangement of LF sub-window lines for TNS synthesis filter */
    2271           0 :                         assert( L_frame <= L_spec );
    2272           0 :                         Copy32( spectrum + 8, xn_buf32, 8 );
    2273           0 :                         Copy32( spectrum + 16, spectrum + 8, sub( tmp1, 8 ) );
    2274           0 :                         Copy32( xn_buf32, spectrum + tmp1, 8 );
    2275             :                     }
    2276             :                 }
    2277             :             }
    2278             :         }
    2279             : 
    2280             :         {
    2281             :             /* normalize spectrum to minimize IMDCT noise */
    2282         634 :             s = getScaleFactor32( spectrum, L_frame );
    2283      189546 :             FOR( i = 0; i < L_frame; i++ )
    2284             :             {
    2285      188912 :                 spectrum[i] = L_shl( spectrum[i], s ); // Q(31-(spectrum_e-s))
    2286      188912 :                 move32();
    2287             :             }
    2288         634 :             *spectrum_e = sub( *spectrum_e, s );
    2289             : 
    2290             :             /*-----------------------------------------------------------*
    2291             :              * Compute inverse MDCT of spectrum[].                        *
    2292             :              *-----------------------------------------------------------*/
    2293         634 :             test();
    2294         634 :             IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( tcxonly != 0 ) )
    2295             :             {
    2296           0 :                 IF( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP )
    2297             :                 {
    2298             :                     Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    2299             :                     Word16 L_win, L_spec_TCX5, L_ola, w;
    2300             : 
    2301             :                     /* minimum or half overlap, two transforms, grouping into one window */
    2302           0 :                     L_win = shr( L_frame, 1 );
    2303           0 :                     L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
    2304           0 :                     L_ola = hTcxCfg->tcx_mdct_window_half_length;
    2305           0 :                     move16();
    2306           0 :                     if ( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    2307             :                     {
    2308           0 :                         L_ola = hTcxCfg->tcx_mdct_window_min_length;
    2309           0 :                         move16();
    2310             :                     }
    2311             : 
    2312           0 :                     set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    2313           0 :                     set16_fx( xn_buf16, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */
    2314             : 
    2315           0 :                     FOR( w = 0; w < 2; w++ )
    2316             :                     {
    2317             : 
    2318           0 :                         IF( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    2319             :                         {
    2320           0 :                             TCX_MDCT_Inverse( spectrum + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2321           0 :                                               win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    2322             :                         }
    2323             :                         ELSE
    2324             :                         {
    2325           0 :                             TCX_MDCT_Inverse( spectrum + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win,
    2326           0 :                                               L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    2327             :                         }
    2328             : 
    2329           0 :                         tmp1 = hTcxCfg->tcx_last_overlap_mode;
    2330           0 :                         move16();
    2331           0 :                         test();
    2332           0 :                         test();
    2333           0 :                         if ( ( w > 0 ) || ( ( w == 0 ) && ( EQ_16( stop, 2 ) ) ) )
    2334             :                         {
    2335           0 :                             tmp1 = MIN_OVERLAP;
    2336           0 :                             move16();
    2337             :                         }
    2338             : 
    2339           0 :                         tmp2 = 0;
    2340           0 :                         move16();
    2341           0 :                         test();
    2342           0 :                         if ( ( w == 0 ) && ( st->last_core == ACELP_CORE ) )
    2343             :                         {
    2344           0 :                             tmp2 = 1;
    2345           0 :                             move16();
    2346             :                         }
    2347             : 
    2348           0 :                         tmp3 = st->last_core;
    2349           0 :                         move16();
    2350           0 :                         if ( w > 0 )
    2351             :                         {
    2352           0 :                             tmp3 = 1;
    2353           0 :                             move16();
    2354             :                         }
    2355             : 
    2356           0 :                         tmp4 = 0;
    2357           0 :                         move16();
    2358           0 :                         if ( tcx_offset < 0 )
    2359             :                         {
    2360           0 :                             tmp4 = negate( tcx_offset );
    2361             :                         }
    2362             : 
    2363           0 :                         tcx_windowing_synthesis_current_frame( win,
    2364           0 :                                                                hTcxCfg->tcx_aldo_window_2,
    2365           0 :                                                                hTcxCfg->tcx_mdct_window_half,
    2366           0 :                                                                hTcxCfg->tcx_mdct_window_minimum,
    2367             :                                                                L_ola,
    2368           0 :                                                                hTcxCfg->tcx_mdct_window_half_length,
    2369           0 :                                                                hTcxCfg->tcx_mdct_window_min_length,
    2370             :                                                                tmp2,
    2371             :                                                                tmp1,
    2372             :                                                                hTcxEnc->acelp_zir,
    2373           0 :                                                                hTcxEnc->Txnq,
    2374             :                                                                NULL,
    2375             :                                                                Aq_old,
    2376           0 :                                                                hTcxCfg->tcx_mdct_window_trans,
    2377             :                                                                L_win,
    2378             :                                                                tmp4,
    2379             :                                                                tmp3,
    2380             :                                                                0,
    2381             :                                                                0 );
    2382             : 
    2383           0 :                         tmp1 = add( tcx_offset, imult1616( w, L_win ) );
    2384           0 :                         move16();
    2385           0 :                         tmpP16 = xn_buf16 + sub( tmp1, shr( L_ola, 1 ) );
    2386             : 
    2387           0 :                         IF( w > 0 )
    2388             :                         {
    2389           0 :                             tcx_windowing_synthesis_past_frame( tmpP16,
    2390           0 :                                                                 hTcxCfg->tcx_aldo_window_1_trunc,
    2391           0 :                                                                 hTcxCfg->tcx_mdct_window_half,
    2392           0 :                                                                 hTcxCfg->tcx_mdct_window_minimum,
    2393             :                                                                 L_ola,
    2394           0 :                                                                 hTcxCfg->tcx_mdct_window_half_length,
    2395           0 :                                                                 hTcxCfg->tcx_mdct_window_min_length,
    2396             :                                                                 2 );
    2397             :                         }
    2398             :                         /* add part of current sub-window overlapping with previous window */
    2399           0 :                         FOR( i = 0; i < L_ola; i++ )
    2400             :                         {
    2401           0 :                             tmpP16[i] = add_sat( tmpP16[i], win[i] );
    2402           0 :                             move16();
    2403             :                         }
    2404             :                         /* copy new sub-window region not overlapping with previous window */
    2405           0 :                         Copy( win + L_ola, xn_buf16 + add( tmp1, shr( L_ola, 1 ) ), L_win );
    2406             :                     }
    2407             :                     /* To assure that no garbage values are copied to hLPDmem->Txnq */
    2408           0 :                     set16_fx( xn_buf16 + add( add( L_frame, tcx_offset ), shr( L_ola, 1 ) ),
    2409           0 :                               0, sub( sub( overlap, tcx_offset ), shr( L_ola, 1 ) ) );
    2410             :                 }
    2411           0 :                 ELSE IF( s_and( frame_cnt == 0, ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) )
    2412             :                 {
    2413             :                     /* special overlap attempt, two transforms, grouping into one window */
    2414             :                     Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    2415             :                     Word16 L_win, L_spec_TCX5, L_ola, w;
    2416             : 
    2417           0 :                     L_win = shr( L_frame, 1 );
    2418           0 :                     L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
    2419           0 :                     L_ola = hTcxCfg->tcx_mdct_window_min_length;
    2420           0 :                     move16();
    2421             : 
    2422           0 :                     set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    2423             : 
    2424             :                     /* Resize overlap (affect only asymmetric window)*/
    2425           0 :                     overlap = st->hTcxCfg->tcx_mdct_window_delay;
    2426             :                     /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
    2427           0 :                     TCX_MDCT_Inverse( spectrum, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2428           0 :                                       win + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode );
    2429             : 
    2430             :                     /* copy new sub-window region not overlapping with previous window */
    2431           0 :                     Copy( win + L_win, xn_buf16 + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
    2432             : 
    2433             :                     /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
    2434             : 
    2435           0 :                     TCX_MDCT_Inverse( spectrum + L_spec_TCX5, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2436           0 :                                       win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    2437             : 
    2438           0 :                     tmp4 = 0;
    2439           0 :                     move16();
    2440           0 :                     if ( tcx_offset < 0 )
    2441             :                     {
    2442           0 :                         tmp4 = negate( tcx_offset );
    2443             :                     }
    2444           0 :                     tcx_windowing_synthesis_current_frame( win,
    2445           0 :                                                            hTcxCfg->tcx_aldo_window_2,
    2446           0 :                                                            hTcxCfg->tcx_mdct_window_half,
    2447           0 :                                                            hTcxCfg->tcx_mdct_window_minimum,
    2448             :                                                            L_ola,
    2449           0 :                                                            hTcxCfg->tcx_mdct_window_half_length,
    2450           0 :                                                            hTcxCfg->tcx_mdct_window_min_length,
    2451             :                                                            0, /* left_rect */
    2452             :                                                            2, /* left_mode */
    2453             :                                                            hTcxEnc->acelp_zir,
    2454           0 :                                                            hTcxEnc->Txnq,
    2455             :                                                            NULL,
    2456             :                                                            Aq_old,
    2457           0 :                                                            hTcxCfg->tcx_mdct_window_trans,
    2458             :                                                            L_win,
    2459             :                                                            tmp4,
    2460             :                                                            1, /* not LPDmem->mode */
    2461             :                                                            0,
    2462             :                                                            0 );
    2463             : 
    2464             : 
    2465           0 :                     tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) );
    2466             : 
    2467           0 :                     tcx_windowing_synthesis_past_frame( tmpP16,
    2468           0 :                                                         hTcxCfg->tcx_aldo_window_1_trunc,
    2469           0 :                                                         hTcxCfg->tcx_mdct_window_half,
    2470           0 :                                                         hTcxCfg->tcx_mdct_window_minimum,
    2471             :                                                         L_ola,
    2472           0 :                                                         hTcxCfg->tcx_mdct_window_half_length,
    2473           0 :                                                         hTcxCfg->tcx_mdct_window_min_length,
    2474             :                                                         2 );
    2475             : 
    2476             :                     /* add part of current sub-window overlapping with previous window */
    2477           0 :                     FOR( i = 0; i < L_ola; i++ )
    2478             :                     {
    2479           0 :                         tmpP16[i] = add_sat( tmpP16[i], win[i] );
    2480           0 :                         move16();
    2481             :                     }
    2482             : 
    2483             :                     /* copy new sub-window region not overlapping with previous window */
    2484           0 :                     Copy( win + L_ola,
    2485           0 :                           xn_buf16 + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ),
    2486             :                           L_win );
    2487             : 
    2488             :                     /* extra folding-out on left side of win, for perfect reconstruction */
    2489           0 :                     FOR( w = overlap / 2; w < overlap; w++ )
    2490             :                     {
    2491           0 :                         xn_buf16[overlap - 1 - w] = negate( xn_buf16[w] );
    2492           0 :                         move16();
    2493             :                     }
    2494             : 
    2495           0 :                     tmp4 = 0;
    2496           0 :                     move16();
    2497           0 :                     if ( tcx_offset < 0 )
    2498             :                     {
    2499           0 :                         tmp4 = negate( tcx_offset );
    2500             :                     }
    2501           0 :                     tcx_windowing_synthesis_current_frame( xn_buf16,
    2502           0 :                                                            hTcxCfg->tcx_aldo_window_2,
    2503           0 :                                                            hTcxCfg->tcx_mdct_window_half,
    2504           0 :                                                            hTcxCfg->tcx_mdct_window_minimum,
    2505             :                                                            overlap,
    2506           0 :                                                            hTcxCfg->tcx_mdct_window_half_length,
    2507           0 :                                                            hTcxCfg->tcx_mdct_window_min_length,
    2508           0 :                                                            st->last_core == ACELP_CORE,
    2509             :                                                            0,
    2510             :                                                            hTcxEnc->acelp_zir,
    2511           0 :                                                            hTcxEnc->Txnq,
    2512             :                                                            NULL,
    2513             :                                                            Aq_old,
    2514           0 :                                                            hTcxCfg->tcx_mdct_window_trans,
    2515             :                                                            L_win,
    2516             :                                                            tmp4,
    2517           0 :                                                            st->last_core,
    2518             :                                                            0,
    2519             :                                                            0 );
    2520             :                 }
    2521             :                 ELSE /* default, i.e. maximum overlap, single transform, no grouping */
    2522             :                 {
    2523             : 
    2524           0 :                     TCX_MDCT_Inverse( spectrum, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2525           0 :                                       xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    2526             : 
    2527           0 :                     tmp1 = stop;
    2528           0 :                     move16();
    2529           0 :                     test();
    2530           0 :                     test();
    2531           0 :                     if ( ( frame_cnt > 0 ) && ( stop == 0 ) && ( st->last_core != ACELP_CORE ) )
    2532             :                     {
    2533           0 :                         tmp1 = 2;
    2534           0 :                         move16();
    2535             :                     }
    2536             : 
    2537           0 :                     tmp4 = 0;
    2538           0 :                     move16();
    2539           0 :                     if ( tcx_offset < 0 )
    2540             :                     {
    2541           0 :                         tmp4 = negate( tcx_offset );
    2542             :                     }
    2543           0 :                     tcx_windowing_synthesis_current_frame( xn_buf16,
    2544           0 :                                                            hTcxCfg->tcx_aldo_window_2,
    2545           0 :                                                            hTcxCfg->tcx_mdct_window_half,
    2546           0 :                                                            hTcxCfg->tcx_mdct_window_minimum,
    2547             :                                                            overlap, /*hTcxCfg->tcx_mdct_window_length*/
    2548           0 :                                                            hTcxCfg->tcx_mdct_window_half_length,
    2549           0 :                                                            hTcxCfg->tcx_mdct_window_min_length,
    2550           0 :                                                            st->last_core == ACELP_CORE,
    2551             :                                                            tmp1,
    2552             :                                                            hTcxEnc->acelp_zir,
    2553           0 :                                                            hTcxEnc->Txnq,
    2554             :                                                            NULL,
    2555             :                                                            Aq_old,
    2556           0 :                                                            hTcxCfg->tcx_mdct_window_trans,
    2557           0 :                                                            shr( L_frame_glob, 1 ),
    2558             :                                                            tmp4,
    2559           0 :                                                            st->last_core,
    2560             :                                                            0,
    2561             :                                                            0 );
    2562             : 
    2563             :                 } /* tcx_last_overlap_mode > 0 */
    2564             :             }
    2565             :             ELSE /* frame is TCX-20 or not TCX-only */
    2566             :             {
    2567         634 :                 IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    2568             :                 {
    2569             :                     Word32 tmp_buf[L_FRAME_PLUS];
    2570             :                     Word16 Q;
    2571             : 
    2572             :                     /* DCT */
    2573         596 :                     Q = sub( 31, *spectrum_e );
    2574         596 :                     edct_fx( spectrum, tmp_buf, L_frame, &Q );
    2575             : 
    2576             :                     /* scale by sqrt(L / NORM_MDCT_FACTOR) */
    2577         596 :                     tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
    2578         596 :                     tmp2 = 4;
    2579         596 :                     move16();
    2580         596 :                     tmp1 = Sqrt16( tmp1, &tmp2 );
    2581             : 
    2582      175508 :                     FOR( i = 0; i < L_frame; i++ )
    2583             :                     {
    2584      174912 :                         tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
    2585      174912 :                         move32();
    2586             :                     }
    2587         596 :                     Q = sub( Q, tmp2 );
    2588             : 
    2589             : 
    2590         596 :                     window_ola_fx( tmp_buf,
    2591             :                                    xn_buf16,
    2592             :                                    &Q,
    2593         596 :                                    hTcxEnc->old_out_fx,
    2594             :                                    &hTcxEnc->Q_old_out,
    2595             :                                    L_frame,
    2596         596 :                                    hTcxCfg->tcx_last_overlap_mode,
    2597         596 :                                    hTcxCfg->tcx_curr_overlap_mode,
    2598             :                                    0,
    2599             :                                    0,
    2600             :                                    NULL );
    2601             : 
    2602             :                     /* scale output */
    2603      175508 :                     FOR( i = 0; i < L_frame; i++ )
    2604             :                     {
    2605      174912 :                         xn_buf16[i] = shr_sat( xn_buf16[i], Q );
    2606      174912 :                         move16();
    2607             :                     }
    2608             : 
    2609         596 :                     aldo = 1;
    2610         596 :                     move16();
    2611             :                 }
    2612             :                 ELSE
    2613             :                 {
    2614             : 
    2615          38 :                     TCX_MDCT_Inverse( spectrum, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2616          38 :                                       xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    2617             : 
    2618             :                     /*-----------------------------------------------------------*
    2619             :                      * Windowing, overlap and add                                *
    2620             :                      *-----------------------------------------------------------*/
    2621             : 
    2622             :                     /* Window current frame */
    2623          38 :                     tmp4 = 0;
    2624          38 :                     move16();
    2625          38 :                     if ( tcx_offset < 0 )
    2626             :                     {
    2627          38 :                         tmp4 = negate( tcx_offset );
    2628             :                     }
    2629          76 :                     tcx_windowing_synthesis_current_frame( xn_buf16,
    2630          38 :                                                            hTcxCfg->tcx_aldo_window_2,
    2631          38 :                                                            hTcxCfg->tcx_mdct_window_half,
    2632          38 :                                                            hTcxCfg->tcx_mdct_window_minimum,
    2633             :                                                            overlap, /*hTcxCfg->tcx_mdct_window_length*/
    2634          38 :                                                            hTcxCfg->tcx_mdct_window_half_length,
    2635          38 :                                                            hTcxCfg->tcx_mdct_window_min_length,
    2636          38 :                                                            st->last_core == ACELP_CORE,
    2637          38 :                                                            hTcxCfg->tcx_last_overlap_mode, /*left mode*/
    2638             :                                                            hTcxEnc->acelp_zir,
    2639          38 :                                                            hTcxEnc->Txnq,
    2640             :                                                            NULL,
    2641             :                                                            Aq_old,
    2642          38 :                                                            hTcxCfg->tcx_mdct_window_trans,
    2643          38 :                                                            shr( L_frame_glob, 1 ),
    2644             :                                                            tmp4,
    2645          38 :                                                            st->last_core,
    2646             :                                                            0,
    2647             :                                                            0 );
    2648             :                 }
    2649             :             } /* TCX-10 and TCX-only */
    2650             : 
    2651             :             /* Window and overlap-add past frame if past frame is TCX */
    2652         634 :             test();
    2653         634 :             test();
    2654         634 :             test();
    2655         634 :             IF( ( st->last_core > ACELP_CORE ) && ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) )
    2656             :             {
    2657             : 
    2658           0 :                 IF( hTcxCfg->last_aldo != 0 )
    2659             :                 {
    2660           0 :                     tmp2 = add( hTcxEnc->Q_old_out, TCX_IMDCT_HEADROOM );
    2661             : 
    2662           0 :                     tmp1 = sub( overlap, hTcxCfg->tcx_mdct_window_min_length );
    2663           0 :                     FOR( i = 0; i < tmp1; i++ )
    2664             :                     {
    2665           0 :                         xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
    2666           0 :                         move16();
    2667             :                     }
    2668             : 
    2669             :                     /* fade truncated ALDO window */
    2670           0 :                     tmp1 = sub( overlap, shr( hTcxCfg->tcx_mdct_window_min_length, 1 ) );
    2671           0 :                     FOR( ; i < tmp1; i++ )
    2672             :                     {
    2673           0 :                         tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), hTcxCfg->tcx_mdct_window_minimum[i - overlap + hTcxCfg->tcx_mdct_window_min_length].v.re );
    2674           0 :                         xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    2675           0 :                         move16();
    2676             :                     }
    2677           0 :                     FOR( ; i < overlap; i++ )
    2678             :                     {
    2679           0 :                         tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im );
    2680           0 :                         xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    2681           0 :                         move16();
    2682             :                     }
    2683             : 
    2684           0 :                     FOR( ; i < L_frame; i++ )
    2685             :                     {
    2686           0 :                         xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    2687           0 :                         move16();
    2688             :                     }
    2689             :                 }
    2690             :                 ELSE
    2691             :                 {
    2692           0 :                     test();
    2693           0 :                     test();
    2694           0 :                     test();
    2695           0 :                     if ( ( frame_cnt > 0 ) && ( stop == 0 ) && ( hTcxCfg->tcx_curr_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) )
    2696             :                     {
    2697           0 :                         stop = 2; /* use minimum overlap between the two TCX-10 windows */
    2698           0 :                         move16();
    2699             :                     }
    2700             : 
    2701           0 :                     tmp1 = stop;
    2702           0 :                     move16();
    2703           0 :                     test();
    2704           0 :                     if ( ( stop == 0 ) || ( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
    2705             :                     {
    2706           0 :                         tmp1 = hTcxCfg->tcx_last_overlap_mode;
    2707           0 :                         move16();
    2708             :                     }
    2709             : 
    2710           0 :                     tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_mdct_window_half,
    2711           0 :                                                         hTcxCfg->tcx_mdct_window_minimum, overlap, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, tmp1 );
    2712             : 
    2713             :                     BASOP_SATURATE_WARNING_OFF_EVS;
    2714           0 :                     FOR( i = 0; i < overlap; i++ )
    2715             :                     {
    2716           0 :                         xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM );
    2717           0 :                         move16();
    2718             :                     }
    2719             : 
    2720           0 :                     IF( LT_16( i, L_frame ) )
    2721             :                     {
    2722           0 :                         FOR( ; i < L_frame; i++ )
    2723             :                         {
    2724           0 :                             xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    2725           0 :                             move16();
    2726             :                         }
    2727             :                     }
    2728             :                     BASOP_SATURATE_WARNING_ON_EVS;
    2729             :                 }
    2730             :             }
    2731             :             ELSE
    2732             :             {
    2733         634 :                 IF( aldo == 0 )
    2734             :                 {
    2735             :                     BASOP_SATURATE_WARNING_OFF_EVS;
    2736       14038 :                     FOR( i = 0; i < L_frame; i++ )
    2737             :                     {
    2738       14000 :                         xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    2739       14000 :                         move16();
    2740             :                     }
    2741             :                     BASOP_SATURATE_WARNING_ON_EVS;
    2742             :                 }
    2743             :             }
    2744             : 
    2745         634 :             test();
    2746         634 :             test();
    2747         634 :             test();
    2748         634 :             IF( ( aldo == 0 ) &&
    2749             :                 ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
    2750             :                   NE_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) )
    2751             :             {
    2752             :                 /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
    2753        3188 :                 FOR( i = 0; i < nz; i++ )
    2754             :                 {
    2755        3150 :                     hTcxEnc->old_out_fx[i] = shr( xn_buf16[L_frame - nz + i], TCX_IMDCT_HEADROOM );
    2756        3150 :                     move16();
    2757             :                 }
    2758          38 :                 Copy( xn_buf16 + L_frame, hTcxEnc->old_out_fx + nz, overlap );
    2759          38 :                 set16_fx( hTcxEnc->old_out_fx + nz + overlap, 0, nz );
    2760             : 
    2761          38 :                 tcx_windowing_synthesis_past_frame( hTcxEnc->old_out_fx + nz,
    2762          38 :                                                     hTcxCfg->tcx_aldo_window_1_trunc,
    2763          38 :                                                     hTcxCfg->tcx_mdct_window_half,
    2764          38 :                                                     hTcxCfg->tcx_mdct_window_minimum,
    2765             :                                                     overlap,
    2766          38 :                                                     hTcxCfg->tcx_mdct_window_half_length,
    2767          38 :                                                     hTcxCfg->tcx_mdct_window_min_length,
    2768          38 :                                                     hTcxCfg->tcx_curr_overlap_mode );
    2769             : 
    2770             :                 /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
    2771          38 :                 IF( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
    2772             :                 {
    2773        3188 :                     FOR( i = 0; i < nz; i++ )
    2774             :                     {
    2775        3150 :                         hTcxEnc->old_out_fx[nz + overlap + i] = shr( mult_r( xn_buf16[L_frame - 1 - i], hTcxCfg->tcx_aldo_window_1[nz - 1 - i] ), TCX_IMDCT_HEADROOM );
    2776        3150 :                         move16();
    2777             :                     }
    2778          38 :                     hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
    2779          38 :                     move16();
    2780             :                 }
    2781             : 
    2782          38 :                 hTcxEnc->Q_old_out = -TCX_IMDCT_HEADROOM;
    2783          38 :                 move16();
    2784             :             }
    2785         634 :             hTcxCfg->last_aldo = aldo;
    2786         634 :             move16();
    2787             : 
    2788             :             /* Update Txnq */
    2789         634 :             IF( hTcxCfg->last_aldo == 0 )
    2790             :             {
    2791          38 :                 Copy( xn_buf16 + L_frame, hTcxEnc->Txnq, overlap );
    2792             :             }
    2793             : 
    2794             : 
    2795             :             /* Output */
    2796         634 :             Copy( xn_buf16 + shr( overlap, 1 ) - tcx_offset, synth, L_frame_glob );
    2797             :         }
    2798             : 
    2799             :         /* Free internal TCX decoder stack memory */
    2800             :     }
    2801             : 
    2802             :     /* Update L_frame_past */
    2803         634 :     st->L_frame_past = L_frame;
    2804         634 :     move16();
    2805         634 : }
    2806             : 
    2807           0 : static Word16 DecideTonalSideInfo_fx(
    2808             :     Word32 spectrum[], // Qx
    2809             :     const Word16 L_frame_glob,
    2810             :     Word32 SFM2 )
    2811             : {
    2812             :     Word32 SFM, K, K2;
    2813             :     Word16 Tonal_SideInfo;
    2814             : 
    2815           0 :     SFM = SFM_Cal_fx( spectrum, s_min( 200, L_frame_glob ) );
    2816           0 :     test();
    2817           0 :     IF( LE_16( L_frame_glob, 256 ) )
    2818             :     {
    2819           0 :         K = 0x33333333;
    2820           0 :         move32();
    2821           0 :         K2 = 0xCCCCCCD;
    2822           0 :         move32();
    2823             :     }
    2824           0 :     ELSE IF( EQ_16( L_frame_glob, 320 ) || EQ_16( L_frame_glob, 512 ) )
    2825             :     {
    2826           0 :         K = 0x33333333;
    2827           0 :         move32();
    2828           0 :         K2 = 0xCCCCCCD;
    2829           0 :         move32();
    2830             :     }
    2831             :     ELSE /*FrameSize_Core == 640*/
    2832             :     {
    2833           0 :         K = 0x2CCCCCCD;
    2834           0 :         move32();
    2835           0 :         K2 = 0x51EB852;
    2836           0 :         move32();
    2837             :     }
    2838             : 
    2839             : 
    2840           0 :     Tonal_SideInfo = 0;
    2841           0 :     move16();
    2842           0 :     if ( LT_32( SFM, K ) )
    2843             :     {
    2844           0 :         Tonal_SideInfo = 1;
    2845           0 :         move16();
    2846             :     }
    2847           0 :     if ( LT_32( SFM2, K2 ) )
    2848             :     {
    2849           0 :         Tonal_SideInfo = 1;
    2850           0 :         move16();
    2851             :     }
    2852             : 
    2853           0 :     return Tonal_SideInfo;
    2854             : }
    2855             : 
    2856      897300 : void QuantizeTCXSpectrum_fx(
    2857             :     Encoder_State *st,           /* i  : state handle                            */
    2858             :     const Word16 frame_cnt,      /* i  : frame counter in the super_frame        Q0 */
    2859             :     Word32 *x_orig_fx,           /* i  : shaped MDCT spectrum                    Q(31-x_orig_e)*/
    2860             :     Word16 x_orig_e,             /* i  : exp of shaped MDCT spectrum                    */
    2861             :     Word16 *gainlpc_fx,          /* i  : FDNS gains                              Q(15-gainlpc_e)*/
    2862             :     Word16 *gainlpc_e,           /* i  : exp of FDNS gains                              */
    2863             :     const Word16 *Aqind,         /* i  : frame-independent quantized coefficients (M+1) Q0 */
    2864             :     const Word16 tnsSize,        /* i  : number of tns parameters put into prm   Q0 */
    2865             :     const Word16 nb_bits,        /* i  : bit budget                              Q0 */
    2866             :     const Word16 vad_hover_flag, /* i  : VAD hangover flag Q0 */
    2867             :     Word16 *pL_frameTCX,         /* o  : full frame length                       Q0 */
    2868             :     Word16 *pL_frame,            /* o  : frame length                            Q0 */
    2869             :     Word16 *pL_spec,             /* o  : length of the coded spectrum            Q0 */
    2870             :     Word16 *ptcx_offset,         /* o  : folding point offset relative to the end of the previous frame Q0 */
    2871             :     Word16 *pnoiseFillingBorder, /* o  : noise filling border                    Q0 */
    2872             :     Word32 spectrum_fx[],        /* o  : quantized MDCT spectrum                 Q(31-spectrum_e)*/
    2873             :     Word16 *spectrum_e,          /* o  : exp of quantized MDCT spectrum                 */
    2874             :     CONTEXT_HM_CONFIG *hm_cfg,   /* o  : Context-based harmonic model configuration */
    2875             :     Word16 *hm_active,           /* o  : flag indicating if the harmonic model is active */
    2876             :     Word16 lf_deemph_fact_fx[],  /* o  : low frequency deemphasis factors        Q14*/
    2877             :     Word16 *nf_seed,             /* o  : noise filling random seed               Q0*/
    2878             :     Word32 *ener_fx,             /* o  : energy of the quantized spectrum       Q(31-ener_e) */
    2879             :     Word16 *ener_e,              /* o  : exp of energy of the quantized spectrum        */
    2880             :     Word16 *gain_tcx_fx,         /* o  : global gain                            Q(15-gain_tcx_e) */
    2881             :     Word16 *gain_tcx_e,          /* o  : exp of global gain                          */
    2882             :     Word16 prm[]                 /* o  : tcx parameters                          Q0 */
    2883             : )
    2884             : {
    2885      897300 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    2886             :     Word16 i, L_frame, L_frameTCX, L_spec, tcx_offset;
    2887             :     Word16 noiseFillingBorder, LtpPitchLag, PeriodicityIndex;
    2888             :     Word16 lastnzCtxHm, lastnz;
    2889             :     Word16 stop;
    2890             :     Word16 nEncodedCtxHm, stopCtxHm, sqBitsCtxHm, Selector;
    2891             :     Word16 nEncoded, sqBits_noStop;
    2892             :     Word16 NumIndexBits, signaling_bits, sqTargetBits, sqBits, ctxHmBits, resQBits, resQTargetBits;
    2893             :     Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_lastnz, *sqQ, *prm_target;
    2894             :     Word32 total_brate, tmp32;
    2895             :     Word16 RelativeScore_fx, sqGain_fx, sqGain_e, gain_tcx_opt_fx, gain_tcx_opt_e;
    2896             :     Word16 tmp1, tmp2, max_iter, minSqGain;
    2897             :     CONTEXT_HM_CONFIG *phm_cfg;
    2898      897300 :     Word16 att_fx = 0;
    2899      897300 :     move16();
    2900             : 
    2901             :     /*-----------------------------------------------------------*
    2902             :      * Init                                                      *
    2903             :      *-----------------------------------------------------------*/
    2904             : 
    2905      897300 :     sqGain_fx = MAX_16;
    2906      897300 :     move16();
    2907      897300 :     sqGain_e = 0;
    2908      897300 :     move16();
    2909      897300 :     minSqGain = 0;
    2910      897300 :     move16();
    2911      897300 :     resQTargetBits = 0;
    2912      897300 :     move16();
    2913             : 
    2914      897300 :     NumIndexBits = 0;
    2915      897300 :     move16();
    2916      897300 :     sqBits = 0;
    2917      897300 :     move16();
    2918      897300 :     ctxHmBits = 0;
    2919      897300 :     move16();
    2920      897300 :     resQBits = 0;
    2921      897300 :     move16();
    2922      897300 :     prm_ltp = &prm[1 + NOISE_FILL_RANGES];
    2923      897300 :     prm_tns = prm_ltp + LTPSIZE;
    2924      897300 :     prm_hm = prm_tns + tnsSize;
    2925      897300 :     prm_lastnz = prm_hm + 2;
    2926      897300 :     sqQ = prm_hm + NPRM_CTX_HM;
    2927             : 
    2928      897300 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    2929             :     {
    2930      658779 :         total_brate = st->element_brate;
    2931             :     }
    2932             :     ELSE
    2933             :     {
    2934      238521 :         total_brate = st->total_brate;
    2935             :     }
    2936      897300 :     move32();
    2937             :     /*-----------------------------------------------------------*
    2938             :      * Init lengths                                              *
    2939             :      *-----------------------------------------------------------*/
    2940             : 
    2941             :     /******************************************************************************************/
    2942             : 
    2943      897300 :     L_frame = st->L_frame;
    2944      897300 :     move16();
    2945      897300 :     L_frameTCX = hTcxEnc->L_frameTCX;
    2946      897300 :     move16();
    2947      897300 :     L_spec = st->hTcxCfg->tcx_coded_lines;
    2948      897300 :     move16();
    2949      897300 :     tcx_offset = st->hTcxCfg->tcx_offset;
    2950      897300 :     move16();
    2951             : 
    2952      897300 :     IF( EQ_16( st->core, TCX_10_CORE ) )
    2953             :     {
    2954       33758 :         L_frame = shr( L_frame, 1 );
    2955       33758 :         L_frameTCX = shr( L_frameTCX, 1 );
    2956       33758 :         L_spec = shr( L_spec, 1 );
    2957             :     }
    2958      863542 :     ELSE IF( st->last_core == ACELP_CORE )
    2959             :     {
    2960        9258 :         st->hTcxCfg->last_aldo = 0;
    2961        9258 :         move16();
    2962        9258 :         L_frame = add( L_frame, tcx_offset );
    2963        9258 :         L_frameTCX = add( L_frameTCX, st->hTcxCfg->tcx_offsetFB );
    2964        9258 :         L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
    2965             : 
    2966        9258 :         IF( st->hTcxCfg->lfacNext < 0 )
    2967             :         {
    2968        9258 :             L_frame = sub( L_frame, st->hTcxCfg->lfacNext );
    2969        9258 :             L_frameTCX = sub( L_frameTCX, st->hTcxCfg->lfacNextFB );
    2970        9258 :             tcx_offset = st->hTcxCfg->lfacNext;
    2971        9258 :             move16();
    2972             :         }
    2973             :         ELSE
    2974             :         {
    2975           0 :             tcx_offset = 0;
    2976           0 :             move16();
    2977             :         }
    2978        9258 :         hTcxEnc->noiseLevelMemory_cnt = 0;
    2979        9258 :         move16();
    2980             :     }
    2981             : 
    2982      897300 :     *pL_frameTCX = L_frameTCX;
    2983      897300 :     move16();
    2984      897300 :     *pL_frame = L_frame;
    2985      897300 :     move16();
    2986      897300 :     *pL_spec = L_spec;
    2987      897300 :     move16();
    2988      897300 :     *ptcx_offset = tcx_offset;
    2989      897300 :     move16();
    2990             : 
    2991             :     /* target bitrate for SQ */
    2992      897300 :     sqTargetBits = sub( nb_bits, NBITS_TCX_GAIN + NBITS_NOISE_FILL_LEVEL );
    2993             : 
    2994      897300 :     IF( st->enablePlcWaveadjust )
    2995             :     {
    2996             :         Word16 L_frame_glob;
    2997           0 :         IF( EQ_16( st->core, TCX_20_CORE ) )
    2998             :         {
    2999           0 :             L_frame_glob = st->L_frame;
    3000           0 :             move16();
    3001             :         }
    3002             :         ELSE
    3003             :         {
    3004           0 :             L_frame_glob = shr( st->L_frame, 1 );
    3005             :         }
    3006           0 :         move16();
    3007           0 :         st->Tonal_SideInfo = DecideTonalSideInfo_fx( x_orig_fx, L_frame_glob, st->hTcxCfg->SFM2 );
    3008             :     }
    3009             : 
    3010             :     /* Start with the pre-shaped spectrum*/
    3011             : 
    3012             :     /*scaling buffer to Q31 if exp < 0 to avoid overflow while scaling constants*/
    3013      897300 :     IF( x_orig_e < 0 )
    3014             :     {
    3015         877 :         scale_sig32( x_orig_fx, L_spec, x_orig_e );
    3016         877 :         x_orig_e = 0;
    3017         877 :         move16();
    3018             :     }
    3019             : 
    3020      897300 :     Copy32( x_orig_fx, spectrum_fx, L_spec );
    3021      897300 :     *spectrum_e = x_orig_e;
    3022      897300 :     move16();
    3023             : 
    3024             :     /*-----------------------------------------------------------*
    3025             :      * Bandwidth Limitation                                      *
    3026             :      *-----------------------------------------------------------*/
    3027             : 
    3028      897300 :     noiseFillingBorder = L_spec;
    3029      897300 :     move16();
    3030      897300 :     IF( st->igf )
    3031             :     {
    3032      616937 :         noiseFillingBorder = st->hIGFEnc->infoStartLine;
    3033      616937 :         move16();
    3034             :     }
    3035      897300 :     *pnoiseFillingBorder = noiseFillingBorder;
    3036      897300 :     move16();
    3037             : 
    3038      897300 :     IF( st->igf )
    3039             :     {
    3040    92543027 :         FOR( i = st->hIGFEnc->infoStopLine; i < s_max( L_frame, L_frameTCX ); i++ )
    3041             :         {
    3042    91926090 :             spectrum_fx[i] = 0;
    3043    91926090 :             move32();
    3044             :         }
    3045             :     }
    3046             :     ELSE
    3047             :     {
    3048    16500123 :         FOR( i = noiseFillingBorder; i < s_max( L_frame, L_frameTCX ); i++ )
    3049             :         {
    3050    16219760 :             spectrum_fx[i] = 0;
    3051    16219760 :             move32();
    3052             :         }
    3053             :     }
    3054             : 
    3055             :     /*-----------------------------------------------------------*
    3056             :      * Quantization                                              *
    3057             :      *-----------------------------------------------------------*/
    3058             : 
    3059      897300 :     IF( !hTcxEnc->tcx_lpc_shaped_ari )
    3060             :     {
    3061             :         /* context based arithmetic coder */
    3062             : 
    3063             :         /* initialize signaling to default, i.e. context based AC is inactive */
    3064      879856 :         prm_hm[0] = 0;
    3065      879856 :         move16();
    3066      879856 :         prm_hm[1] = -1;
    3067      879856 :         move16();
    3068             : 
    3069             :         /* Fast estimation of the scalar quantizer step size */
    3070      879856 :         test();
    3071      879856 :         IF( st->hTcxCfg->ctx_hm && ( st->last_core != ACELP_CORE ) )
    3072      181301 :         {
    3073      181301 :             LtpPitchLag = -1;
    3074      181301 :             move16();
    3075             : 
    3076      181301 :             test();
    3077      181301 :             IF( ( st->tcxonly == 0 ) && ( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) ) )
    3078             :             {
    3079       50697 :                 tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
    3080       50697 :                 tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
    3081       50697 :                 LtpPitchLag = div_l( tmp32, tmp1 );
    3082             :             }
    3083             : 
    3084      181301 :             ctxHmBits = add( ctxHmBits, 1 );       /* ContextHM flag */
    3085      181301 :             sqTargetBits = sub( sqTargetBits, 1 ); /* ContextHM flag */
    3086             : 
    3087             :             Word16 LtpGain;
    3088      181301 :             IF( hTcxEnc->tcxltp )
    3089             :             {
    3090      108291 :                 LtpGain = hTcxEnc->tcxltp_gain;
    3091             :             }
    3092             :             ELSE
    3093             :             {
    3094       73010 :                 LtpGain = -MAX_16;
    3095             :             }
    3096      181301 :             move16();
    3097      181301 :             PeriodicityIndex = SearchPeriodicityIndex_fx( spectrum_fx, NULL, L_spec, sqTargetBits, LtpPitchLag, LtpGain, &RelativeScore_fx );
    3098             : 
    3099      181301 :             NumIndexBits = CountIndexBits( (Word16) GE_16( L_spec, (Word16) 256 ), PeriodicityIndex );
    3100             : 
    3101      181301 :             IF( st->element_mode > EVS_MONO )
    3102             :             {
    3103      181301 :                 ConfigureContextHm( L_spec, sub( sqTargetBits, NumIndexBits ), PeriodicityIndex, LtpPitchLag, hm_cfg );
    3104             :             }
    3105             :             ELSE
    3106             :             {
    3107           0 :                 ConfigureContextHm( L_spec, sqTargetBits, PeriodicityIndex, LtpPitchLag, hm_cfg );
    3108             :             }
    3109             : 
    3110             :             /* Quantize original spectrum */
    3111      181301 :             sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, ( mult( hTcxEnc->tcx_target_bits_fac, shl( sqTargetBits, 1 ) ) ), L_spec, &sqGain_e );
    3112             : 
    3113      181301 :             tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    3114             : 
    3115             :             /* Estimate original bitrate */
    3116      181301 :             stop = 0;
    3117      181301 :             move16();
    3118      181301 :             IF( st->element_mode > EVS_MONO )
    3119             :             {
    3120      181301 :                 sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    3121             :             }
    3122             :             ELSE
    3123             :             {
    3124           0 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, NULL );
    3125             :             }
    3126             : 
    3127             :             /* Estimate context mapped bitrate */
    3128      181301 :             stopCtxHm = 0;
    3129      181301 :             move16();
    3130             : 
    3131             :             /* Context Mapping */
    3132      181301 :             IF( st->element_mode > EVS_MONO )
    3133             :             {
    3134      181301 :                 sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
    3135             :             }
    3136             :             ELSE
    3137             :             {
    3138           0 :                 sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
    3139             :             }
    3140             : 
    3141             :             /* Decide whether or not to use context mapping */
    3142      181301 :             Selector = sub( s_max( stop, sqBits ), ( add( s_max( stopCtxHm, sqBitsCtxHm ), NumIndexBits ) ) );
    3143             : 
    3144      181301 :             test();
    3145      181301 :             test();
    3146      181301 :             IF( GT_16( Selector, 2 ) || ( LE_16( abs_s( Selector ), 2 ) && LT_16( kCtxHmOlRSThr, RelativeScore_fx ) ) )
    3147             :             {
    3148             :                 /* CtxHm is likely better */
    3149       12411 :                 sqTargetBits = sub( sqTargetBits, NumIndexBits );
    3150       12411 :                 ctxHmBits = add( ctxHmBits, NumIndexBits );
    3151       12411 :                 prm_hm[0] = 1;
    3152       12411 :                 move16();
    3153       12411 :                 prm_hm[1] = PeriodicityIndex;
    3154       12411 :                 move16();
    3155       12411 :                 *prm_lastnz = lastnzCtxHm;
    3156       12411 :                 move16();
    3157       12411 :                 sqBits_noStop = sqBits = sqBitsCtxHm;
    3158       12411 :                 move16();
    3159       12411 :                 move16();
    3160       12411 :                 nEncoded = nEncodedCtxHm;
    3161       12411 :                 move16();
    3162       12411 :                 stop = stopCtxHm;
    3163       12411 :                 move16();
    3164             :             }
    3165             :             ELSE
    3166             :             {
    3167             :                 /* Original is better or not much difference */
    3168      168890 :                 prm_hm[0] = 0;
    3169      168890 :                 move16();
    3170      168890 :                 prm_hm[1] = PeriodicityIndex;
    3171      168890 :                 move16();
    3172      168890 :                 *prm_lastnz = lastnz;
    3173      168890 :                 move16();
    3174      168890 :                 PeriodicityIndex = -1;
    3175      168890 :                 move16();
    3176             : 
    3177      168890 :                 sqBits_noStop = sqBits;
    3178      168890 :                 move16();
    3179             :             }
    3180             : 
    3181      181301 :             if ( stop != 0 )
    3182             :             {
    3183       66734 :                 sqBits = stop;
    3184       66734 :                 move16();
    3185             :             }
    3186             :         }
    3187             :         ELSE
    3188             :         {
    3189             :             /* no context hm*/
    3190      698555 :             PeriodicityIndex = -1;
    3191      698555 :             move16();
    3192             : 
    3193      698555 :             IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    3194             :             {
    3195      658779 :                 Word16 scale = sub( L_norm_arr( spectrum_fx, L_spec ), 2 );
    3196      658779 :                 scale_sig32( spectrum_fx, L_spec, scale );
    3197      658779 :                 *spectrum_e = sub( *spectrum_e, scale );
    3198      658779 :                 sqGain_fx = SQ_gain_estimate_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e );
    3199             :             }
    3200             :             ELSE
    3201             :             {
    3202       39776 :                 sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e );
    3203             :             }
    3204             :             /* Quantize spectrum */
    3205      698555 :             tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    3206             : 
    3207             :             /* Estimate bitrate */
    3208      698555 :             stop = 0;
    3209      698555 :             move16();
    3210             : 
    3211      698555 :             IF( st->element_mode > EVS_MONO )
    3212             :             {
    3213      698555 :                 sqBits_noStop = sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    3214      698555 :                 move16();
    3215             :             }
    3216             :             ELSE
    3217             :             {
    3218           0 :                 sqBits_noStop = sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, NULL );
    3219           0 :                 move16();
    3220             :             }
    3221             : 
    3222      698555 :             if ( stop != 0 )
    3223             :             {
    3224      363126 :                 sqBits = stop;
    3225      363126 :                 move16();
    3226             :             }
    3227             :         } /* end of if (ctx_hm) */
    3228             : 
    3229             :         /* Adjust correction factor */
    3230      879856 :         tmp1 = sqBits;
    3231      879856 :         move16();
    3232             : 
    3233      879856 :         if ( s_and( L_spec, sub( L_spec, 1 ) ) == 0 ) /* power-of-2 */
    3234             :         {
    3235           0 :             tmp1 = add( tmp1, 1 );
    3236             :         }
    3237             : 
    3238      879856 :         tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 );
    3239             :         BASOP_SATURATE_WARNING_OFF_EVS
    3240      879856 :         hTcxEnc->tcx_target_bits_fac = shl_sat( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2 );
    3241             :         BASOP_SATURATE_WARNING_ON_EVS
    3242             : 
    3243      879856 :         if ( GT_16( hTcxEnc->tcx_target_bits_fac, 20480 /*1.25 in Q14*/ ) )
    3244             :         {
    3245       90034 :             hTcxEnc->tcx_target_bits_fac = 20480;
    3246       90034 :             move16();
    3247             :         }
    3248      879856 :         if ( LT_16( hTcxEnc->tcx_target_bits_fac, 12288 /*.75 in Q14*/ ) )
    3249             :         {
    3250       57721 :             hTcxEnc->tcx_target_bits_fac = 12288;
    3251       57721 :             move16();
    3252             :         }
    3253             : 
    3254             :         /* Refine quantizer step size with a rate-control-loop (optional) */
    3255      879856 :         phm_cfg = NULL;
    3256      879856 :         move16();
    3257      879856 :         if ( PeriodicityIndex >= 0 )
    3258             :         {
    3259       12411 :             phm_cfg = hm_cfg;
    3260       12411 :             move16();
    3261             :         }
    3262             : 
    3263      879856 :         max_iter = 4;
    3264      879856 :         move16();
    3265      879856 :         if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    3266             :         {
    3267      658779 :             max_iter = 2;
    3268      658779 :             move16();
    3269             :         }
    3270      879856 :         sqBits = tcx_scalar_quantization_rateloop_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, &sqGain_fx, &sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, prm_lastnz, /* lastnz */ sqTargetBits, &nEncoded, &stop, sqBits_noStop, sqBits, st->hTcxCfg->tcxRateLoopOpt, st->tcxonly, phm_cfg, max_iter, st->element_mode );
    3271             : 
    3272      879856 :         IF( ctxHmBits > 0 )
    3273             :         {
    3274             :             /* Mapping tool is enabled */
    3275             :             /* Truncate spectrum */
    3276      181301 :             FOR( i = nEncoded; i < L_spec; i++ )
    3277             :             {
    3278      179833 :                 IF( st->element_mode > EVS_MONO )
    3279             :                 {
    3280      179833 :                     break;
    3281             :                 }
    3282             :                 ELSE
    3283             :                 {
    3284           0 :                     sqQ[i] = 0;
    3285           0 :                     move16();
    3286             :                 }
    3287             :             }
    3288             : 
    3289      181301 :             IF( PeriodicityIndex >= 0 )
    3290             :             {
    3291             :                 /* Mapping is used */
    3292             :                 /* Estimate non-mapped bitrate */
    3293       12411 :                 stopCtxHm = 1;
    3294       12411 :                 move16();
    3295       12411 :                 IF( st->element_mode > EVS_MONO )
    3296             :                 {
    3297             :                     /* Fix: Use updated value for target bits (sqTargetBits + NumIndexBits) before computing non-mapped estimate */
    3298       12411 :                     sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits + NumIndexBits, &stopCtxHm, 0, NULL );
    3299             :                 }
    3300             :                 ELSE
    3301             :                 {
    3302           0 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits, &stopCtxHm, NULL );
    3303             :                 }
    3304             : 
    3305             :                 /* Decide whether or not to revert mapping */
    3306       12411 :                 Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    3307             : 
    3308       12411 :                 IF( st->element_mode > EVS_MONO )
    3309             :                 {
    3310       12411 :                     test();
    3311       12411 :                     test();
    3312       12411 :                     IF( ( stopCtxHm == 0 && Selector > 0 ) || stop ) /* If overflow occured with mapped, select non-mapped */
    3313             :                     {
    3314             :                         /* Non-mapped is better */
    3315         481 :                         sqTargetBits = add( sqTargetBits, NumIndexBits );
    3316         481 :                         ctxHmBits = sub( ctxHmBits, NumIndexBits );
    3317         481 :                         prm_hm[0] = 0;
    3318         481 :                         move16();
    3319         481 :                         *prm_lastnz = lastnz;
    3320         481 :                         move16();
    3321         481 :                         PeriodicityIndex = -1;
    3322         481 :                         move16();
    3323         481 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    3324         481 :                         move16();
    3325         481 :                         move16();
    3326         481 :                         nEncoded = nEncodedCtxHm;
    3327         481 :                         move16();
    3328         481 :                         stop = stopCtxHm;
    3329         481 :                         move16();
    3330             :                     }
    3331             :                 }
    3332             :                 ELSE
    3333             :                 {
    3334           0 :                     test();
    3335           0 :                     IF( stopCtxHm == 0 && Selector > 0 )
    3336             :                     {
    3337             :                         /* Non-mapped is better */
    3338           0 :                         sqTargetBits = add( sqTargetBits, NumIndexBits );
    3339           0 :                         ctxHmBits = sub( ctxHmBits, NumIndexBits );
    3340           0 :                         prm_hm[0] = 0;
    3341           0 :                         move16();
    3342           0 :                         *prm_lastnz = lastnz;
    3343           0 :                         move16();
    3344           0 :                         PeriodicityIndex = -1;
    3345           0 :                         move16();
    3346           0 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    3347           0 :                         move16();
    3348           0 :                         move16();
    3349           0 :                         nEncoded = nEncodedCtxHm;
    3350           0 :                         move16();
    3351           0 :                         stop = stopCtxHm;
    3352           0 :                         move16();
    3353             :                     }
    3354             :                 }
    3355             :             }
    3356             :             ELSE
    3357             :             {
    3358             :                 /* Mapping is not used */
    3359      168890 :                 IF( st->element_mode > EVS_MONO )
    3360             :                 {
    3361             :                     /* Truncate Spectrum */
    3362    87708044 :                     FOR( i = nEncoded; i < L_spec; i++ )
    3363             :                     {
    3364    87539154 :                         sqQ[i] = 0;
    3365    87539154 :                         move16();
    3366             :                     }
    3367             :                 }
    3368             :                 /* Estimate mapped bitrate */
    3369      168890 :                 stopCtxHm = 1;
    3370      168890 :                 move16();
    3371      168890 :                 IF( st->element_mode > EVS_MONO )
    3372             :                 {
    3373      168890 :                     sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
    3374             :                 }
    3375             :                 ELSE
    3376             :                 {
    3377           0 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
    3378             :                 }
    3379             : 
    3380             :                 /* Decide whether or not to use mapping */
    3381      168890 :                 Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    3382      168890 :                 test();
    3383      168890 :                 IF( stopCtxHm == 0 && Selector > 0 )
    3384             :                 {
    3385             :                     /* Mapped is better */
    3386         767 :                     sqTargetBits = sub( sqTargetBits, NumIndexBits );
    3387         767 :                     ctxHmBits = add( ctxHmBits, NumIndexBits );
    3388         767 :                     prm_hm[0] = 1;
    3389         767 :                     move16();
    3390         767 :                     *prm_lastnz = lastnzCtxHm;
    3391         767 :                     move16();
    3392         767 :                     PeriodicityIndex = prm_hm[1];
    3393         767 :                     move16();
    3394         767 :                     sqBits_noStop = sqBits = sqBitsCtxHm;
    3395         767 :                     move16();
    3396         767 :                     move16();
    3397         767 :                     nEncoded = nEncodedCtxHm;
    3398         767 :                     move16();
    3399         767 :                     stop = stopCtxHm;
    3400         767 :                     move16();
    3401             :                 }
    3402             :             }
    3403             :         }
    3404             : 
    3405             :         /* Limit low sqGain for avoiding saturation of the gain quantizer*/
    3406             :         /*(float) sqrt( (float) NORM_MDCT_FACTOR / (float) L_spec ) in Q14 */
    3407      879856 :         SWITCH( L_spec )
    3408             :         {
    3409           0 :             case 80:
    3410           0 :                 minSqGain = 23170;
    3411           0 :                 BREAK;
    3412           0 :             case 100:
    3413           0 :                 minSqGain = 20724;
    3414           0 :                 BREAK;
    3415        2446 :             case 160:
    3416        2446 :                 minSqGain = 16384;
    3417        2446 :                 BREAK;
    3418           0 :             case 200:
    3419           0 :                 minSqGain = 14654;
    3420           0 :                 BREAK;
    3421           0 :             case 240:
    3422           0 :                 minSqGain = 13377;
    3423           0 :                 BREAK;
    3424           0 :             case 300:
    3425           0 :                 minSqGain = 11965;
    3426           0 :                 BREAK;
    3427       77539 :             case 320:
    3428       77539 :                 minSqGain = 11585;
    3429       77539 :                 BREAK;
    3430         444 :             case 400:
    3431         444 :                 minSqGain = 10362;
    3432         444 :                 BREAK;
    3433       23220 :             case 480:
    3434       23220 :                 minSqGain = 9459;
    3435       23220 :                 BREAK;
    3436           0 :             case 600:
    3437           0 :                 minSqGain = 8461;
    3438           0 :                 BREAK;
    3439      215168 :             case 640:
    3440      215168 :                 minSqGain = 8192;
    3441      215168 :                 BREAK;
    3442        3148 :             case 800:
    3443        3148 :                 minSqGain = 7327;
    3444        3148 :                 BREAK;
    3445      553875 :             case 960:
    3446      553875 :                 minSqGain = 6689;
    3447      553875 :                 BREAK;
    3448        4016 :             case 1200:
    3449        4016 :                 minSqGain = 5983;
    3450        4016 :                 BREAK;
    3451           0 :             case 1440:
    3452           0 :                 minSqGain = 5461;
    3453           0 :                 BREAK;
    3454           0 :             case 1800:
    3455           0 :                 minSqGain = 4885;
    3456           0 :                 BREAK;
    3457           0 :             case 2048:
    3458           0 :                 minSqGain = 4579;
    3459           0 :                 BREAK;
    3460           0 :             default:
    3461           0 :                 assert( 0 );
    3462             :         }
    3463      879856 :         move16();
    3464      879856 :         Word16 shift_tmp = s_max( sqGain_e, 1 );
    3465      879856 :         test();
    3466      879856 :         IF( LT_16( st->hTcxCfg->tcxRateLoopOpt, 3 ) && LT_16( shl( sqGain_fx, sub( sqGain_e, shift_tmp ) ), shl( minSqGain, sub( 1, shift_tmp ) ) ) )
    3467             :         {
    3468        5028 :             sqGain_fx = minSqGain;
    3469        5028 :             move16();
    3470        5028 :             sqGain_e = 1;
    3471        5028 :             move16();
    3472             : 
    3473        5028 :             tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    3474        5028 :             stop = 1;
    3475        5028 :             IF( st->element_mode > EVS_MONO )
    3476             :             {
    3477             :                 /* Ensure non-mapped estimation is used for limiting low sqGain considering that this refinement occurs very rarely */
    3478        5028 :                 PeriodicityIndex = -1;
    3479        5028 :                 move16();
    3480        5028 :                 IF( prm_hm[0] == 1 )
    3481             :                 {
    3482           0 :                     prm_hm[0] = 0;
    3483           0 :                     move16();
    3484           0 :                     sqTargetBits = add( sqTargetBits, NumIndexBits );
    3485           0 :                     ctxHmBits = sub( ctxHmBits, NumIndexBits );
    3486             :                 }
    3487        5028 :                 sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    3488             :             }
    3489             :             ELSE
    3490             :             {
    3491           0 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, PeriodicityIndex >= 0 ? hm_cfg : NULL );
    3492             :             }
    3493             :         }
    3494             : 
    3495             :         /* Truncate spectrum (for CBR) */
    3496      879856 :         IF( stop )
    3497             :         {
    3498    66722930 :             FOR( i = nEncoded; i < L_spec; i++ )
    3499             :             {
    3500    66594088 :                 sqQ[i] = 0;
    3501    66594088 :                 move16();
    3502             :             }
    3503             :         }
    3504             : 
    3505             :         /* Save quantized Values */
    3506      879856 :         *nf_seed = 0;
    3507      879856 :         move16();
    3508   714172016 :         FOR( i = 0; i < L_spec; i++ )
    3509             :         {
    3510   713292160 :             spectrum_fx[i] = (Word32) sqQ[i];
    3511   713292160 :             move32();
    3512             :             /* noise filling seed */
    3513   713292160 :             *nf_seed = (Word16) L_add( *nf_seed, L_mult0( abs_s( sqQ[i] ), shl( i, 1 ) ) );
    3514   713292160 :             move16();
    3515             :         }
    3516             : 
    3517      879856 :         Word64 tmp64 = 0;
    3518   714172016 :         FOR( i = 0; i < L_spec; i++ )
    3519             :         {
    3520   713292160 :             spectrum_fx[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) );
    3521   713292160 :             move32();
    3522             :             /* noise filling seed */
    3523   713292160 :             tmp64 = W_mac_16_16( tmp64, abs_s( sqQ[i] ), i );
    3524             :         }
    3525      879856 :         *spectrum_e = SPEC_EXP_DEC;
    3526      879856 :         move16();
    3527             : 
    3528      879856 :         assert( W_extract_h( tmp64 ) == 0 );
    3529      879856 :         *nf_seed = extract_l( W_extract_l( tmp64 ) );
    3530             :     }
    3531             :     ELSE
    3532             :     {
    3533             :         /* low rates: envelope based arithmetic coder */
    3534             : 
    3535       17444 :         AdaptLowFreqEmph_fx( spectrum_fx, *spectrum_e, NULL, 0, 0, 1, gainlpc_fx, gainlpc_e, L_frame );
    3536             : 
    3537       17444 :         prm_target = sqQ;
    3538       17444 :         sqQ = prm_target + 1;
    3539             : 
    3540       17444 :         LtpPitchLag = -1;
    3541       17444 :         move16();
    3542             : 
    3543       17444 :         IF( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) )
    3544             :         {
    3545        7686 :             tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
    3546        7686 :             tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
    3547        7686 :             LtpPitchLag = div_l( tmp32, tmp1 );
    3548             :         }
    3549             : 
    3550       17444 :         Word8 tmp8 = 1;
    3551       17444 :         move16();
    3552       17444 :         if ( st->last_core == ACELP_CORE )
    3553             :         {
    3554        1650 :             tmp8 = 0;
    3555        1650 :             move16();
    3556             :         }
    3557       17444 :         Word16 low_complexiety = 0;
    3558       17444 :         move16();
    3559       17444 :         if ( GT_16( st->bwidth, WB ) )
    3560             :         {
    3561       16155 :             low_complexiety = 1;
    3562       16155 :             move16();
    3563             :         }
    3564       17444 :         tcx_arith_encode_envelope_ivas_fx( spectrum_fx, spectrum_e, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, tmp8, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, low_complexiety );
    3565             : 
    3566       17444 :         sqTargetBits = sub( sqTargetBits, signaling_bits );
    3567       17444 :         *prm_target = sqTargetBits;
    3568       17444 :         move16();
    3569             : 
    3570             :         /* Noise filling seed */
    3571       17444 :         Word64 seed = 0;
    3572       17444 :         move64();
    3573     3649220 :         FOR( i = 0; i < noiseFillingBorder; ++i )
    3574             :         {
    3575             :             /* *nf_seed += (int16_t) ( abs( (int16_t) spectrum[i] ) * i * 2 ); */
    3576     3631776 :             seed = W_mac_32_32( seed, L_abs( spectrum_fx[i] ), i ); // exp: spectrum_e
    3577             :         }
    3578       17444 :         *nf_seed = extract_l( W_extract_l( W_shr( seed, sub( 31, *spectrum_e ) ) ) ); // Q0
    3579       17444 :         move16();
    3580             :     }
    3581             : 
    3582      897300 :     *hm_active = prm_hm[0];
    3583      897300 :     move16();
    3584             : 
    3585             :     /*-----------------------------------------------------------*
    3586             :      * Compute optimal TCX gain.                                 *
    3587             :      *-----------------------------------------------------------*/
    3588             : 
    3589      897300 :     IF( lf_deemph_fact_fx != NULL )
    3590             :     {
    3591             :         /* initialize LF deemphasis factors in lf_deemph_fact */
    3592   199031401 :         FOR( i = 0; i < L_spec; i++ )
    3593             :         {
    3594   198792880 :             lf_deemph_fact_fx[i] = ONE_IN_Q14;
    3595   198792880 :             move16();
    3596             :         }
    3597             :     }
    3598             : 
    3599      897300 :     IF( !st->tcxonly )
    3600             :     {
    3601      129573 :         AdaptLowFreqDeemph( spectrum_fx, *spectrum_e, hTcxEnc->tcx_lpc_shaped_ari, gainlpc_fx, gainlpc_e, L_frame, lf_deemph_fact_fx );
    3602             :     }
    3603             : 
    3604      897300 :     assert( x_orig_fx != spectrum_fx );
    3605             : 
    3606      897300 :     tcx_get_gain( x_orig_fx, x_orig_e, spectrum_fx, *spectrum_e, L_spec, &gain_tcx_opt_fx, &gain_tcx_opt_e, ener_fx, ener_e );
    3607             : 
    3608      897300 :     IF( gain_tcx_opt_fx <= 0 )
    3609             :     {
    3610        2383 :         gain_tcx_opt_fx = sqGain_fx;
    3611        2383 :         move16();
    3612        2383 :         gain_tcx_opt_e = sqGain_e;
    3613        2383 :         move16();
    3614             :     }
    3615      897300 :     *gain_tcx_fx = gain_tcx_opt_fx;
    3616      897300 :     move16();
    3617      897300 :     *gain_tcx_e = gain_tcx_opt_e;
    3618      897300 :     move16();
    3619             : 
    3620      897300 :     test();
    3621      897300 :     IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) )
    3622             :     {
    3623       14453 :         calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag );
    3624       14453 :         *gain_tcx_fx = mult( *gain_tcx_fx, att_fx );
    3625       14453 :         move16();
    3626             :     }
    3627             : 
    3628             :     /*-----------------------------------------------------------*
    3629             :      * Quantize TCX gain                                         *
    3630             :      *-----------------------------------------------------------*/
    3631             : 
    3632             :     /*  gain quantization here in case of VBR unvoiced coding; fixes problems of uninitialized global gain values */
    3633      897300 :     test();
    3634      897300 :     IF( GE_32( total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    3635             :     {
    3636      864127 :         QuantizeGain( L_spec, gain_tcx_fx, gain_tcx_e, &prm[0] );
    3637             :     }
    3638             : 
    3639             :     /*-----------------------------------------------------------*
    3640             :      * Residual Quantization                                     *
    3641             :      *-----------------------------------------------------------*/
    3642             : 
    3643      897300 :     IF( st->hTcxCfg->resq )
    3644             :     {
    3645      396064 :         resQTargetBits = sub( sqTargetBits, sqBits );
    3646             : 
    3647      396064 :         IF( hTcxEnc->tcx_lpc_shaped_ari )
    3648             :         {
    3649             :             /* envelope based arithmetic coder */
    3650             :             Word16 *prm_resq;
    3651             : 
    3652       17444 :             prm_resq = sqQ + sub( sqTargetBits, resQTargetBits );
    3653             : 
    3654       17444 :             resQBits = tcx_ari_res_Q_spec_ivas_fx( x_orig_fx, x_orig_e, hm_cfg->indexBuffer, spectrum_fx, *spectrum_e, L_spec, *gain_tcx_fx, *gain_tcx_e, prm_resq, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, lf_deemph_fact_fx );
    3655             : 
    3656             :             /* Transmit zeros when there bits remain after RESQ */
    3657       18649 :             FOR( i = resQBits; i < resQTargetBits; ++i )
    3658             :             {
    3659        1205 :                 prm_resq[i] = 0;
    3660        1205 :                 move16();
    3661             :             }
    3662             :         }
    3663             :         ELSE
    3664             :         {
    3665             :             /* context based arithmetic coder */
    3666      378620 :             resQBits = tcx_res_Q_gain_fx( gain_tcx_opt_fx, gain_tcx_opt_e, gain_tcx_fx, gain_tcx_e, sqQ + L_spec, resQTargetBits );
    3667      378620 :             IF( st->tcxonly )
    3668             :             {
    3669      266491 :                 resQBits = tcx_res_Q_spec_ivas_fx( x_orig_fx, x_orig_e, spectrum_fx, *spectrum_e, L_spec, *gain_tcx_fx, *gain_tcx_e, sqQ + L_spec, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, NULL );
    3670             :             }
    3671             :             ELSE
    3672             :             {
    3673      112129 :                 resQBits = tcx_res_Q_spec_ivas_fx( x_orig_fx, x_orig_e, spectrum_fx, *spectrum_e, L_spec, *gain_tcx_fx, *gain_tcx_e, sqQ + L_spec, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, lf_deemph_fact_fx );
    3674             :             }
    3675             :         }
    3676             :     }
    3677             : 
    3678      897300 :     tmp1 = norm_s( *gain_tcx_fx );
    3679      897300 :     *gain_tcx_fx = shl( *gain_tcx_fx, tmp1 );
    3680      897300 :     move16();
    3681      897300 :     *gain_tcx_e = sub( *gain_tcx_e, tmp1 );
    3682      897300 :     move16();
    3683             : 
    3684             :     /*-----------------------------------------------------------*
    3685             :      * ALFE tcx only bitrates                                    *
    3686             :      *-----------------------------------------------------------*/
    3687             : 
    3688      897300 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    3689             :     {
    3690      238521 :         IF( st->tcxonly )
    3691             :         {
    3692      108948 :             test();
    3693      108948 :             test();
    3694      108948 :             IF( hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !hTcxEnc->fUseTns[frame_cnt] )
    3695             :             {
    3696        3730 :                 PsychAdaptLowFreqDeemph( spectrum_fx, gainlpc_fx, gainlpc_e, NULL );
    3697             :             }
    3698             :         }
    3699             :     }
    3700             : 
    3701      897300 :     return;
    3702             : }
    3703             : 
    3704         634 : void coder_tcx_fx(
    3705             :     Word16 n,
    3706             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    3707             :     Word16 A[],                /* input: quantized coefficients NxAz_q[M+1] */
    3708             :     Word16 Aqind[],            /* input: frame-independent quantized coefficients (M+1) */
    3709             :     Word16 synth[],            /*Qx*/
    3710             :     Word16 L_frame_glob,       /* input: frame length             */
    3711             :     Word16 L_frameTCX_glob,
    3712             :     Word16 L_spec,
    3713             :     Word16 nb_bits,     /*input: bit budget*/
    3714             :     Word8 tcxonly,      /*input: only TCX flag*/
    3715             :     Word32 spectrum[],  /* i/o: MDCT spectrum Q(31-spectrum_e)*/
    3716             :     Word16 *spectrum_e, /* i/o: MDCT spectrum exponent               */
    3717             :     Word16 prm[],       /* output: tcx parameters          */
    3718             :     Encoder_State *st,
    3719             :     CONTEXT_HM_CONFIG *hm_cfg )
    3720             : {
    3721             :     Word16 L_frame;
    3722             :     Word16 left_overlap, right_overlap;
    3723             :     Word16 tnsSize; /* number of tns parameters put into prm */
    3724             :     Word16 tnsBits; /* number of tns bits in the frame */
    3725             :     Word16 ltpBits;
    3726             :     Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
    3727             :     Word16 win[N_MAX + L_MDCT_OVLP_MAX];
    3728             :     Word32 powerSpec[N_MAX];
    3729             :     Word16 powerSpec_e;
    3730             :     Word16 winMDST[N_MAX + L_MDCT_OVLP_MAX];
    3731             :     Word16 *pWinMDST;
    3732             :     Word16 left_overlap_mode, right_overlap_mode;
    3733         634 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    3734             : 
    3735         634 :     left_overlap = right_overlap = -1;
    3736         634 :     move16();
    3737         634 :     move16();
    3738         634 :     tnsSize = 0;
    3739         634 :     move16();
    3740         634 :     tnsBits = 0;
    3741         634 :     move16();
    3742         634 :     ltpBits = 0;
    3743         634 :     move16();
    3744             : 
    3745         634 :     L_frame = L_frameTCX_glob;
    3746         634 :     move16();
    3747             : 
    3748             :     /*-----------------------------------------------------------*
    3749             :      * Windowing                                                 *
    3750             :      *-----------------------------------------------------------*/
    3751         634 :     IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    3752             :     {
    3753             : 
    3754          38 :         WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap,
    3755          38 :                       hTcxEnc->speech_TCX, &L_frame, win, 1, 1 );
    3756             : 
    3757             :         /*-----------------------------------------------------------*
    3758             :          * Compute MDCT                                              *
    3759             :          *-----------------------------------------------------------*/
    3760             : 
    3761          38 :         *spectrum_e = 16;
    3762          38 :         move16();
    3763          38 :         TCX_MDCT( win, spectrum, spectrum_e, left_overlap, sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
    3764             :     }
    3765             :     ELSE
    3766             :     {
    3767             :         Word32 tmp_buf[L_FRAME_PLUS];
    3768             :         Word16 Q, tmp1, tmp2, i;
    3769             : 
    3770         596 :         Q = 0;
    3771         596 :         move16();
    3772             : 
    3773         596 :         wtda_fx( hTcxEnc->new_speech_TCX, &Q, tmp_buf, NULL, NULL, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, L_frame );
    3774             : 
    3775         596 :         left_overlap_mode = hTcxCfg->tcx_last_overlap_mode;
    3776         596 :         move16();
    3777         596 :         if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
    3778             :         {
    3779         588 :             left_overlap_mode = FULL_OVERLAP;
    3780         588 :             move16();
    3781             :         }
    3782         596 :         right_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
    3783         596 :         move16();
    3784         596 :         if ( EQ_16( right_overlap_mode, ALDO_WINDOW ) )
    3785             :         {
    3786         585 :             right_overlap_mode = FULL_OVERLAP;
    3787         585 :             move16();
    3788             :         }
    3789             : 
    3790         596 :         WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, hTcxEnc->speech_TCX, &L_frame, winMDST, 1, 1 );
    3791             : 
    3792             :         /* scale by NORM_MDCT_FACTOR / L */
    3793         596 :         tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
    3794         596 :         tmp2 = 4;
    3795         596 :         move16();
    3796         596 :         tmp1 = ISqrt16( tmp1, &tmp2 );
    3797             : 
    3798      493716 :         FOR( i = 0; i < L_frame; i++ )
    3799             :         {
    3800      493120 :             tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
    3801      493120 :             move32();
    3802             :         }
    3803         596 :         Q = sub( Q, tmp2 );
    3804             : 
    3805             :         /* DCT */
    3806         596 :         edct_fx( tmp_buf, spectrum, L_frame, &Q );
    3807         596 :         *spectrum_e = sub( 31, Q );
    3808         596 :         move16();
    3809             :     }
    3810             : 
    3811             : 
    3812             :     /*-----------------------------------------------------------*
    3813             :      * Attenuate upper end of NB spectrum,                       *
    3814             :      * to simulate ACELP behavior                                *
    3815             :      *-----------------------------------------------------------*/
    3816             : 
    3817         634 :     IF( st->narrowBand != 0 )
    3818             :     {
    3819           0 :         attenuateNbSpectrum_fx( L_frame, spectrum );
    3820             :     }
    3821             : 
    3822             :     /*-----------------------------------------------------------*
    3823             :      * Compute noise-measure flags for spectrum filling          *
    3824             :      * and quantization (0: tonal, 1: noise-like).               *
    3825             :      * Detect low pass if present.                               *
    3826             :      *-----------------------------------------------------------*/
    3827             : 
    3828         634 :     pWinMDST = winMDST;
    3829         634 :     move16();
    3830         634 :     if ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    3831             :     {
    3832          38 :         pWinMDST = win;
    3833          38 :         move16();
    3834             :     }
    3835             : 
    3836         634 :     AnalyzePowerSpectrum_fx( st,
    3837         634 :                              round_fx( L_shl( Mpy_32_16_1( L_mult0( L_frame, st->L_frame ) /*Q0*/,
    3838         634 :                                                            getInvFrameLen( hTcxEnc->L_frameTCX ) /*Q21*/ ) /*Q6*/,
    3839             :                                               16 - 6 ) ),
    3840             :                              L_frame,
    3841             :                              left_overlap, right_overlap,
    3842         634 :                              spectrum, *spectrum_e,
    3843             :                              pWinMDST,
    3844             :                              powerSpec, &powerSpec_e );
    3845         634 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
    3846             :     {
    3847             : 
    3848         372 :         SetTnsConfig( hTcxCfg, sub( L_frame_glob, st->L_frame ) == 0, st->last_core == 0 );
    3849             : 
    3850         372 :         TNSAnalysis_fx( hTcxCfg, L_frame, L_spec, TCX_20, st->last_core == 0, spectrum, hTcxEnc->tnsData, hTcxEnc->fUseTns, &st->hIGFEnc->tns_predictionGain );
    3851             :     }
    3852             :     ELSE
    3853             :     {
    3854         262 :         hTcxEnc->fUseTns[0] = hTcxEnc->fUseTns[1] = 0;
    3855         262 :         move16();
    3856         262 :         move16();
    3857             :     }
    3858             : 
    3859         634 :     IF( st->igf )
    3860             :     {
    3861         634 :         ProcessIGF_fx( st->hIGFEnc, st, spectrum, spectrum_e, powerSpec, &powerSpec_e, 1, hTcxEnc->fUseTns[0], ( st->last_core == ACELP_CORE ), 0 );
    3862             :     }
    3863             : 
    3864         634 :     ShapeSpectrum_fx( hTcxCfg, A, gainlpc, gainlpc_e,
    3865             :                       L_frame_glob,
    3866             :                       L_spec,
    3867             :                       spectrum,
    3868         634 :                       hTcxEnc->fUseTns[0],
    3869             :                       st );
    3870         634 :     if ( st->igf )
    3871             :     {
    3872         634 :         nb_bits = sub( nb_bits, st->hIGFEnc->infoTotalBitsPerFrameWritten );
    3873             :     }
    3874         634 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
    3875             :     {
    3876         372 :         EncodeTnsData_fx( hTcxCfg->pCurrentTnsConfig, hTcxEnc->tnsData, prm + 1 + NOISE_FILL_RANGES + LTPSIZE, &tnsSize, &tnsBits );
    3877             :     }
    3878             : 
    3879         634 :     QuantizeSpectrum_fx( hTcxCfg,
    3880             :                          A,
    3881             :                          Aqind,
    3882             :                          gainlpc, gainlpc_e,
    3883             :                          synth,
    3884             :                          L_frame_glob,
    3885             :                          L_frameTCX_glob,
    3886             :                          L_spec,
    3887         634 :                          sub( sub( nb_bits, tnsBits ), ltpBits ),
    3888             :                          tcxonly,
    3889             :                          spectrum, spectrum_e,
    3890         634 :                          hTcxEnc->tnsData,
    3891         634 :                          hTcxEnc->fUseTns[0],
    3892             :                          tnsSize,
    3893             :                          prm,
    3894             :                          n,
    3895             :                          st,
    3896             :                          hm_cfg );
    3897         634 : }
    3898             : 
    3899             : 
    3900             : /*-------------------------------------------------------------------*
    3901             :  * coder_tcx_post_fx()
    3902             :  *
    3903             :  *
    3904             :  *-------------------------------------------------------------------*/
    3905             : 
    3906         634 : void coder_tcx_post_fx(
    3907             :     Encoder_State *st,
    3908             :     LPD_state *LPDmem,
    3909             :     TCX_CONFIG_HANDLE hTcxCfg,
    3910             :     /* i  : configuration of TCX               */ Word16 *synth,
    3911             :     const Word16 *A,
    3912             :     const Word16 *Ai,
    3913             :     Word16 *wsig,
    3914             :     Word16 Q_new,
    3915             :     Word16 shift )
    3916             : {
    3917             :     Word16 xn_buf[L_FRAME_MAX];
    3918             : 
    3919             :     /* TCX output */
    3920         634 :     Copy( synth, xn_buf, st->L_frame );
    3921             : 
    3922             : 
    3923             :     /*-----------------------------------------------------------*
    3924             :      * Memory update                                             *
    3925             :      *-----------------------------------------------------------*/
    3926             : 
    3927             :     /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
    3928         634 :     tcx_encoder_memory_update_fx( wsig, xn_buf, st->L_frame, Ai, A, hTcxCfg->preemph_fac, LPDmem, st, synth, Q_new, shift );
    3929             : 
    3930         634 :     return;
    3931             : }
    3932      236462 : void coder_tcx_post_ivas_fx(
    3933             :     Encoder_State *st,
    3934             :     LPD_state *LPDmem,
    3935             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    3936             :     Word16 *synth,
    3937             :     const Word16 *A,
    3938             :     const Word16 *Ai,
    3939             :     Word16 *wsig,
    3940             :     Word16 Q_new )
    3941             : {
    3942             :     Word16 xn_buf[L_FRAME_MAX];
    3943             : 
    3944             :     /* TCX output */
    3945      236462 :     Copy( synth, xn_buf, st->L_frame );
    3946             : 
    3947             : 
    3948             :     /*-----------------------------------------------------------*
    3949             :      * Memory update                                             *
    3950             :      *-----------------------------------------------------------*/
    3951             : 
    3952             :     /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
    3953      236462 :     tcx_encoder_memory_update_ivas_fx( wsig, xn_buf, st->L_frame, Ai, A, hTcxCfg->preemph_fac, LPDmem, st, synth, Q_new );
    3954             : 
    3955      236462 :     return;
    3956             : }
    3957             : 
    3958             : 
    3959             : /*-------------------------------------------------------------------*
    3960             :  * InternalTCXDecoder_fx()
    3961             :  *
    3962             :  *
    3963             :  *-------------------------------------------------------------------*/
    3964             : 
    3965      238521 : void InternalTCXDecoder_fx(
    3966             :     Encoder_State *st,               /* i/o: state handle                            */
    3967             :     const Word16 frame_cnt,          /* i  : frame counter in the super_frame        */
    3968             :     const Word16 L_frameTCX,         /* i  : full frame length                       */
    3969             :     const Word16 L_frame,            /* i  : frame length                            */
    3970             :     const Word16 L_spec,             /* i  : length of the coded spectrum            */
    3971             :     const Word16 tcx_offset,         /* i  : folding point offset relative to the end of the previous frame */
    3972             :     const Word16 noiseFillingBorder, /* i  : noise filling border                    */
    3973             :     const Word32 *x_quant_fx,        /* i  : quantized spectrum, exponent same as spectrum_e                      */
    3974             :     const Word32 ener_fx,            /* i  : energy of the quantized spectrum    Q(31-ener_e)    */
    3975             :     const Word16 ener_e,             /* i  : exponent of energy of the quantized spectrum         */
    3976             :     Word16 lf_deemph_fact_fx[],      /* i/o: low frequency deemphasis factors        */
    3977             :     const Word16 fac_ns_fx,          /* i  : noise filling level, Q15                     */
    3978             :     const Word16 nf_seed,            /* i  : noise filling random seed, Q0               */
    3979             :     const Word16 *A_fx,              /* i  : LPC representation of the FDNS gains, Q = 14 - norm_s(A_fx[0])    */
    3980             :     Word16 gainlpc_fx[],             /* i/o: FDNS gains                           Q(15-gainlpc_e)   */
    3981             :     Word16 gainlpc_e[],              /* i/o: FDNS gains exponents                              */
    3982             :     const Word16 hm_active,          /* i  : flag indicating if the harmonic model is active */
    3983             :     Word16 gain_tcx_fx,              /* i/o: global gain / quantized global gain     Q(15-gain_tcx_e)        */
    3984             :     Word16 *gain_tcx_e,              /* i/o: global gain / quantized global gain exponent             */
    3985             :     Word32 spectrum_fx[],            /* o  : dequantized spectrum               Q(31-spectrum_e)     */
    3986             :     Word16 *spectrum_e,              /* o  : exponent of dequantized spectrum                    */
    3987             :     Word16 synth[],                  /* o  : time domain signal                      */
    3988             :     Word16 *gain_tcx_q               /* o  : quantized global gain (at low bitrates), Q0 */
    3989             : )
    3990             : {
    3991      238521 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    3992             :     Word16 i, iStart, noiseTransWidth;
    3993             :     Word16 tcx_last_overlap_mode, overlap;
    3994             :     Word16 nz;   /* non-zero length in ALDO window*/
    3995             :     Word16 aldo; /* ALDO flag in current frame*/
    3996             :     Word16 tmp1, tmp2, tmp3, tmp4, s;
    3997             :     Word16 *tmpP16;
    3998             :     Word16 q_spec, len;
    3999             :     Word32 tmp32;
    4000             :     Word32 xn_buf32[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
    4001             :     Word16 Aq_old_fx[M + 1];
    4002             :     Word32 sns_interpolated_scalefactors_fx[FDNS_NPTS], A_fx32[M + 1];
    4003      238521 :     Word16 *xn_buf16 = (Word16 *) xn_buf32;
    4004             : 
    4005      238521 :     Copy32( x_quant_fx, spectrum_fx, s_max( L_frame, L_spec ) );
    4006             : 
    4007             :     /* Replication of ACELP formant enhancement for low rates */
    4008      238521 :     test();
    4009      238521 :     IF( st->total_brate < ACELP_13k20 || st->rf_mode )
    4010             :     {
    4011       33173 :         tcxFormantEnhancement( lf_deemph_fact_fx, gainlpc_fx, gainlpc_e, spectrum_fx, spectrum_e, L_frame, L_spec );
    4012             :     }
    4013             : 
    4014             :     /*-----------------------------------------------------------*
    4015             :      * Noise Filling.                                            *
    4016             :      *-----------------------------------------------------------*/
    4017             : 
    4018      238521 :     IF( fac_ns_fx > 0 )
    4019             :     {
    4020      219910 :         tmp1 = 0;
    4021      219910 :         move16();
    4022      219910 :         test();
    4023      219910 :         if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    4024             :         {
    4025      186901 :             tmp1 = 1;
    4026      186901 :             move16();
    4027             :         }
    4028      219910 :         iStart = tcxGetNoiseFillingTilt( A_fx, M, L_frame, tmp1, &hTcxEnc->noiseTiltFactor );
    4029             : 
    4030      219910 :         tmp1 = 0;
    4031      219910 :         move16();
    4032      219910 :         test();
    4033      219910 :         test();
    4034      219910 :         if ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active )
    4035             :         {
    4036       12640 :             tmp1 = 1;
    4037       12640 :             move16();
    4038             :         }
    4039      219910 :         noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame, shr( st->L_frame, 1 ) ), hTcxEnc->tcxltp_gain, tmp1 );
    4040      219910 :         assert( st->element_mode != IVAS_CPE_MDCT );
    4041      219910 :         tcx_noise_filling( spectrum_fx, *spectrum_e, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns_fx, NULL, st->element_mode );
    4042             :     }
    4043             : 
    4044      238521 :     test();
    4045      238521 :     IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 )
    4046             :     {
    4047             :         /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */
    4048       33173 :         s = sub( getScaleFactor32( spectrum_fx, L_spec ), 4 );
    4049       33173 :         tmp32 = L_deposit_l( 1 );
    4050             : 
    4051    21391733 :         FOR( i = 0; i < L_spec; i++ )
    4052             :         {
    4053    21358560 :             tmp1 = round_fx( L_shl( spectrum_fx[i], s ) );
    4054    21358560 :             tmp32 = L_mac0( tmp32, tmp1, tmp1 );
    4055             :         }
    4056             : 
    4057       33173 :         tmp1 = BASOP_Util_Divide3232_Scale( ener_fx, tmp32, &tmp2 );
    4058       33173 :         tmp2 = add( tmp2, sub( ener_e, add( shl( sub( *spectrum_e, s ), 1 ), 1 ) ) );
    4059       33173 :         tmp1 = Sqrt16( tmp1, &tmp2 );
    4060             : 
    4061       33173 :         gain_tcx_fx = mult( gain_tcx_fx, tmp1 ); // Q(15-(gain_tcx_e+tmp2))
    4062       33173 :         *gain_tcx_e = add( *gain_tcx_e, tmp2 );
    4063       33173 :         move16();
    4064             : 
    4065       33173 :         QuantizeGain( L_spec, &gain_tcx_fx, gain_tcx_e, gain_tcx_q );
    4066             :     }
    4067             : 
    4068             :     /*end of noise filling*/
    4069             : 
    4070             :     /*-----------------------------------------------------------*
    4071             :      * Noise shaping in frequency domain (1/Wz)                  *
    4072             :      *-----------------------------------------------------------*/
    4073             : 
    4074      238521 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    4075             :     {
    4076           0 :         Copy_Scale_sig_16_32_DEPREC( A_fx, A_fx32, M + 1, add( norm_s( A_fx[0] ), 2 ) ); // Copying the Word16 A_fx buffer to a temporary Word32 buffer in Q16
    4077             : 
    4078           0 :         q_spec = sub( 31, *spectrum_e );
    4079           0 :         sns_interpolate_scalefactors_fx( sns_interpolated_scalefactors_fx, A_fx32, DEC );
    4080           0 :         sns_shape_spectrum_fx( spectrum_fx, &q_spec, st->hTcxCfg->psychParamsCurrent, sns_interpolated_scalefactors_fx, Q16, L_frame, &len );
    4081             : 
    4082           0 :         test();
    4083           0 :         test();
    4084           0 :         IF( NE_16( len, L_frame ) && LT_16( q_spec, sub( 31, *spectrum_e ) ) )
    4085             :         {
    4086           0 :             scale_sig32( spectrum_fx + len, sub( L_frame, len ), sub( q_spec, sub( 15, *spectrum_e ) ) ); // q_spec
    4087             :         }
    4088           0 :         ELSE IF( NE_16( len, L_frame ) && GT_16( q_spec, sub( 31, *spectrum_e ) ) )
    4089             :         {
    4090           0 :             scale_sig32( spectrum_fx, len, sub( sub( 15, *spectrum_e ), q_spec ) ); // Q(31-spectrum_e)
    4091           0 :             q_spec = sub( 31, *spectrum_e );
    4092             :         }
    4093           0 :         *spectrum_e = sub( 31, q_spec );
    4094           0 :         move16();
    4095             :     }
    4096             :     ELSE
    4097             :     {
    4098      238521 :         mdct_noiseShaping_ivas_fx( spectrum_fx, spectrum_e, L_frame, gainlpc_fx, gainlpc_e );
    4099             :     }
    4100             :     /*-----------------------------------------------------------*
    4101             :      * Apply gain                                                *
    4102             :      *-----------------------------------------------------------*/
    4103             : 
    4104      238521 :     IF( st->hTcxCfg->coder_type == INACTIVE )
    4105             :     {
    4106       13526 :         gain_tcx_fx = mult_r( gain_tcx_fx, st->hTcxCfg->na_scale );
    4107             :     }
    4108             : 
    4109   199031401 :     FOR( i = 0; i < L_spec; i++ )
    4110             :     {
    4111   198792880 :         spectrum_fx[i] = Mpy_32_16_1( spectrum_fx[i], gain_tcx_fx );
    4112   198792880 :         move32();
    4113             :     }
    4114      238521 :     *spectrum_e = add( *spectrum_e, *gain_tcx_e );
    4115      238521 :     move16();
    4116             : 
    4117      238521 :     tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    4118      238521 :     move16();
    4119             : 
    4120      238521 :     test();
    4121      238521 :     IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    4122             :     {
    4123        4118 :         Word16 L = L_frame;
    4124        4118 :         move16();
    4125             : 
    4126        4118 :         test();
    4127        4118 :         test();
    4128        4118 :         if ( ( ( st->hTcxCfg->fIsTNSAllowed != 0 ) && ( hTcxEnc->fUseTns[frame_cnt] != 0 ) ) || ( GT_16( L_spec, L_frame ) ) )
    4129             :         {
    4130        4018 :             L = L_spec;
    4131        4018 :             move16();
    4132             :         }
    4133             : 
    4134        4118 :         tcxInvertWindowGrouping( st->hTcxCfg,
    4135             :                                  xn_buf32,
    4136             :                                  spectrum_fx,
    4137             :                                  L,
    4138        4118 :                                  hTcxEnc->fUseTns[frame_cnt],
    4139        4118 :                                  st->last_core,
    4140             :                                  tcx_last_overlap_mode,
    4141             :                                  frame_cnt,
    4142             :                                  0 );
    4143             :     }
    4144             : 
    4145             :     /*-----------------------------------------------------------*
    4146             :      * Temporal Noise Shaping Synthesis                          *
    4147             :      *-----------------------------------------------------------*/
    4148             : 
    4149      238521 :     IF( st->hTcxCfg->fIsTNSAllowed )
    4150             :     {
    4151      161673 :         test();
    4152      161673 :         SetTnsConfig( st->hTcxCfg, (Word16) EQ_16( st->core, TCX_20_CORE ), ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
    4153             : 
    4154             :         /* Apply TNS to get the reconstructed signal */
    4155      161673 :         IF( hTcxEnc->fUseTns[frame_cnt] != 0 )
    4156             :         {
    4157       17593 :             ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frame_cnt], spectrum_fx, 0 );
    4158             : 
    4159       17593 :             test();
    4160       17593 :             IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    4161             :             {
    4162        2365 :                 test();
    4163        2365 :                 test();
    4164        2365 :                 test();
    4165        2365 :                 IF( ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
    4166             :                     ( ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( tcx_last_overlap_mode == 0 ) ) )
    4167             :                 {
    4168        1717 :                     const Word16 L_win = shr( L_spec, 1 );
    4169             :                     /* undo rearrangement of LF sub-window lines for TNS synthesis filter */
    4170        1717 :                     IF( GT_16( L_frame, L_spec ) )
    4171             :                     {
    4172           0 :                         assert( 0 );
    4173             :                     }
    4174             :                     ELSE
    4175             :                     {
    4176        1717 :                         Copy32( spectrum_fx + 8, xn_buf32, L_win );
    4177        1717 :                         Copy32( xn_buf32, spectrum_fx + L_win, 8 );
    4178        1717 :                         Copy32( xn_buf32 + 8, spectrum_fx + 8, L_win - 8 );
    4179             :                     }
    4180             :                 }
    4181             :             }
    4182             :         }
    4183             :     }
    4184             : 
    4185             : 
    4186             :     /*-----------------------------------------------------------*
    4187             :      * Compute inverse MDCT of spectrum[].                        *
    4188             :      *-----------------------------------------------------------*/
    4189             : 
    4190      238521 :     E_LPC_f_lsp_a_conversion( st->lsp_old_fx, Aq_old_fx, M );
    4191      238521 :     overlap = st->hTcxCfg->tcx_mdct_window_length;
    4192      238521 :     nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS );
    4193      238521 :     aldo = 0;
    4194      238521 :     move16();
    4195      238521 :     move16();
    4196             : 
    4197             :     /* normalize spectrum to minimize IMDCT noise */
    4198      238521 :     s = getScaleFactor32( spectrum_fx, L_frame );
    4199   106122345 :     FOR( i = 0; i < L_frame; i++ )
    4200             :     {
    4201   105883824 :         spectrum_fx[i] = L_shl( spectrum_fx[i], s );
    4202   105883824 :         move32();
    4203             :     }
    4204      238521 :     *spectrum_e = sub( *spectrum_e, s );
    4205      238521 :     move16();
    4206             : 
    4207      238521 :     test();
    4208      238521 :     IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    4209             :     {
    4210        4118 :         IF( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP )
    4211             :         {
    4212             :             Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    4213             :             Word16 L_win, L_spec_TCX5, L_ola, w;
    4214             : 
    4215             :             /* minimum or half overlap, two transforms, grouping into one window */
    4216        1601 :             L_win = shr( L_frame, 1 );
    4217        1601 :             L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
    4218        1601 :             L_ola = st->hTcxCfg->tcx_mdct_window_half_length;
    4219        1601 :             move16();
    4220        1601 :             if ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    4221             :             {
    4222         770 :                 L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
    4223         770 :                 move16();
    4224             :             }
    4225             : 
    4226        1601 :             set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    4227        1601 :             set16_fx( xn_buf16, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */
    4228             : 
    4229        4803 :             FOR( w = 0; w < 2; w++ )
    4230             :             {
    4231             : 
    4232        3202 :                 IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    4233             :                 {
    4234        1540 :                     TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4235        1540 :                                       win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    4236             :                 }
    4237             :                 ELSE
    4238             :                 {
    4239        1662 :                     TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win,
    4240        1662 :                                       L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    4241             :                 }
    4242             : 
    4243        3202 :                 tmp1 = st->hTcxCfg->tcx_last_overlap_mode;
    4244        3202 :                 move16();
    4245        3202 :                 test();
    4246        3202 :                 test();
    4247        3202 :                 if ( ( w > 0 ) || ( ( w == 0 ) && ( EQ_16( tcx_last_overlap_mode, 2 ) ) ) )
    4248             :                 {
    4249        1942 :                     tmp1 = MIN_OVERLAP;
    4250        1942 :                     move16();
    4251             :                 }
    4252             : 
    4253        3202 :                 tmp2 = 0;
    4254        3202 :                 move16();
    4255        3202 :                 test();
    4256        3202 :                 if ( ( w == 0 ) && ( st->last_core == ACELP_CORE ) )
    4257             :                 {
    4258           0 :                     tmp2 = 1;
    4259           0 :                     move16();
    4260             :                 }
    4261             : 
    4262        3202 :                 tmp3 = st->last_core;
    4263        3202 :                 move16();
    4264        3202 :                 if ( w > 0 )
    4265             :                 {
    4266        1601 :                     tmp3 = 1;
    4267        1601 :                     move16();
    4268             :                 }
    4269             : 
    4270        3202 :                 tmp4 = 0;
    4271        3202 :                 move16();
    4272        3202 :                 if ( tcx_offset < 0 )
    4273             :                 {
    4274           0 :                     tmp4 = negate( tcx_offset );
    4275             :                 }
    4276             : 
    4277        3202 :                 tcx_windowing_synthesis_current_frame( win,
    4278        3202 :                                                        st->hTcxCfg->tcx_aldo_window_2,
    4279        3202 :                                                        st->hTcxCfg->tcx_mdct_window_half,
    4280        3202 :                                                        st->hTcxCfg->tcx_mdct_window_minimum,
    4281             :                                                        L_ola,
    4282        3202 :                                                        st->hTcxCfg->tcx_mdct_window_half_length,
    4283        3202 :                                                        st->hTcxCfg->tcx_mdct_window_min_length,
    4284             :                                                        tmp2,
    4285             :                                                        tmp1,
    4286             :                                                        hTcxEnc->acelp_zir,
    4287        3202 :                                                        hTcxEnc->Txnq,
    4288             :                                                        NULL,
    4289             :                                                        Aq_old_fx,
    4290        3202 :                                                        st->hTcxCfg->tcx_mdct_window_trans,
    4291             :                                                        L_win,
    4292             :                                                        tmp4,
    4293             :                                                        tmp3,
    4294             :                                                        0,
    4295             :                                                        0 );
    4296             : 
    4297        3202 :                 tmp1 = add( tcx_offset, imult1616( w, L_win ) );
    4298        3202 :                 move16();
    4299        3202 :                 tmpP16 = xn_buf16 + sub( tmp1, shr( L_ola, 1 ) );
    4300             : 
    4301        3202 :                 IF( w > 0 )
    4302             :                 {
    4303        1601 :                     tcx_windowing_synthesis_past_frame( tmpP16,
    4304        1601 :                                                         st->hTcxCfg->tcx_aldo_window_1_trunc,
    4305        1601 :                                                         st->hTcxCfg->tcx_mdct_window_half,
    4306        1601 :                                                         st->hTcxCfg->tcx_mdct_window_minimum,
    4307             :                                                         L_ola,
    4308        1601 :                                                         st->hTcxCfg->tcx_mdct_window_half_length,
    4309        1601 :                                                         st->hTcxCfg->tcx_mdct_window_min_length,
    4310             :                                                         2 );
    4311             :                 }
    4312             :                 /* add part of current sub-window overlapping with previous window */
    4313      263522 :                 FOR( i = 0; i < L_ola; i++ )
    4314             :                 {
    4315      260320 :                     tmpP16[i] = add_sat( tmpP16[i], win[i] );
    4316      260320 :                     move16();
    4317             :                 }
    4318             :                 /* copy new sub-window region not overlapping with previous window */
    4319        3202 :                 Copy( win + L_ola, xn_buf16 + add( tmp1, shr( L_ola, 1 ) ), L_win );
    4320             :             }
    4321             :             /* To assure that no garbage values are copied to hLPDmem->Txnq */
    4322        1601 :             set16_fx( xn_buf16 + add( add( L_frame, tcx_offset ), shr( L_ola, 1 ) ),
    4323        1601 :                       0, sub( sub( overlap, tcx_offset ), shr( L_ola, 1 ) ) );
    4324             :         }
    4325        2517 :         ELSE IF( s_and( frame_cnt == 0, ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) )
    4326             :         {
    4327             :             /* special overlap attempt, two transforms, grouping into one window */
    4328             :             Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    4329             :             Word16 L_win, L_spec_TCX5, L_ola, w;
    4330             : 
    4331         596 :             L_win = shr( L_frame, 1 );
    4332         596 :             L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
    4333         596 :             L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
    4334         596 :             move16();
    4335             : 
    4336         596 :             set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    4337             : 
    4338             :             /* Resize overlap (affect only asymmetric window)*/
    4339         596 :             overlap = st->hTcxCfg->tcx_mdct_window_delay;
    4340             :             /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
    4341         596 :             TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4342         596 :                               win + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode );
    4343             : 
    4344             :             /* copy new sub-window region not overlapping with previous window */
    4345         596 :             Copy( win + L_win, xn_buf16 + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
    4346             : 
    4347             :             /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
    4348             : 
    4349         596 :             TCX_MDCT_Inverse( spectrum_fx + L_spec_TCX5, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4350         596 :                               win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    4351             : 
    4352         596 :             tmp4 = 0;
    4353         596 :             move16();
    4354         596 :             if ( tcx_offset < 0 )
    4355             :             {
    4356           0 :                 tmp4 = negate( tcx_offset );
    4357             :             }
    4358         596 :             tcx_windowing_synthesis_current_frame( win,
    4359         596 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4360         596 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4361         596 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4362             :                                                    L_ola,
    4363         596 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4364         596 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4365             :                                                    0, /* left_rect */
    4366             :                                                    2, /* left_mode */
    4367             :                                                    hTcxEnc->acelp_zir,
    4368         596 :                                                    hTcxEnc->Txnq,
    4369             :                                                    NULL,
    4370             :                                                    Aq_old_fx,
    4371         596 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4372             :                                                    L_win,
    4373             :                                                    tmp4,
    4374             :                                                    1, /* not LPDmem->mode */
    4375             :                                                    0,
    4376             :                                                    0 );
    4377             : 
    4378             : 
    4379         596 :             tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) );
    4380             : 
    4381         596 :             tcx_windowing_synthesis_past_frame( tmpP16,
    4382         596 :                                                 st->hTcxCfg->tcx_aldo_window_1_trunc,
    4383         596 :                                                 st->hTcxCfg->tcx_mdct_window_half,
    4384         596 :                                                 st->hTcxCfg->tcx_mdct_window_minimum,
    4385             :                                                 L_ola,
    4386         596 :                                                 st->hTcxCfg->tcx_mdct_window_half_length,
    4387         596 :                                                 st->hTcxCfg->tcx_mdct_window_min_length,
    4388             :                                                 2 );
    4389             : 
    4390             :             /* add part of current sub-window overlapping with previous window */
    4391       24316 :             FOR( i = 0; i < L_ola; i++ )
    4392             :             {
    4393       23720 :                 tmpP16[i] = add_sat( tmpP16[i], win[i] );
    4394       23720 :                 move16();
    4395             :             }
    4396             : 
    4397             :             /* copy new sub-window region not overlapping with previous window */
    4398        1192 :             Copy( win + L_ola,
    4399         596 :                   xn_buf16 + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ),
    4400             :                   L_win );
    4401             : 
    4402             :             /* extra folding-out on left side of win, for perfect reconstruction */
    4403       83616 :             FOR( w = shr( overlap, 1 ); w < overlap; w++ )
    4404             :             {
    4405       83020 :                 xn_buf16[overlap - 1 - w] = negate( xn_buf16[w] );
    4406       83020 :                 move16();
    4407             :             }
    4408             : 
    4409         596 :             tmp4 = 0;
    4410         596 :             move16();
    4411         596 :             if ( tcx_offset < 0 )
    4412             :             {
    4413           0 :                 tmp4 = negate( tcx_offset );
    4414             :             }
    4415         596 :             tcx_windowing_synthesis_current_frame( xn_buf16,
    4416         596 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4417         596 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4418         596 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4419             :                                                    overlap,
    4420         596 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4421         596 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4422         596 :                                                    st->last_core == ACELP_CORE,
    4423             :                                                    0,
    4424             :                                                    hTcxEnc->acelp_zir,
    4425         596 :                                                    hTcxEnc->Txnq,
    4426             :                                                    NULL,
    4427             :                                                    Aq_old_fx,
    4428         596 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4429             :                                                    L_win,
    4430             :                                                    tmp4,
    4431         596 :                                                    st->last_core,
    4432             :                                                    0,
    4433             :                                                    0 );
    4434             :         }
    4435             :         ELSE /* default, i.e. maximum overlap, single transform, no grouping */
    4436             :         {
    4437             : 
    4438        1921 :             TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4439        1921 :                               xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    4440             : 
    4441        1921 :             tmp1 = tcx_last_overlap_mode;
    4442        1921 :             move16();
    4443        1921 :             test();
    4444        1921 :             test();
    4445        1921 :             if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) )
    4446             :             {
    4447         596 :                 tmp1 = 2;
    4448         596 :                 move16();
    4449             :             }
    4450             : 
    4451        1921 :             tmp4 = 0;
    4452        1921 :             move16();
    4453        1921 :             if ( tcx_offset < 0 )
    4454             :             {
    4455           0 :                 tmp4 = negate( tcx_offset );
    4456             :             }
    4457        3842 :             tcx_windowing_synthesis_current_frame( xn_buf16,
    4458        1921 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4459        1921 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4460        1921 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4461             :                                                    overlap, /*hTcxCfg->tcx_mdct_window_length*/
    4462        1921 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4463        1921 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4464        1921 :                                                    st->last_core == ACELP_CORE,
    4465             :                                                    tmp1,
    4466             :                                                    hTcxEnc->acelp_zir,
    4467        1921 :                                                    hTcxEnc->Txnq,
    4468             :                                                    NULL,
    4469             :                                                    Aq_old_fx,
    4470        1921 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4471        1921 :                                                    shr( st->L_frame, 2 ),
    4472             :                                                    tmp4,
    4473        1921 :                                                    st->last_core,
    4474             :                                                    0,
    4475             :                                                    0 );
    4476             : 
    4477             :         } /* tcx_last_overlap_mode > 0 */
    4478             :     }
    4479             :     ELSE /* frame is TCX-20 or not TCX-only */
    4480             :     {
    4481      234403 :         IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    4482             :         {
    4483             :             Word32 tmp_buf[L_FRAME_PLUS];
    4484             :             Word16 Q;
    4485             : 
    4486             :             /* DCT */
    4487      226472 :             Q = sub( 31, *spectrum_e );
    4488      226472 :             edct_ivas_fx( spectrum_fx, tmp_buf, L_frame, &Q );
    4489             : 
    4490             :             /* scale by sqrt(L / NORM_MDCT_FACTOR) */
    4491      226472 :             tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
    4492      226472 :             tmp2 = 4;
    4493      226472 :             move16();
    4494      226472 :             tmp1 = Sqrt16( tmp1, &tmp2 );
    4495             : 
    4496   101805736 :             FOR( i = 0; i < L_frame; i++ )
    4497             :             {
    4498   101579264 :                 tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
    4499   101579264 :                 move32();
    4500             :             }
    4501      226472 :             Q = sub( Q, tmp2 );
    4502             : 
    4503             : 
    4504      226472 :             window_ola_fx( tmp_buf,
    4505             :                            xn_buf16,
    4506             :                            &Q,
    4507      226472 :                            hTcxEnc->old_out_fx,
    4508             :                            &hTcxEnc->Q_old_out,
    4509             :                            L_frame,
    4510      226472 :                            st->hTcxCfg->tcx_last_overlap_mode,
    4511      226472 :                            st->hTcxCfg->tcx_curr_overlap_mode,
    4512             :                            0,
    4513             :                            0,
    4514             :                            NULL );
    4515             : 
    4516             :             /* scale output */
    4517   101805736 :             FOR( i = 0; i < L_frame; i++ )
    4518             :             {
    4519   101579264 :                 xn_buf16[i] = shr_sat( xn_buf16[i], Q );
    4520   101579264 :                 move16();
    4521             :             }
    4522             : 
    4523      226472 :             aldo = 1;
    4524      226472 :             move16();
    4525             :         }
    4526             :         ELSE
    4527             :         {
    4528             : 
    4529        7931 :             TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4530        7931 :                               xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    4531             : 
    4532             :             /*-----------------------------------------------------------*
    4533             :              * Windowing, overlap and add                                *
    4534             :              *-----------------------------------------------------------*/
    4535             : 
    4536             :             /* Window current frame */
    4537        7931 :             tmp4 = 0;
    4538        7931 :             move16();
    4539        7931 :             if ( tcx_offset < 0 )
    4540             :             {
    4541        7931 :                 tmp4 = negate( tcx_offset );
    4542             :             }
    4543       15862 :             tcx_windowing_synthesis_current_frame( xn_buf16,
    4544        7931 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4545        7931 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4546        7931 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4547             :                                                    overlap, /*hTcxCfg->tcx_mdct_window_length*/
    4548        7931 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4549        7931 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4550        7931 :                                                    st->last_core == ACELP_CORE,
    4551        7931 :                                                    st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/
    4552             :                                                    hTcxEnc->acelp_zir,
    4553        7931 :                                                    hTcxEnc->Txnq,
    4554             :                                                    NULL,
    4555             :                                                    Aq_old_fx,
    4556        7931 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4557        7931 :                                                    shr( st->L_frame, 1 ),
    4558             :                                                    tmp4,
    4559        7931 :                                                    st->last_core,
    4560             :                                                    0,
    4561             :                                                    0 );
    4562             :         }
    4563             :     } /* TCX-10 and TCX-only */
    4564             : 
    4565             :     /* Window and overlap-add past frame if past frame is TCX */
    4566      238521 :     test();
    4567      238521 :     test();
    4568      238521 :     test();
    4569      238521 :     IF( ( st->last_core > ACELP_CORE ) && ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) )
    4570             :     {
    4571             : 
    4572        4118 :         IF( st->hTcxCfg->last_aldo != 0 )
    4573             :         {
    4574        1922 :             tmp2 = add( hTcxEnc->Q_old_out, TCX_IMDCT_HEADROOM );
    4575             : 
    4576        1922 :             tmp1 = sub( overlap, st->hTcxCfg->tcx_mdct_window_min_length );
    4577      461522 :             FOR( i = 0; i < tmp1; i++ )
    4578             :             {
    4579      459600 :                 xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
    4580      459600 :                 move16();
    4581             :             }
    4582             : 
    4583             :             /* fade truncated ALDO window */
    4584        1922 :             tmp1 = sub( overlap, shr( st->hTcxCfg->tcx_mdct_window_min_length, 1 ) );
    4585       40222 :             FOR( ; i < tmp1; i++ )
    4586             :             {
    4587       38300 :                 tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[i - overlap + st->hTcxCfg->tcx_mdct_window_min_length].v.re );
    4588       38300 :                 xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    4589       38300 :                 move16();
    4590             :             }
    4591       40222 :             FOR( ; i < overlap; i++ )
    4592             :             {
    4593       38300 :                 tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im );
    4594       38300 :                 xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    4595       38300 :                 move16();
    4596             :             }
    4597             : 
    4598       78522 :             FOR( ; i < L_frame; i++ )
    4599             :             {
    4600       76600 :                 xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    4601       76600 :                 move16();
    4602             :             }
    4603             :         }
    4604             :         ELSE
    4605             :         {
    4606        2196 :             test();
    4607        2196 :             test();
    4608        2196 :             test();
    4609        2196 :             if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( st->last_core != ACELP_CORE ) )
    4610             :             {
    4611         596 :                 tcx_last_overlap_mode = 2; /* use minimum overlap between the two TCX-10 windows */
    4612         596 :                 move16();
    4613             :             }
    4614             : 
    4615        2196 :             tmp1 = tcx_last_overlap_mode;
    4616        2196 :             move16();
    4617        2196 :             test();
    4618        2196 :             if ( ( tcx_last_overlap_mode == 0 ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
    4619             :             {
    4620        1056 :                 tmp1 = st->hTcxCfg->tcx_last_overlap_mode;
    4621        1056 :                 move16();
    4622             :             }
    4623             : 
    4624        2196 :             tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half,
    4625        2196 :                                                 st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, tmp1 );
    4626             : 
    4627             :             BASOP_SATURATE_WARNING_OFF_EVS;
    4628      615116 :             FOR( i = 0; i < overlap; i++ )
    4629             :             {
    4630      612920 :                 xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM );
    4631      612920 :                 move16();
    4632             :             }
    4633             : 
    4634        2196 :             IF( LT_16( i, L_frame ) )
    4635             :             {
    4636       89756 :                 FOR( ; i < L_frame; i++ )
    4637             :                 {
    4638       87560 :                     xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    4639       87560 :                     move16();
    4640             :                 }
    4641             :             }
    4642             :             BASOP_SATURATE_WARNING_ON_EVS;
    4643             :         }
    4644             :     }
    4645             :     ELSE
    4646             :     {
    4647      234403 :         IF( aldo == 0 )
    4648             :         {
    4649             :             BASOP_SATURATE_WARNING_OFF_EVS;
    4650     2999211 :             FOR( i = 0; i < L_frame; i++ )
    4651             :             {
    4652     2991280 :                 xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    4653     2991280 :                 move16();
    4654             :             }
    4655             :             BASOP_SATURATE_WARNING_ON_EVS;
    4656             :         }
    4657             :     }
    4658             : 
    4659      238521 :     test();
    4660      238521 :     test();
    4661      238521 :     test();
    4662      238521 :     IF( ( aldo == 0 ) &&
    4663             :         ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
    4664             :           NE_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) )
    4665             :     {
    4666             :         /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
    4667     1052388 :         FOR( i = 0; i < nz; i++ )
    4668             :         {
    4669     1042398 :             hTcxEnc->old_out_fx[i] = shr( xn_buf16[L_frame - nz + i], TCX_IMDCT_HEADROOM );
    4670     1042398 :             move16();
    4671             :         }
    4672        9990 :         Copy( xn_buf16 + L_frame, hTcxEnc->old_out_fx + nz, overlap );
    4673        9990 :         set16_fx( hTcxEnc->old_out_fx + nz + overlap, 0, nz );
    4674             : 
    4675        9990 :         tcx_windowing_synthesis_past_frame( hTcxEnc->old_out_fx + nz,
    4676        9990 :                                             st->hTcxCfg->tcx_aldo_window_1_trunc,
    4677        9990 :                                             st->hTcxCfg->tcx_mdct_window_half,
    4678        9990 :                                             st->hTcxCfg->tcx_mdct_window_minimum,
    4679             :                                             overlap,
    4680        9990 :                                             st->hTcxCfg->tcx_mdct_window_half_length,
    4681        9990 :                                             st->hTcxCfg->tcx_mdct_window_min_length,
    4682        9990 :                                             st->hTcxCfg->tcx_curr_overlap_mode );
    4683             : 
    4684             :         /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
    4685        9990 :         IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP )
    4686             :         {
    4687      862485 :             FOR( i = 0; i < nz; i++ )
    4688             :             {
    4689      853578 :                 hTcxEnc->old_out_fx[nz + overlap + i] = shr( mult_r( xn_buf16[L_frame - 1 - i], st->hTcxCfg->tcx_aldo_window_1[nz - 1 - i] ), TCX_IMDCT_HEADROOM );
    4690      853578 :                 move16();
    4691             :             }
    4692             :         }
    4693             : 
    4694        9990 :         hTcxEnc->Q_old_out = -TCX_IMDCT_HEADROOM;
    4695        9990 :         move16();
    4696             :     }
    4697      238521 :     st->hTcxCfg->last_aldo = aldo;
    4698      238521 :     move16();
    4699             : 
    4700             :     /* Update Txnq */
    4701      238521 :     IF( st->hTcxCfg->last_aldo == 0 )
    4702             :     {
    4703       12049 :         Copy( xn_buf16 + L_frame, hTcxEnc->Txnq, overlap );
    4704             :     }
    4705             : 
    4706      238521 :     tmp1 = L_frame;
    4707      238521 :     move16();
    4708      238521 :     if ( EQ_16( st->core, TCX_20_CORE ) )
    4709             :     {
    4710      234403 :         tmp1 = st->L_frame;
    4711      234403 :         move16();
    4712             :     }
    4713             : 
    4714             :     /* Output */
    4715      238521 :     Copy( xn_buf16 + shr( overlap, 1 ) - tcx_offset, synth, tmp1 );
    4716             : 
    4717      238521 :     return;
    4718             : }
    4719             : 
    4720             : 
    4721      712182 : void TNSAnalysisStereo_fx(
    4722             :     Encoder_State **sts,                            /* i  : encoder state handle                    */
    4723             :     Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o  : MDST spectrum                       Qx*/
    4724             :     const Word16 bWhitenedDomain,                   /* i  : whitened domain flag                    Q0*/
    4725             :     Word16 tnsSize[CPE_CHANNELS][NB_DIV],           /* i  : number of tns parameters put into prm   Q0*/
    4726             :     Word16 tnsBits[CPE_CHANNELS][NB_DIV],           /* i  : number of tns bits in the frame         Q0*/
    4727             :     Word16 param_core[][NB_DIV * NPRM_DIV],         /* o  : TNS parameters                          Q0*/
    4728             :     const Word16 mct_on                             /* i  : flag mct block (1) or stereo (0)        Q0*/
    4729             : )
    4730             : {
    4731             :     Word16 ch, k, L_spec, L_frame, nSubframes, iFilter;
    4732             :     Word32 *spectrum_fx, sum;
    4733      712182 :     Encoder_State *st = NULL;
    4734      712182 :     TCX_ENC_HANDLE hTcxEnc = NULL;
    4735             :     Word16 individual_decision[NB_DIV];
    4736      712182 :     Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx;
    4737      712182 :     move32();
    4738      712182 :     Word16 maxPredictionGain_e = 0, meanPredictionGain_e;
    4739      712182 :     move16();
    4740      712182 :     Word16 sum_e = 0;
    4741      712182 :     move16();
    4742      712182 :     individual_decision[0] = 0;
    4743      712182 :     move16();
    4744      712182 :     individual_decision[1] = 0;
    4745      712182 :     move16();
    4746      712182 :     L_spec = -1;
    4747      712182 :     move16();
    4748      712182 :     L_frame = -1;
    4749      712182 :     move16();
    4750             : 
    4751             :     /* TNS filter analysis, loop over channels */
    4752     2136546 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    4753             :     {
    4754     1424364 :         st = sts[ch];
    4755     1424364 :         IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    4756             :         {
    4757      128194 :             CONTINUE;
    4758             :         }
    4759             : 
    4760     1296170 :         hTcxEnc = st->hTcxEnc;
    4761             : 
    4762     1296170 :         IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) )
    4763             :         {
    4764     1266530 :             nSubframes = 1;
    4765             :         }
    4766             :         ELSE
    4767             :         {
    4768       29640 :             nSubframes = NB_DIV;
    4769             :         }
    4770     1296170 :         move16();
    4771             : 
    4772     2621980 :         FOR( k = 0; k < nSubframes; k++ )
    4773             :         {
    4774             :             /* reset tns on whitened domain flag */
    4775     1325810 :             IF( !bWhitenedDomain )
    4776             :             {
    4777      667173 :                 hTcxEnc->bTnsOnWhithenedSpectra[k] = 0;
    4778      667173 :                 move16();
    4779      667173 :                 hTcxEnc->fUseTns[k] = 0;
    4780      667173 :                 move16();
    4781             :             }
    4782     1325810 :             test();
    4783     1325810 :             test();
    4784     1325810 :             IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    4785             :             {
    4786     1303537 :                 spectrum_fx = hTcxEnc->spectrum_fx[k];
    4787             : 
    4788     1303537 :                 L_frame = hTcxEnc->L_frameTCX;
    4789     1303537 :                 move16();
    4790     1303537 :                 st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
    4791     1303537 :                 L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
    4792     1303537 :                 move16();
    4793             :                 /*-----------------------------------------------------------*
    4794             :                  * Temporal Noise Shaping analysis                           *
    4795             :                  *-----------------------------------------------------------*/
    4796             : 
    4797     1303537 :                 IF( EQ_16( hTcxEnc->transform_type[k], TCX_5 ) )
    4798             :                 {
    4799             :                     /* rearrange LF sub-window lines prior to TNS analysis & filtering */
    4800       15311 :                     tcx5TnsGrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), spectrum_fx );
    4801             :                 }
    4802             : 
    4803             :                 /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */
    4804             : 
    4805     1303537 :                 ResetTnsData( &hTcxEnc->tnsData[k] );
    4806     1303537 :                 IF( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 )
    4807             :                 {
    4808           0 :                     BREAK;
    4809             :                 }
    4810             : 
    4811     1303537 :                 CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] );
    4812             :             }
    4813             :         }
    4814             :     }
    4815             : 
    4816      712182 :     IF( !mct_on )
    4817             :     {
    4818             :         /* TNS decision */
    4819             :         /* if framing differs between channels, keep the filter decision per channel */
    4820      167566 :         test();
    4821      167566 :         test();
    4822      167566 :         IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) &&
    4823             :               NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) ||
    4824             :             NE_16( sts[0]->hTcxCfg->fIsTNSAllowed, sts[1]->hTcxCfg->fIsTNSAllowed ) )
    4825             :         {
    4826        1254 :             individual_decision[0] = individual_decision[1] = 1;
    4827        1254 :             move16();
    4828        1254 :             move16();
    4829             :         }
    4830      166312 :         ELSE IF( bWhitenedDomain )
    4831             :         {
    4832       83156 :             IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) )
    4833             :             {
    4834       81396 :                 nSubframes = 1;
    4835             :             }
    4836             :             ELSE
    4837             :             {
    4838        1760 :                 nSubframes = NB_DIV;
    4839             :             }
    4840       83156 :             move16();
    4841      168072 :             FOR( k = 0; k < nSubframes; k++ )
    4842             :             {
    4843       84916 :                 IF( NE_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    4844             :                 {
    4845         427 :                     individual_decision[k] = 1;
    4846         427 :                     move16();
    4847             :                 }
    4848             :             }
    4849             :         }
    4850             : 
    4851             :         /* framing equal, check for similar filters, if very similar (also indicator for and M signal),
    4852             :          * use at least the same decision, maybe use the same filter
    4853             :          */
    4854             :         {
    4855             :             Word8 isTCX10;
    4856             : 
    4857      167566 :             IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) )
    4858             :             {
    4859      163444 :                 nSubframes = 1;
    4860      163444 :                 isTCX10 = 0;
    4861             :             }
    4862             :             ELSE
    4863             :             {
    4864        4122 :                 nSubframes = NB_DIV;
    4865        4122 :                 isTCX10 = 1;
    4866             :             }
    4867      167566 :             move16();
    4868      167566 :             move16();
    4869      339254 :             FOR( k = 0; k < nSubframes; k++ )
    4870             :             {
    4871      171688 :                 test();
    4872      171688 :                 test();
    4873      171688 :                 test();
    4874      171688 :                 IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    4875             :                 {
    4876      167092 :                     Word32 maxPredGain_fx = -ONE_IN_Q31;
    4877      167092 :                     move32();
    4878      167092 :                     Word16 maxPredGain_e = 0;
    4879      167092 :                     move16();
    4880      167092 :                     sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )];
    4881      167092 :                     sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )];
    4882             : 
    4883      479765 :                     FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    4884             :                     {
    4885             :                         STnsFilter *pFilter[2];
    4886             :                         struct TnsParameters const *pTnsParameters[2];
    4887      312673 :                         pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter;
    4888      312673 :                         pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
    4889      312673 :                         pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter;
    4890      312673 :                         pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
    4891             : 
    4892             :                         /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of
    4893             :                          * both filters for the decision
    4894             :                          */
    4895             : 
    4896      312673 :                         meanPredictionGain_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[0]->predictionGain_e, Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain_e, &meanPredictionGain_e ); // meanPredictionGain_e
    4897             : 
    4898             :                         /* maxPredictionGain = max( maxPredictionGain, meanPredictionGain );*/
    4899      312673 :                         IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, meanPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */
    4900             :                         {
    4901      207244 :                             maxPredictionGain_fx = meanPredictionGain_fx;
    4902      207244 :                             maxPredictionGain_e = meanPredictionGain_e;
    4903      207244 :                             move32();
    4904      207244 :                             move16();
    4905             :                         }
    4906             : 
    4907      312673 :                         test();
    4908      312673 :                         test();
    4909      312673 :                         test();
    4910      312673 :                         IF( GT_32( pFilter[0]->predictionGain32, L_shl_sat( ( pTnsParameters[0]->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter[0]->predictionGain_e ) ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) &&
    4911             :                             GT_32( pFilter[1]->predictionGain32, L_shl_sat( ( pTnsParameters[1]->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter[1]->predictionGain_e ) ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) )
    4912             :                         {
    4913        4928 :                             pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */
    4914        4928 :                             move32();
    4915        4928 :                             move32();
    4916        4928 :                             pFilter[0]->predictionGain_e = pFilter[1]->predictionGain_e = meanPredictionGain_e; /* more TNS filter sync at 48kbps */
    4917        4928 :                             move16();
    4918        4928 :                             move16();
    4919        4928 :                             pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */
    4920        4928 :                             move16();
    4921             :                         }
    4922      312673 :                         sum_e = s_max( pFilter[0]->predictionGain_e, pFilter[1]->predictionGain_e );
    4923      312673 :                         sum = L_abs( L_sub_sat( L_shl( pFilter[0]->predictionGain32, sub( pFilter[0]->predictionGain_e, sum_e ) ), L_shl( pFilter[1]->predictionGain32, sub( pFilter[1]->predictionGain_e, sum_e ) ) ) ); // sum_e
    4924             : 
    4925      312673 :                         IF( LT_32( L_shl_sat( sum, sub( sum_e, meanPredictionGain_e ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) &&
    4926             :                             ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) )
    4927      207540 :                         {
    4928             : 
    4929      207540 :                             Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15
    4930      207540 :                             Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) );
    4931             : 
    4932             :                             /* maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); */
    4933      207540 :                             IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, maxPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */
    4934             :                             {
    4935      155939 :                                 maxPredGain_fx = meanPredictionGain_fx;
    4936      155939 :                                 maxPredGain_e = meanPredictionGain_e;
    4937      155939 :                                 move32();
    4938      155939 :                                 move16();
    4939             :                             }
    4940             : 
    4941      207540 :                             test();
    4942      207540 :                             test();
    4943      207540 :                             IF( GT_32( meanPredictionGain_fx, L_shl_sat( ( pTnsParameters[0]->minPredictionGain_32 ), sub( PRED_GAIN_E, meanPredictionGain_e ) ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) )
    4944             :                             {
    4945        7217 :                                 test();
    4946        7217 :                                 test();
    4947        7217 :                                 test();
    4948        7217 :                                 IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( meanLtpGain_fx, 19660 /* 0.6 in Q15*/ ) )
    4949             :                                 {
    4950             : 
    4951        6555 :                                     sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
    4952        6555 :                                     move16();
    4953             :                                     /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    4954             :                                     this may result in crash later. Changing the filter type here so the order is taken here in further section */
    4955        6555 :                                     IF( pFilter[0]->order != 0 )
    4956             :                                     {
    4957        6555 :                                         pFilter[0]->filterType = TNS_FILTER_ON;
    4958        6555 :                                         move16();
    4959             :                                     }
    4960             :                                     ELSE
    4961             :                                     {
    4962           0 :                                         pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
    4963           0 :                                         move16();
    4964             :                                     }
    4965        6555 :                                     sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
    4966        6555 :                                     move16();
    4967        6555 :                                     IF( pFilter[1]->order != 0 )
    4968             :                                     {
    4969        6555 :                                         pFilter[1]->filterType = TNS_FILTER_ON;
    4970        6555 :                                         move16();
    4971             :                                     }
    4972             :                                     ELSE
    4973             :                                     {
    4974           0 :                                         pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
    4975           0 :                                         move16();
    4976             :                                     }
    4977             :                                 }
    4978             :                                 ELSE
    4979             :                                 {
    4980             :                                     Word16 maxEnergyChange_fx;
    4981         662 :                                     maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 );
    4982             : 
    4983         662 :                                     IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) )
    4984             :                                     {
    4985         652 :                                         sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
    4986         652 :                                         move16();
    4987             :                                         /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    4988             :                                         this may result in crash later. Changing the filter type here so the order is taken here in further section */
    4989         652 :                                         IF( pFilter[0]->order != 0 )
    4990             :                                         {
    4991         652 :                                             pFilter[0]->filterType = TNS_FILTER_ON;
    4992         652 :                                             move16();
    4993             :                                         }
    4994             :                                         ELSE
    4995             :                                         {
    4996           0 :                                             pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
    4997           0 :                                             move16();
    4998             :                                         }
    4999         652 :                                         sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
    5000         652 :                                         move16();
    5001         652 :                                         IF( pFilter[1]->order != 0 )
    5002             :                                         {
    5003         652 :                                             pFilter[1]->filterType = TNS_FILTER_ON;
    5004         652 :                                             move16();
    5005             :                                         }
    5006             :                                         ELSE
    5007             :                                         {
    5008           0 :                                             pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
    5009           0 :                                             move16();
    5010             :                                         }
    5011             :                                     }
    5012             :                                     ELSE
    5013             :                                     {
    5014          10 :                                         pFilter[0]->filterType = TNS_FILTER_OFF;
    5015          10 :                                         move16();
    5016          10 :                                         pFilter[1]->filterType = TNS_FILTER_OFF;
    5017          10 :                                         move16();
    5018             :                                     }
    5019             :                                 }
    5020             :                             }
    5021      200323 :                             ELSE IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
    5022             :                             {
    5023         226 :                                 pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
    5024         226 :                                 pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
    5025         226 :                                 move16();
    5026         226 :                                 move16();
    5027         226 :                                 sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
    5028         226 :                                 move16();
    5029         226 :                                 sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
    5030         226 :                                 move16();
    5031             :                             }
    5032      200097 :                             ELSE IF( NE_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) /* sanity check */
    5033             :                             {
    5034           0 :                                 assert( 0 );
    5035             :                             }
    5036             :                             ELSE
    5037             :                             {
    5038      200097 :                                 pFilter[0]->filterType = TNS_FILTER_OFF;
    5039      200097 :                                 move16();
    5040      200097 :                                 pFilter[1]->filterType = TNS_FILTER_OFF;
    5041      200097 :                                 move16();
    5042             :                             }
    5043             : 
    5044      207540 :                             test();
    5045      207540 :                             test();
    5046      207540 :                             IF( EQ_16( pFilter[0]->filterType, TNS_FILTER_ON ) && EQ_16( pFilter[1]->filterType, TNS_FILTER_ON ) && LT_32( sts[0]->element_brate, IVAS_80k ) )
    5047             :                             {
    5048        6090 :                                 Word16 tmpIntValue = 0;
    5049        6090 :                                 move16();
    5050             :                                 Word16 tmpCoeff[TNS_MAX_FILTER_ORDER];
    5051        6090 :                                 Word16 i, maxOrder = s_max( pFilter[0]->order, pFilter[1]->order );
    5052             : 
    5053        6090 :                                 set16_fx( tmpCoeff, 0, TNS_MAX_FILTER_ORDER );
    5054       46270 :                                 FOR( i = 0; i < maxOrder; i++ )
    5055             :                                 {
    5056       40180 :                                     tmpIntValue = s_max( tmpIntValue, abs_s( sub( pFilter[0]->coefIndex[i], pFilter[1]->coefIndex[i] ) ) );
    5057             :                                 }
    5058             : 
    5059        6090 :                                 IF( EQ_16( tmpIntValue, 1 ) ) /* the TNS coefficients are sufficiently similar to equalize the two filters */
    5060             :                                 {
    5061       27835 :                                     FOR( i = maxOrder - 1; i >= 0; i-- )
    5062             :                                     {
    5063       24193 :                                         IF( LT_16( abs_s( pFilter[0]->coefIndex[i] ), abs_s( pFilter[1]->coefIndex[i] ) ) )
    5064             :                                         {
    5065        4457 :                                             tmpCoeff[i] = pFilter[0]->coefIndex[i];
    5066             :                                         }
    5067             :                                         ELSE
    5068             :                                         {
    5069       19736 :                                             tmpCoeff[i] = pFilter[1]->coefIndex[i];
    5070             :                                         }
    5071       24193 :                                         move16();
    5072       24193 :                                         IF( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) )
    5073             :                                         {
    5074        5923 :                                             maxOrder = sub( maxOrder, 1 );
    5075             :                                         }
    5076             :                                         ELSE
    5077             :                                         {
    5078       18270 :                                             tmpIntValue = 0;
    5079       18270 :                                             move16();
    5080             :                                         }
    5081             :                                     }
    5082             :                                     /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */
    5083        3642 :                                     IF( maxOrder > 0 )
    5084             :                                     {
    5085       32778 :                                         FOR( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- )
    5086             :                                         {
    5087       29136 :                                             pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i];
    5088       29136 :                                             move16();
    5089       29136 :                                             move16();
    5090             :                                         }
    5091             : 
    5092        3642 :                                         pFilter[0]->order = pFilter[1]->order = maxOrder;
    5093        3642 :                                         move16();
    5094        3642 :                                         move16();
    5095             :                                     }
    5096             : #ifdef FIX_1349_TNS_CRASH
    5097             :                                     ELSE
    5098             :                                     {
    5099           0 :                                         pFilter[0]->filterType = TNS_FILTER_OFF;
    5100           0 :                                         pFilter[1]->filterType = TNS_FILTER_OFF;
    5101           0 :                                         sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
    5102           0 :                                         sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
    5103           0 :                                         move16();
    5104           0 :                                         move16();
    5105           0 :                                         move16();
    5106           0 :                                         move16();
    5107             :                                     }
    5108             : #endif
    5109             :                                 }
    5110             :                             }
    5111             :                         }
    5112             :                         ELSE
    5113             :                         {
    5114      105133 :                             individual_decision[k] = 1;
    5115      105133 :                             move16();
    5116             :                         }
    5117             :                     }
    5118             : 
    5119      167092 :                     IF( individual_decision[k] == 0 )
    5120             :                     {
    5121       82918 :                         IF( ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) )
    5122             :                         {
    5123        3489 :                             sts[0]->hTcxEnc->fUseTns[k] = 1;
    5124             :                         }
    5125             :                         ELSE
    5126             :                         {
    5127       79429 :                             sts[0]->hTcxEnc->fUseTns[k] = 0;
    5128             :                         }
    5129       82918 :                         move16();
    5130             : 
    5131       82918 :                         IF( ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) )
    5132             :                         {
    5133        3489 :                             sts[1]->hTcxEnc->fUseTns[k] = 1;
    5134             :                         }
    5135             :                         ELSE
    5136             :                         {
    5137       79429 :                             sts[1]->hTcxEnc->fUseTns[k] = 0;
    5138             :                         }
    5139       82918 :                         move16();
    5140             :                     }
    5141             :                     ELSE
    5142             :                     {
    5143       84174 :                         sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
    5144       84174 :                         move16();
    5145       84174 :                         sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
    5146       84174 :                         move16();
    5147       84174 :                         sts[0]->hTcxEnc->fUseTns[k] = 0;
    5148       84174 :                         move16();
    5149       84174 :                         sts[1]->hTcxEnc->fUseTns[k] = 0;
    5150       84174 :                         move16();
    5151      245081 :                         FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5152             :                         {
    5153      160907 :                             sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
    5154      160907 :                             move16();
    5155      160907 :                             sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
    5156      160907 :                             move16();
    5157             :                         }
    5158             :                     }
    5159             : 
    5160      167092 :                     test();
    5161      167092 :                     test();
    5162      167092 :                     test();
    5163      167092 :                     IF( !bWhitenedDomain && individual_decision[k] == 0 &&
    5164             :                         LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) &&
    5165             :                         NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) )
    5166             :                     {
    5167       40796 :                         sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
    5168       40796 :                         move16();
    5169       40796 :                         sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
    5170       40796 :                         move16();
    5171       40796 :                         sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
    5172       40796 :                         move16();
    5173       40796 :                         sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
    5174       40796 :                         move16();
    5175       40796 :                         sts[0]->hTcxEnc->fUseTns[k] = 0;
    5176       40796 :                         move16();
    5177       40796 :                         sts[1]->hTcxEnc->fUseTns[k] = 0;
    5178       40796 :                         move16();
    5179      115480 :                         FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5180             :                         {
    5181       74684 :                             ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter );
    5182       74684 :                             ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter );
    5183             :                         }
    5184             :                     }
    5185             : 
    5186             :                     /* maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); */
    5187      167092 :                     IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* exp: maxPredGain_e */
    5188             :                     {
    5189           0 :                         maxPredictionGain_fx = maxPredGain_fx;
    5190           0 :                         maxPredictionGain_e = maxPredGain_e;
    5191           0 :                         move32();
    5192           0 :                         move16();
    5193             :                     }
    5194             :                 }
    5195             :             }
    5196             :         }
    5197             :     }
    5198             : 
    5199             :     /* individual decision for each channel */
    5200     2136546 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5201             :     {
    5202     1424364 :         IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    5203             :         {
    5204      128194 :             CONTINUE;
    5205             :         }
    5206             : 
    5207             :         Word8 isTCX10;
    5208             : 
    5209     1296170 :         IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
    5210             :         {
    5211     1266530 :             nSubframes = 1;
    5212     1266530 :             isTCX10 = 0;
    5213             :         }
    5214             :         ELSE
    5215             :         {
    5216       29640 :             nSubframes = NB_DIV;
    5217       29640 :             isTCX10 = 1;
    5218             :         }
    5219     1296170 :         move16();
    5220     1296170 :         move16();
    5221             : 
    5222     2621980 :         FOR( k = 0; k < nSubframes; k++ )
    5223             :         {
    5224     1325810 :             test();
    5225     1325810 :             test();
    5226     1325810 :             test();
    5227     1325810 :             test();
    5228     1325810 :             IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) &&
    5229             :                 ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    5230             :             {
    5231     1137701 :                 Word32 maxPredGain_fx = -ONE_IN_Q31; // Q31
    5232     1137701 :                 move32();
    5233     1137701 :                 Word16 maxPredGain_e = 0;
    5234     1137701 :                 move16();
    5235     1137701 :                 sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
    5236             : 
    5237     3320266 :                 FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5238             :                 {
    5239             :                     STnsFilter *pFilter;
    5240             :                     struct TnsParameters const *pTnsParameters;
    5241     2182565 :                     pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
    5242     2182565 :                     pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
    5243             : 
    5244             :                     // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 );
    5245     2182565 :                     IF( GT_32( pFilter->predictionGain32, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, pFilter->predictionGain_e ) ) ) ) /* pFilter->predictionGain_e */
    5246             :                     {
    5247     1487492 :                         maxPredGain_fx = pFilter->predictionGain32;
    5248     1487492 :                         maxPredGain_e = pFilter->predictionGain_e;
    5249     1487492 :                         move32();
    5250     1487492 :                         move16();
    5251             :                     }
    5252             : 
    5253     2182565 :                     test();
    5254     2182565 :                     IF( GT_32( pFilter->predictionGain32, L_shl_sat( ( pTnsParameters->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter->predictionGain_e ) ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) )
    5255             :                     {
    5256      134925 :                         test();
    5257      134925 :                         test();
    5258      134925 :                         IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( sts[ch]->hTcxEnc->tcxltp_gain, 19660 /*.6f in Q15*/ ) )
    5259             :                         {
    5260      115838 :                             sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
    5261      115838 :                             move16();
    5262             :                             /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    5263             :                             this may result in crash later. Changing the filter type here so the order is taken here in further section */
    5264      115838 :                             IF( pFilter->order != 0 )
    5265             :                             {
    5266      115838 :                                 pFilter->filterType = TNS_FILTER_ON;
    5267      115838 :                                 move16();
    5268             :                             }
    5269             :                             ELSE
    5270             :                             {
    5271           0 :                                 pFilter->filterType = TNS_FILTER_ON_ZERO;
    5272           0 :                                 move16();
    5273             :                             }
    5274             :                         }
    5275             :                         ELSE
    5276             :                         {
    5277       19087 :                             Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 );
    5278             : 
    5279       19087 :                             IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) )
    5280             :                             {
    5281       17982 :                                 sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
    5282       17982 :                                 move16();
    5283             :                                 /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    5284             :                                 this may result in crash later. Changing the filter type here so the order is taken here in further section */
    5285       17982 :                                 IF( pFilter->order != 0 )
    5286             :                                 {
    5287       17982 :                                     pFilter->filterType = TNS_FILTER_ON;
    5288       17982 :                                     move16();
    5289             :                                 }
    5290             :                                 ELSE
    5291             :                                 {
    5292           0 :                                     pFilter->filterType = TNS_FILTER_ON_ZERO;
    5293           0 :                                     move16();
    5294             :                                 }
    5295             :                             }
    5296             :                             ELSE
    5297             :                             {
    5298        1105 :                                 pFilter->filterType = TNS_FILTER_OFF;
    5299        1105 :                                 move16();
    5300             :                             }
    5301             :                         }
    5302             :                     }
    5303     2047640 :                     ELSE IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
    5304             :                     {
    5305       12891 :                         pFilter->filterType = TNS_FILTER_ON_ZERO;
    5306       12891 :                         move16();
    5307       12891 :                         sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
    5308       12891 :                         move16();
    5309             :                     }
    5310             :                     ELSE
    5311             :                     {
    5312     2034749 :                         pFilter->filterType = TNS_FILTER_OFF;
    5313     2034749 :                         move16();
    5314             :                     }
    5315             :                 }
    5316             : 
    5317     1137701 :                 sts[ch]->hTcxEnc->fUseTns[k] = 0;
    5318     1137701 :                 move16();
    5319     1137701 :                 if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 )
    5320             :                 {
    5321      123195 :                     sts[ch]->hTcxEnc->fUseTns[k] = 1;
    5322      123195 :                     move16();
    5323             :                 }
    5324             : 
    5325     1137701 :                 test();
    5326     1137701 :                 test();
    5327     1137701 :                 IF( !bWhitenedDomain && LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) )
    5328             :                 {
    5329      563308 :                     sts[ch]->hTcxEnc->fUseTns[k] = 0;
    5330      563308 :                     move16();
    5331      563308 :                     sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
    5332      563308 :                     move16();
    5333      563308 :                     sts[ch]->hTcxEnc->tnsData[k].nFilters = 0;
    5334      563308 :                     move16();
    5335     1643074 :                     FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5336             :                     {
    5337     1079766 :                         ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
    5338     1079766 :                         sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
    5339     1079766 :                         move16();
    5340             :                     }
    5341             :                 }
    5342             : 
    5343             :                 // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx );
    5344     1137701 :                 IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* maxPredGain_e */
    5345             :                 {
    5346      820035 :                     maxPredictionGain_fx = maxPredGain_fx;
    5347      820035 :                     maxPredictionGain_e = maxPredGain_e;
    5348      820035 :                     move32();
    5349      820035 :                     move16();
    5350             :                 }
    5351             :             }
    5352             :         }
    5353             :     }
    5354             : 
    5355             : 
    5356             :     /* we have the decision, set filter data accordingly */
    5357     2136546 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5358             :     {
    5359     1424364 :         IF( EQ_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    5360             :         {
    5361      128194 :             CONTINUE;
    5362             :         }
    5363             : 
    5364     1296170 :         IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
    5365             :         {
    5366     1266530 :             nSubframes = 1;
    5367             :         }
    5368             :         ELSE
    5369             :         {
    5370       29640 :             nSubframes = NB_DIV;
    5371             :         }
    5372     1296170 :         move16();
    5373     2621980 :         FOR( k = 0; k < nSubframes; k++ )
    5374             :         {
    5375     1325810 :             test();
    5376     1325810 :             test();
    5377     1325810 :             IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    5378             :             {
    5379     1303537 :                 sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
    5380             : 
    5381     3789634 :                 FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5382             :                 {
    5383             :                     STnsFilter *pFilter;
    5384     2486097 :                     pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
    5385     2486097 :                     SWITCH( pFilter->filterType )
    5386             :                     {
    5387     2391367 :                         case TNS_FILTER_OFF:
    5388     2391367 :                             ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
    5389     2391367 :                             BREAK;
    5390        9839 :                         case TNS_FILTER_ON_ZERO:
    5391             :                             /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */
    5392        9839 :                             ClearTnsFilterCoefficients( pFilter );
    5393        9839 :                             pFilter->order = 1;
    5394        9839 :                             move16();
    5395        9839 :                             BREAK;
    5396             :                     }
    5397     2486097 :                 }
    5398             :             }
    5399             :         }
    5400             :     }
    5401             : 
    5402             :     /* Apply filters, loop over channels */
    5403     2136546 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5404             :     {
    5405     1424364 :         st = sts[ch];
    5406     1424364 :         IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    5407             :         {
    5408      128194 :             CONTINUE;
    5409             :         }
    5410             : 
    5411     1296170 :         IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
    5412             :         {
    5413     1266530 :             nSubframes = 1;
    5414             :         }
    5415             :         ELSE
    5416             :         {
    5417       29640 :             nSubframes = NB_DIV;
    5418             :         }
    5419     1296170 :         move16();
    5420             : 
    5421     2621980 :         FOR( k = 0; k < nSubframes; k++ )
    5422             :         {
    5423     1325810 :             test();
    5424     1325810 :             test();
    5425     1325810 :             test();
    5426     1325810 :             test();
    5427     1325810 :             test();
    5428     1325810 :             IF( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */
    5429             :                 sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] &&
    5430             :                 sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] )
    5431             :             {
    5432       18925 :                 Word16 equalFilterData = 0;
    5433       18925 :                 move16();
    5434       18925 :                 test();
    5435       18925 :                 test();
    5436       37836 :                 if ( EQ_16( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ) &&
    5437       35500 :                      EQ_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) &&
    5438       16589 :                      EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) )
    5439             :                 {
    5440       15193 :                     equalFilterData = 1;
    5441       15193 :                     move16();
    5442             :                 }
    5443             : 
    5444       18925 :                 IF( equalFilterData )
    5445             :                 {
    5446       31221 :                     FOR( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5447             :                     {
    5448       26926 :                         const Word16 *pDataCh0 = (const Word16 *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter];
    5449       26926 :                         const Word16 *pDataCh1 = (const Word16 *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter];
    5450       26926 :                         Word16 i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */
    5451             : 
    5452       26926 :                         move16();
    5453       26926 :                         test();
    5454      227369 :                         WHILE( ( i >= 0 ) && EQ_16( pDataCh0[i], pDataCh1[i] ) )
    5455             :                         {
    5456      200443 :                             test();
    5457      200443 :                             i = sub( i, 1 );
    5458             :                         }
    5459       26926 :                         IF( i >= 0 )
    5460             :                         {
    5461       10898 :                             equalFilterData = 0;
    5462       10898 :                             move16();
    5463       10898 :                             BREAK;
    5464             :                         }
    5465             :                     }
    5466       15193 :                     IF( equalFilterData )
    5467             :                     {
    5468        4295 :                         st->hTcxEnc->tnsData[k].nFilters = i_mult( st->hTcxEnc->tnsData[k].nFilters, -1 ); /* signals common TNS */
    5469        4295 :                         move16();
    5470             :                     }
    5471             :                 }
    5472             :             }
    5473     1325810 :             test();
    5474     1325810 :             test();
    5475     1325810 :             IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    5476             :             {
    5477     1303537 :                 L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
    5478     1303537 :                 move16();
    5479     1303537 :                 spectrum_fx = st->hTcxEnc->spectrum_fx[k];
    5480             :                 /* If TNS should be used then get the residual after applying it inplace in the spectrum */
    5481     1303537 :                 IF( st->hTcxEnc->fUseTns[k] )
    5482             :                 {
    5483       73159 :                     st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
    5484             : 
    5485       73159 :                     ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum_fx, 1 );
    5486             :                 }
    5487             : 
    5488     1303537 :                 IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) )
    5489             :                 {
    5490       15311 :                     tcx5TnsUngrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), st->hTcxEnc->spectrum_fx[k], ENC );
    5491             :                 }
    5492             : 
    5493     1303537 :                 st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k];
    5494     1303537 :                 move16();
    5495     1303537 :                 EncodeTnsData_ivas_fx( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k );
    5496             :             }
    5497             : 
    5498     1325810 :             IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) )
    5499             :             {
    5500       30622 :                 tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[k] );
    5501       30622 :                 tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][k] );
    5502             :             }
    5503             :         }
    5504             :     }
    5505      712182 :     return;
    5506             : }

Generated by: LCOV version 1.14