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

Generated by: LCOV version 1.14