LCOV - code coverage report
Current view: top level - lib_enc - cod_tcx_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 2125 2600 81.7 %
Date: 2025-05-03 01:55:50 Functions: 16 17 94.1 %

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

Generated by: LCOV version 1.14