LCOV - code coverage report
Current view: top level - lib_enc - cod_tcx_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ b9bfbe380d1c207f5198ba67a82398b3d313550e Lines: 2132 2607 81.8 %
Date: 2025-11-16 02:22:47 Functions: 16 17 94.1 %

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

Generated by: LCOV version 1.14