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 @ a00cb1a4e00ddb5714e6edf7a8c2107a29ea8765 Lines: 2110 2600 81.2 %
Date: 2025-07-09 01:57:24 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      108924 : 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      108924 :     Flag Overflow = 0;
      46      108924 :     move32();
      47             : #endif
      48             : 
      49             :     /*-----------------------------------------------------------*
      50             :      * Windowing                                                 *
      51             :      *-----------------------------------------------------------*/
      52             : 
      53      108924 :     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      108924 :     len = add( L_frame, shr( add( left_overlap, right_overlap ), 1 ) );
      60             : 
      61             :     /* calculate shift */
      62      108924 :     shift = 0;
      63      108924 :     move16();
      64      108924 :     L_sum = L_deposit_l( 0 );
      65      108924 :     Overflow = 0;
      66      108924 :     move32();
      67    96653501 :     FOR( i = 0; i < len; i += 1 )
      68             :     {
      69             :         /* Test Addition */
      70    96544579 :         L_mac0_o( L_sum, y[i], y[i], &Overflow );
      71    96544579 :         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    96544577 :         L_sum = L_mac0_o( L_sum, y[i], y[i], &Overflow );
     102             :     }
     103             : 
     104             :     /* scale signal to avoid overflow in autocorrelation */
     105      108924 :     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      108924 :     L_sum = L_mac0( 1, y[0], y[0] );
     117    96544952 :     FOR( i = 1; i < len; i++ )
     118             :     {
     119    96436028 :         L_sum = L_mac0( L_sum, y[i], y[i] );
     120             :     }
     121             : 
     122      108924 :     norm = norm_l( L_sum );
     123      108924 :     L_sum = L_shl( L_sum, norm );
     124      108924 :     r[0] = L_sum;
     125      108924 :     move32();
     126             : 
     127             :     /* Compute r[1] to r[m] */
     128     1851708 :     FOR( i = 1; i <= m; i++ )
     129             :     {
     130     1742784 :         L_sum = L_mult0( y[0], y[i] );
     131  1529905568 :         FOR( j = 1; j < len - i; j++ )
     132             :         {
     133  1528162784 :             L_sum = L_mac0( L_sum, y[j], y[j + i] );
     134             :         }
     135             : 
     136     1742784 :         L_sum = L_shl( L_sum, norm );
     137     1742784 :         r[i] = L_sum;
     138     1742784 :         move32();
     139             :     }
     140      108924 : }
     141             : 
     142         376 : 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         376 :     Word16 tmp = 0;  /* initialization only to avoid compiler warning, not counted */
     156         376 :     Word16 tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
     157         376 :     move16();
     158         376 :     move16();
     159             : 
     160             :     /* Init TNS */
     161         376 :     *pfUseTns = 0;
     162         376 :     move16();
     163             : 
     164         376 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
     165             :     {
     166         376 :         hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( tcxMode - TCX_20 ) == 0][isAfterACELP];
     167         376 :         L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
     168         376 :         move16();
     169             : 
     170             :         /*-----------------------------------------------------------*
     171             :          * Temporal Noise Shaping analysis                           *
     172             :          *-----------------------------------------------------------*/
     173             : 
     174         376 :         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         376 :         move16();
     196         376 :         *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         376 :         IF( *pfUseTns != 0 )
     200             :         {
     201           4 :             ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
     202             :         }
     203             : 
     204         376 :         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         376 : }
     224             : 
     225      238326 : 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      238326 :     Word16 tmp = 0;  /* initialization only to avoid compiler warning, not counted */
     241      238326 :     Word16 tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
     242      238326 :     move16();
     243      238326 :     move16();
     244             : 
     245             :     /* Init TNS */
     246      238326 :     *pfUseTns = 0;
     247      238326 :     move16();
     248             : 
     249      238326 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
     250             :     {
     251      161512 :         hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( transform_type - TCX_20 ) == 0][isAfterACELP];
     252      161512 :         L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
     253      161512 :         move16();
     254             : 
     255             :         /*-----------------------------------------------------------*
     256             :          * Temporal Noise Shaping analysis                           *
     257             :          *-----------------------------------------------------------*/
     258             : 
     259      161512 :         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      161512 :         move16();
     281      161512 :         *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      161512 :         IF( *pfUseTns != 0 )
     285             :         {
     286       17618 :             ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
     287             :         }
     288             : 
     289      161512 :         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      238326 : }
     309             : 
     310         637 : 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         637 :     Word32 max_low_pre = 0, max_high_pre = 0;
     328         637 :     move32();
     329         637 :     move32();
     330         637 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     331             : 
     332             :     /*-----------------------------------------------------------*
     333             :      * Init                                                      *
     334             :      *-----------------------------------------------------------*/
     335             : 
     336             :     /* Init lengths */
     337         637 :     L_frame = L_frame_glob;
     338         637 :     move16();
     339         637 :     gamma1 = st->gamma;
     340         637 :     move16();
     341         637 :     if ( st->enableTcxLpc != 0 )
     342             :     {
     343           0 :         gamma1 = 0x7FFF;
     344           0 :         move16();
     345             :     }
     346             : 
     347             :     /* if past frame is ACELP */
     348             : 
     349         637 :     IF( st->last_core == ACELP_CORE )
     350             :     {
     351          34 :         L_frame = add( L_frame, hTcxCfg->tcx_offset );
     352          34 :         L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
     353          34 :         if ( hTcxCfg->lfacNext < 0 )
     354             :         {
     355          34 :             L_frame = sub( L_frame, hTcxCfg->lfacNext );
     356          34 :             move16();
     357             :         }
     358             :     }
     359             : 
     360         637 :     test();
     361         637 :     tcxGetNoiseFillingTilt( A,
     362             :                             M,
     363             :                             L_frame,
     364         637 :                             ( 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         637 :     IF( st->enablePlcWaveadjust )
     369             :     {
     370           0 :         hTcxCfg->SFM2 = SFM_Cal_fx( spectrum, s_min( 200, L_frame ) );
     371           0 :         move32();
     372             :     }
     373             : 
     374         637 :     test();
     375         637 :     test();
     376         637 :     test();
     377         637 :     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         261 :         max_low_pre = 0;
     381         261 :         move32();
     382       67781 :         FOR( i = 0; i < L_frame; i++ )
     383             :         {
     384       67520 :             Word32 tmp = L_abs( spectrum[i] );
     385       67520 :             if ( GT_32( tmp, max_low_pre ) )
     386             :             {
     387        1624 :                 max_low_pre = tmp;
     388        1624 :                 move32();
     389             :             }
     390             :         }
     391             : 
     392         261 :         max_high_pre = 0;
     393         261 :         move32();
     394      101541 :         FOR( i = 0; i < L_spec - L_frame; i++ )
     395             :         {
     396      101280 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     397      101280 :             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         637 :     weight_a_fx( A, Ap, gamma1, M );
     410             : 
     411         637 :     lpc2mdct( Ap, M, gainlpc_noinv, gainlpc_noinv_e, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
     412             : 
     413         637 :     mdct_shaping( spectrum, L_frame, gainlpc_noinv, gainlpc_noinv_e );
     414      224077 :     FOR( i = L_frame; i < L_spec; i++ )
     415             :     {
     416      223440 :         spectrum[i] = L_shl( Mpy_32_16_1( spectrum[i], gainlpc_noinv[FDNS_NPTS - 1] ), gainlpc_noinv_e[FDNS_NPTS - 1] );
     417      223440 :         move32();
     418             :     }
     419             : 
     420             :     /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
     421         637 :     test();
     422         637 :     test();
     423         637 :     test();
     424         637 :     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         261 :         max_fac_m = 24576;
     435         261 :         move16();
     436             :         /* max_fac = 3 */
     437         261 :         max_fac_s = 2;
     438         261 :         move16();
     439         261 :         if ( hTcxEnc->tcx_lpc_shaped_ari )
     440             :         {
     441             :             /* max_fac = 1.5 */
     442           0 :             max_fac_s = 1;
     443           0 :             move16();
     444             :         }
     445             : 
     446         261 :         sf_width = shr( L_frame, 1 );
     447             : 
     448         261 :         max_low2 = 0;
     449         261 :         move32();
     450         261 :         dist_low = 0;
     451         261 :         move16();
     452       34021 :         FOR( i = 0; i < sf_width; i++ )
     453             :         {
     454       33760 :             Word32 tmp = L_abs( spectrum[L_frame - 1 - i] );
     455       33760 :             IF( GT_32( tmp, max_low2 ) )
     456             :             {
     457        1499 :                 max_low2 = tmp;
     458        1499 :                 move32();
     459        1499 :                 dist_low = i;
     460        1499 :                 move16();
     461             :             }
     462             :         }
     463             : 
     464         261 :         max_low1 = 0;
     465         261 :         move32();
     466       34021 :         FOR( i = 0; i < ( L_frame - sf_width ); i++ )
     467             :         {
     468       33760 :             Word32 tmp = L_abs( spectrum[L_frame - sf_width - 1 - i] );
     469       33760 :             if ( GT_32( tmp, max_low1 ) )
     470             :             {
     471        2327 :                 max_low1 = tmp;
     472        2327 :                 move32();
     473             :             }
     474       33760 :             if ( GT_32( tmp, max_low2 ) )
     475             :             {
     476        3688 :                 dist_low = add( sf_width, i );
     477             :             }
     478             :         }
     479             : 
     480         261 :         max_low = L_max( max_low1, max_low2 );
     481             : 
     482         261 :         max_high = 0;
     483         261 :         move32();
     484         261 :         dist_high = 0;
     485         261 :         move16();
     486      101541 :         FOR( i = 0; i < ( L_spec - L_frame ); i++ )
     487             :         {
     488      101280 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     489      101280 :             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         261 :         shift = 0;
     500         261 :         move16();
     501         261 :         headroom = 31;
     502         261 :         move16();
     503             : 
     504         261 :         tmp16 = norm_l( max_low );
     505         261 :         if ( max_low != 0 )
     506         261 :             headroom = s_min( headroom, tmp16 );
     507             : 
     508         261 :         tmp16 = norm_l( max_low2 );
     509         261 :         if ( max_low2 != 0 )
     510         261 :             headroom = s_min( headroom, tmp16 );
     511             : 
     512         261 :         tmp16 = norm_l( max_high );
     513         261 :         if ( max_high != 0 )
     514           1 :             headroom = s_min( headroom, tmp16 );
     515             : 
     516         261 :         if ( LT_16( headroom, 9 ) )
     517             :         {
     518           0 :             shift = sub( 9, headroom );
     519             :         }
     520         261 :         max_low = L_shr( max_low, shift );
     521         261 :         max_low2 = L_shr( max_low2, shift );
     522         261 :         max_high = L_shr( max_high, shift );
     523             : 
     524         261 :         test();
     525         261 :         test();
     526         261 :         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         637 :     test();
     542         637 :     test();
     543         637 :     test();
     544         637 :     IF( st->tcxonly && hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !pfUseTns )
     545             :     {
     546           0 :         PsychAdaptLowFreqEmph_fx( spectrum, gainlpc, gainlpc_e );
     547             :     }
     548         637 : }
     549     1417407 : 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     1417407 :     Word32 max_low_pre = 0, max_high_pre = 0;
     572     1417407 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     573     1417407 :     move32();
     574     1417407 :     move32();
     575     1417407 :     Word32 total_brate = st->total_brate;
     576     1417407 :     move32();
     577     1417407 :     if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
     578             :     {
     579     1179081 :         total_brate = st->element_brate;
     580     1179081 :         move32();
     581             :     }
     582             : 
     583             :     /*-----------------------------------------------------------*
     584             :      * Init                                                      *
     585             :      *-----------------------------------------------------------*/
     586             : 
     587             :     /* Init lengths */
     588     1417407 :     L_frame = L_frame_glob;
     589     1417407 :     move16();
     590     1417407 :     gamma1 = st->gamma;
     591     1417407 :     move16();
     592     1417407 :     if ( st->enableTcxLpc != 0 )
     593             :     {
     594       17462 :         gamma1 = 0x7FFF;
     595       17462 :         move16();
     596             :     }
     597             : 
     598             :     /* if past frame is ACELP */
     599     1417407 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) /* in MDCT, this is already done outside the function */
     600             :     {
     601      238326 :         IF( st->last_core == ACELP_CORE )
     602             :         {
     603        7859 :             L_frame = add( L_frame, hTcxCfg->tcx_offset );
     604        7859 :             L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
     605        7859 :             if ( hTcxCfg->lfacNext < 0 )
     606             :             {
     607        7859 :                 L_frame = sub( L_frame, hTcxCfg->lfacNext );
     608        7859 :                 move16();
     609             :             }
     610             :         }
     611             :     }
     612             : 
     613     1417407 :     test();
     614     1417407 :     tcxGetNoiseFillingTilt( A,
     615             :                             M,
     616             :                             L_frame,
     617     1417407 :                             ( GE_32( total_brate, ACELP_13k20 ) && st->rf_mode == 0 ),
     618             :                             &hTcxEnc->noiseTiltFactor );
     619             : 
     620             :     /* Calculate Spectrum Flatness Measure for the TCX Concealment */
     621     1417407 :     IF( st->enablePlcWaveadjust )
     622             :     {
     623           0 :         hTcxCfg->SFM2 = SFM_Cal_fx( spectrum, s_min( 200, L_frame ) );
     624           0 :         move32();
     625             :     }
     626             : 
     627     1417407 :     test();
     628     1417407 :     IF( LE_32( total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) )
     629             :     {
     630       31108 :         max_low_pre = 0;
     631       31108 :         move32();
     632     8135684 :         FOR( i = 0; i < L_frame; i++ )
     633             :         {
     634     8104576 :             Word32 tmp = L_abs( spectrum[i] );
     635     8104576 :             if ( GT_32( tmp, max_low_pre ) )
     636             :             {
     637      137640 :                 max_low_pre = tmp;
     638      137640 :                 move32();
     639             :             }
     640             :         }
     641             : 
     642       31108 :         max_high_pre = 0;
     643       31108 :         move32();
     644    12187972 :         FOR( i = 0; i < L_spec - L_frame; i++ )
     645             :         {
     646    12156864 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     647    12156864 :             if ( GT_32( tmp, max_high_pre ) )
     648             :             {
     649        2473 :                 max_high_pre = tmp;
     650        2473 :                 move32();
     651             :             }
     652             :         }
     653             :     }
     654             : 
     655     1417407 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
     656             :     {
     657             :         Word64 W_tmp;
     658             :         Word16 len;
     659     1179081 :         q_spectrum = sub( 31, *spectrum_e );
     660     1179081 :         sns_interpolate_scalefactors_fx( &sns_int_scf[0], scf, ENC );
     661     1179081 :         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     1179081 :         test();
     664     1179081 :         test();
     665     1179081 :         IF( NE_16( len, L_spec ) && LT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) )
     666             :         {
     667         120 :             scale_sig32( spectrum + len, sub( L_spec, len ), sub( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) ); // Q31
     668             :         }
     669     1178961 :         ELSE IF( NE_16( len, L_spec ) && GT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) )
     670             :         {
     671      948449 :             scale_sig32( spectrum, len, sub( sub( 31, *spectrum_e ), add( q_spectrum, 1 ) ) ); // Q(30-specturm_e)
     672      948449 :             q_spectrum = sub( 31 - 1, *spectrum_e );
     673             :         }
     674             : 
     675   296536377 :         FOR( i = L_frame; i < L_spec; i++ )
     676             :         {
     677   295357296 :             W_tmp = W_mult0_32_32( spectrum[i], sns_int_scf[hTcxCfg->psychParamsCurrent->nBands - 1] );
     678   295357296 :             spectrum[i] = W_extract_h( W_shl( W_tmp, Q16 ) );
     679   295357296 :             move32();
     680             :         }
     681     1179081 :         *spectrum_e = sub( 31 - 1, q_spectrum ); // As the output spectrum from sns_shape_spectrum_fx has Q = q_spectrum + 1
     682     1179081 :         move16();
     683             :     }
     684             :     ELSE
     685             :     {
     686             :         /*-----------------------------------------------------------*
     687             :          * Pre-shaping in frequency domain using weighted LPC (Wz)   *
     688             :          *-----------------------------------------------------------*/
     689             : 
     690      238326 :         weight_a_fx( A, Ap, gamma1, M );
     691             : 
     692      238326 :         lpc2mdct( Ap, M, gainlpc_noinv, gainlpc_noinv_e, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
     693             : 
     694      238326 :         mdct_shaping( spectrum, L_frame, gainlpc_noinv, gainlpc_noinv_e );
     695    93091686 :         FOR( i = L_frame; i < L_spec; i++ )
     696             :         {
     697    92853360 :             spectrum[i] = L_shl( Mpy_32_16_1( spectrum[i], gainlpc_noinv[FDNS_NPTS - 1] ), gainlpc_noinv_e[FDNS_NPTS - 1] );
     698    92853360 :             move32();
     699             :         }
     700             :     }
     701             : 
     702             :     /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
     703     1417407 :     test();
     704     1417407 :     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       31108 :         max_fac_m = 24576;
     714       31108 :         move16();
     715             :         /* max_fac = 3 */
     716       31108 :         max_fac_s = 2;
     717       31108 :         move16();
     718       31108 :         if ( hTcxEnc->tcx_lpc_shaped_ari )
     719             :         {
     720             :             /* max_fac = 1.5 */
     721       13422 :             max_fac_s = 1;
     722       13422 :             move16();
     723             :         }
     724             : 
     725       31108 :         sf_width = shr( L_frame, 1 );
     726             : 
     727       31108 :         max_low2 = 0;
     728       31108 :         move32();
     729       31108 :         dist_low = 0;
     730       31108 :         move16();
     731     4083396 :         FOR( i = 0; i < sf_width; i++ )
     732             :         {
     733     4052288 :             Word32 tmp = L_abs( spectrum[L_frame - 1 - i] );
     734     4052288 :             IF( GT_32( tmp, max_low2 ) )
     735             :             {
     736      187803 :                 max_low2 = tmp;
     737      187803 :                 move32();
     738      187803 :                 dist_low = i;
     739      187803 :                 move16();
     740             :             }
     741             :         }
     742             : 
     743       31108 :         max_low1 = 0;
     744       31108 :         move32();
     745     4083396 :         FOR( i = 0; i < sub( L_frame, sf_width ); i++ )
     746             :         {
     747     4052288 :             Word32 tmp = L_abs( spectrum[L_frame - sf_width - 1 - i] );
     748     4052288 :             if ( GT_32( tmp, max_low1 ) )
     749             :             {
     750      286021 :                 max_low1 = tmp;
     751      286021 :                 move32();
     752             :             }
     753     4052288 :             if ( GT_32( tmp, max_low2 ) )
     754             :             {
     755      556322 :                 dist_low = add( sf_width, i );
     756             :             }
     757             :         }
     758             : 
     759       31108 :         max_low = L_max( max_low1, max_low2 );
     760             : 
     761       31108 :         max_high = 0;
     762       31108 :         move32();
     763       31108 :         dist_high = 0;
     764       31108 :         move16();
     765    12187972 :         FOR( i = 0; i < ( L_spec - L_frame ); i++ )
     766             :         {
     767    12156864 :             Word32 tmp = L_abs( spectrum[L_frame + i] );
     768    12156864 :             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       31108 :         shift = 0;
     779       31108 :         move16();
     780       31108 :         headroom = 31;
     781       31108 :         move16();
     782             : 
     783       31108 :         tmp16 = norm_l( max_low );
     784       31108 :         if ( max_low != 0 )
     785       31104 :             headroom = s_min( headroom, tmp16 );
     786             : 
     787       31108 :         tmp16 = norm_l( max_low2 );
     788       31108 :         if ( max_low2 != 0 )
     789       31104 :             headroom = s_min( headroom, tmp16 );
     790             : 
     791       31108 :         tmp16 = norm_l( max_high );
     792       31108 :         if ( max_high != 0 )
     793         841 :             headroom = s_min( headroom, tmp16 );
     794             : 
     795       31108 :         if ( LT_16( headroom, 9 ) )
     796             :         {
     797       30037 :             shift = sub( 9, headroom );
     798             :         }
     799       31108 :         max_low = L_shr( max_low, shift );
     800       31108 :         max_low2 = L_shr( max_low2, shift );
     801       31108 :         max_high = L_shr( max_high, shift );
     802             : 
     803       31108 :         test();
     804       31108 :         test();
     805       31108 :         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     1417407 :     test();
     832     1417407 :     test();
     833     1417407 :     test();
     834     1417407 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) && st->tcxonly && hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !pfUseTns )
     835             :     {
     836        3721 :         PsychAdaptLowFreqEmph_fx( spectrum, gainlpc, gainlpc_e );
     837             :     }
     838     1417407 : }
     839             : 
     840             : /*-------------------------------------------------------------------*
     841             :  * GetTransWidth()
     842             :  *
     843             :  *
     844             :  *-------------------------------------------------------------------*/
     845             : 
     846     1044442 : 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     1044442 :     Word16 noiseTransWidth = MIN_NOISE_FILLING_HOLE;
     853     1044442 :     move16();
     854             : 
     855     1044442 :     IF( tcxonly )
     856             :     {
     857      786126 :         IF( hm_active )
     858             :         {
     859        8954 :             noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( tcxltp_gain, 10240 /*0.3125f Q15*/ ) );
     860             :         }
     861             :         ELSE
     862             :         {
     863      777172 :             noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( tcxltp_gain, 0 ) );
     864             :         }
     865             : 
     866      786126 :         if ( tcx10 )
     867             :         {
     868       33191 :             noiseTransWidth = 3; /* minimum transition for noise filling in TCX-10 */
     869       33191 :             move16();
     870             :         }
     871             :     }
     872             : 
     873     1044442 :     return noiseTransWidth;
     874             : }
     875             : 
     876             : /*-----------------------------------------------------------*
     877             :  * EstimateTCXNoiseLevel()
     878             :  *
     879             :  * Estimate and quantize noise factor                        *
     880             :  *-----------------------------------------------------------*/
     881             : 
     882      238326 : 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      238326 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     898             : 
     899      238326 :     maxNfCalcBw = s_min( noiseFillingBorder, round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame ), 1 ) ) );
     900             : 
     901      238326 :     IF( GE_32( st->total_brate, HQ_96k ) )
     902             :     {
     903       18140 :         *fac_ns = 0;
     904       18140 :         *fac_ns_q = 0;
     905       18140 :         move16();
     906       18140 :         move16();
     907             :     }
     908             :     ELSE
     909             :     {
     910             :         Word16 minLevel;
     911      220186 :         minLevel = 1;
     912      220186 :         move16();
     913      220186 :         test();
     914      220186 :         if ( hTcxEnc->tcx_lpc_shaped_ari && GT_16( st->element_mode, IVAS_SCE ) )
     915             :         {
     916        4721 :             minLevel = 0;
     917        4721 :             move16();
     918             :         }
     919             : 
     920             :         /* noise filling start bin */
     921      220186 :         iStart = shr( L_frame, 3 );
     922      220186 :         test();
     923      220186 :         IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
     924             :         {
     925      186991 :             iStart = idiv1616U( L_frame, 6 );
     926             :         }
     927             : 
     928      220186 :         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      220186 :         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      220186 :         IF( EQ_16( *fac_ns_q, minLevel ) )
     934             :         {
     935       12904 :             hTcxEnc->noiseLevelMemory_cnt = s_min( INT16_MAX, add( 1, abs_s( hTcxEnc->noiseLevelMemory_cnt ) ) ); /* update counter */
     936       12904 :             move16();
     937             :         }
     938             :         ELSE
     939             :         {
     940      207282 :             test();
     941      207282 :             IF( EQ_16( *fac_ns_q, add( minLevel, 1 ) ) && GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) )
     942             :             {
     943         788 :                 *fac_ns_q = minLevel; /* reduce noise filling level by one step */
     944         788 :                 *fac_ns = 0;
     945         788 :                 move16();
     946         788 :                 move16();
     947         788 :                 IF( minLevel != 0 )
     948             :                 {
     949         788 :                     *fac_ns = shr( 0x6000, NBITS_NOISE_FILL_LEVEL );
     950         788 :                     move16();
     951             :                 }
     952             :                 /* signal that noise level is changed by inverting sign of level memory */
     953         788 :                 IF( hTcxEnc->noiseLevelMemory_cnt < 0 )
     954             :                 {
     955         263 :                     hTcxEnc->noiseLevelMemory_cnt = 5;
     956         263 :                     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      206494 :                 hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
     967      206494 :                 move16();
     968             :             }
     969             :         }
     970             :     } /* bitrate */
     971             : 
     972      238326 :     return;
     973             : }
     974             : 
     975             : 
     976             : /*-------------------------------------------------------------------*
     977             :  * QuantizeSpectrum()
     978             :  *
     979             :  *
     980             :  *-------------------------------------------------------------------*/
     981             : 
     982      238326 : 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      238326 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1014             : 
    1015      238326 :     set32_fx( quantized_spectrum_fx, 0, N_MAX );
    1016             : 
    1017             :     /*-----------------------------------------------------------*
    1018             :      * Quantize the MDCT spectrum                                *
    1019             :      *-----------------------------------------------------------*/
    1020             : 
    1021      238326 :     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      238326 :     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      238326 :     Word16 s1 = sub( getScaleFactor32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame ), 6 );
    1031      238326 :     Word16 s2 = getScaleFactor32( quantized_spectrum_fx, s_max( L_frame, L_spec ) );
    1032      238326 :     Word16 max_e = s_max( sub( hTcxEnc->spectrum_e[frame_cnt], s1 ), sub( quantized_spectrum_e, s2 ) );
    1033             : 
    1034      238326 :     scale_sig32( quantized_spectrum_fx, s_max( L_frame, L_spec ), sub( quantized_spectrum_e, max_e ) );        // max_e
    1035      238326 :     scale_sig32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame, sub( hTcxEnc->spectrum_e[frame_cnt], max_e ) ); // max_e
    1036      238326 :     hTcxEnc->spectrum_e[frame_cnt] = max_e;
    1037      238326 :     move16();
    1038             : 
    1039             :     /*-----------------------------------------------------------*
    1040             :      * Estimate and quantize noise factor                        *
    1041             :      *-----------------------------------------------------------*/
    1042             : 
    1043      238326 :     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      238326 :     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      238326 :     st->L_frame_past = L_frame;
    1053      238326 :     move16();
    1054             : 
    1055             :     /* Update overlap */
    1056      238326 :     test();
    1057      238326 :     test();
    1058      238326 :     test();
    1059      238326 :     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        8834 :         st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
    1062        8834 :         move16();
    1063             :     }
    1064             : 
    1065             : 
    1066      238326 :     return;
    1067             : }
    1068             : 
    1069      343491 : 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      343491 :     set32_fx( combined_q_spectrum, 0, N_MAX );
    1091             : 
    1092     1030473 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    1093             :     {
    1094      686982 :         Encoder_State *st = sts[ch];
    1095      686982 :         TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1096             : 
    1097      686982 :         IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
    1098             :         {
    1099      673231 :             nSubframes = 1;
    1100      673231 :             move16();
    1101             :         }
    1102             :         ELSE
    1103             :         {
    1104       13751 :             nSubframes = NB_DIV;
    1105       13751 :             move16();
    1106             :         }
    1107             : 
    1108      686982 :         IF( ignore_chan[ch] )
    1109             :         {
    1110       76237 :             CONTINUE;
    1111             :         }
    1112             : 
    1113      610745 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag )
    1114             :         {
    1115      164646 :             total_brate = st->element_brate;
    1116      164646 :             move32();
    1117             :         }
    1118             :         ELSE
    1119             :         {
    1120      446099 :             total_brate = st->total_brate;
    1121      446099 :             move32();
    1122             :         }
    1123             : 
    1124     1235235 :         FOR( n = 0; n < nSubframes; n++ )
    1125             :         {
    1126      624490 :             fac_ns_q = param_core[ch] + add( i_mult( n, NPRM_DIV ), 1 );
    1127             : 
    1128      624490 :             maxNfCalcBw = s_min( noiseFillingBorder[ch][n], round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame[ch][n] ), 1 ) ) );
    1129             : 
    1130      624490 :             test();
    1131      624490 :             test();
    1132      624490 :             test();
    1133      624490 :             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       19931 :                 fac_ns[ch][n] = 0;
    1136       19931 :                 move16();
    1137       19931 :                 *fac_ns_q = 0;
    1138       19931 :                 move16();
    1139             :             }
    1140             :             ELSE
    1141             :             {
    1142      604559 :                 test();
    1143      604559 :                 IF( GE_32( total_brate, ACELP_13k20 ) && !st->rf_mode )
    1144             :                 {
    1145      593503 :                     iStart = idiv1616( L_frame[ch][n], 6 );
    1146             :                 }
    1147             :                 ELSE
    1148             :                 {
    1149       11056 :                     iStart = shr( L_frame[ch][n], 3 );
    1150             :                 }
    1151             : 
    1152      604559 :                 IF( n == 0 )
    1153             :                 {
    1154      591267 :                     Copy( hTcxEnc->ltpGainMemory_fx, &hTcxEnc->ltpGainMemory_fx[1], N_LTP_GAIN_MEMS - 1 );
    1155      591267 :                     hTcxEnc->ltpGainMemory_fx[0] = st->hTcxEnc->tcxltp_gain;
    1156      591267 :                     move16();
    1157             :                 }
    1158             : 
    1159      604559 :                 Word32 temp = L_mult0( hTcxEnc->ltpGainMemory_fx[0], nf_tw_smoothing_coeffs_fx[0] );
    1160             : 
    1161     2418236 :                 FOR( i = 1; i < N_LTP_GAIN_MEMS; i++ )
    1162             :                 {
    1163     1813677 :                     temp = L_mac0( temp, hTcxEnc->ltpGainMemory_fx[i], nf_tw_smoothing_coeffs_fx[i] );
    1164             :                 }
    1165      604559 :                 smooth_gain = round_fx( L_shl( temp, 1 ) );
    1166      604559 :                 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      604559 :                 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      604559 :                 maximum_abs_32_fx( hTcxEnc->spectrum_fx[n], L_frame[ch][n], &L_tmp );
    1173      604559 :                 maximum_abs_32_fx( combined_q_spectrum, L_frame[ch][n], &L_tmp1 );
    1174      604559 :                 test();
    1175      604559 :                 IF( L_tmp != 0 || L_tmp1 != 0 )
    1176             :                 {
    1177      604372 :                     scale_sig32( hTcxEnc->spectrum_fx[n], L_frame[ch][n], -Q1 ); // Q(31-(spectrum_e+1)
    1178      604372 :                     scale_sig32( combined_q_spectrum, L_frame[ch][n], -Q1 );     // Q(31-(spectrum_e+1)
    1179      604372 :                     hTcxEnc->spectrum_e[n] = add( hTcxEnc->spectrum_e[n], Q1 );
    1180      604372 :                     move16();
    1181             :                 }
    1182      604559 :                 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      604559 :                 IF( EQ_16( *fac_ns_q, 1 ) )
    1186             :                 {
    1187       70297 :                     hTcxEnc->noiseLevelMemory_cnt = s_min( INT16_MAX, 1 + abs_s( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
    1188       70297 :                     move16();
    1189             :                 }
    1190             :                 ELSE
    1191             :                 {
    1192      534262 :                     test();
    1193      534262 :                     IF( EQ_16( *fac_ns_q, 2 ) && GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) )
    1194             :                     {
    1195        5679 :                         *fac_ns_q = 1;        /* reduce noise filling level by one step */
    1196        5679 :                         fac_ns[ch][n] = 3072; /* 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL ) in Q15*/
    1197        5679 :                         move16();
    1198        5679 :                         move16();
    1199             :                         /* signal that noise level is changed by inverting sign of level memory */
    1200        5679 :                         IF( ( hTcxEnc->noiseLevelMemory_cnt < 0 ) )
    1201             :                         {
    1202        1951 :                             hTcxEnc->noiseLevelMemory_cnt = 5;
    1203        1951 :                             move16();
    1204             :                         }
    1205             :                         ELSE
    1206             :                         {
    1207        3728 :                             hTcxEnc->noiseLevelMemory_cnt = sub( -1, hTcxEnc->noiseLevelMemory_cnt );
    1208        3728 :                             move16();
    1209             :                         }
    1210             :                     }
    1211             :                     ELSE
    1212             :                     {
    1213      528583 :                         hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
    1214      528583 :                         move16();
    1215             :                     }
    1216             :                 }
    1217             :             } /* bitrate */
    1218             :         }
    1219             :     }
    1220             : 
    1221      343491 :     return;
    1222             : }
    1223             : 
    1224         637 : 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         637 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1276             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1277         637 :     Flag Overflow = 0;
    1278         637 :     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         637 :         sqGain = 0x4000;
    1304         637 :         move16();
    1305         637 :         sqGain_e = 1;
    1306         637 :         move16();
    1307         637 :         noiseTransWidth = MIN_NOISE_FILLING_HOLE;
    1308         637 :         move16();
    1309         637 :         resQTargetBits = 0;
    1310         637 :         move16();
    1311             : 
    1312             :         /*-----------------------------------------------------------*
    1313             :          * Init                                                      *
    1314             :          *-----------------------------------------------------------*/
    1315             : 
    1316             :         /* Init lengths */
    1317         637 :         L_frame = L_frame_glob;
    1318         637 :         move16();
    1319         637 :         L_frameTCX = L_frameTCX_glob;
    1320         637 :         move16();
    1321         637 :         overlap = hTcxCfg->tcx_mdct_window_length;
    1322         637 :         move16();
    1323         637 :         aldo = 0;
    1324         637 :         move16();
    1325         637 :         nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS );
    1326         637 :         move16();
    1327             :         /* Modified the overlap to the delay in case of short blocks*/
    1328         637 :         tcx_offset = hTcxCfg->tcx_offset;
    1329         637 :         move16();
    1330             : 
    1331         637 :         OriginalSpectrum = NULL;
    1332         637 :         signs = NULL; /* silence warning */
    1333         637 :         NumIndexBits = 0;
    1334         637 :         move16();
    1335         637 :         sqBits = 0;
    1336         637 :         move16();
    1337         637 :         ctxHmBits = 0;
    1338         637 :         move16();
    1339         637 :         resQBits = 0;
    1340         637 :         move16();
    1341         637 :         prm_ltp = &prm[1 + NOISE_FILL_RANGES];
    1342         637 :         move16();
    1343         637 :         prm_tns = prm_ltp + LTPSIZE;
    1344         637 :         move16();
    1345         637 :         prm_hm = prm_tns + tnsSize;
    1346         637 :         move16();
    1347         637 :         prm_lastnz = prm_hm + 2;
    1348         637 :         move16();
    1349         637 :         sqQ = prm_hm + NPRM_CTX_HM;
    1350         637 :         move16();
    1351             : 
    1352             :         /* if past frame is ACELP */
    1353             : 
    1354         637 :         IF( st->last_core == ACELP_CORE )
    1355             :         {
    1356          34 :             hTcxCfg->last_aldo = 0;
    1357          34 :             move16();
    1358             : 
    1359          34 :             L_frame = add( L_frame, tcx_offset );
    1360          34 :             L_frameTCX = add( L_frameTCX, hTcxCfg->tcx_offsetFB );
    1361          34 :             L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
    1362          34 :             tcx_offset = 0;
    1363          34 :             move16();
    1364          34 :             IF( hTcxCfg->lfacNext < 0 )
    1365             :             {
    1366          34 :                 L_frame = sub( L_frame, hTcxCfg->lfacNext );
    1367          34 :                 L_frameTCX = sub( L_frameTCX, hTcxCfg->lfacNextFB );
    1368          34 :                 tcx_offset = hTcxCfg->lfacNext;
    1369          34 :                 move16();
    1370             :             }
    1371          34 :             hTcxEnc->noiseLevelMemory_cnt = 0;
    1372          34 :             move16();
    1373             :         }
    1374             : 
    1375             : 
    1376         637 :         E_LPC_f_lsp_a_conversion( st->lsp_old_fx, Aq_old, M );
    1377             : 
    1378             :         /* target bitrate for SQ */
    1379         637 :         sqTargetBits = sub( nb_bits, 7 + NBITS_NOISE_FILL_LEVEL );
    1380             : 
    1381             :         /*Unquantized spectrum here*/
    1382         637 :         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         637 :         Copy32( spectrum, x_orig, L_spec );
    1431         637 :         x_orig_e = *spectrum_e;
    1432         637 :         move16();
    1433             : 
    1434             :         /*-----------------------------------------------------------*
    1435             :          * Bandwidth Limitation                                      *
    1436             :          *-----------------------------------------------------------*/
    1437             : 
    1438         637 :         noiseFillingSize = L_spec;
    1439         637 :         move16();
    1440         637 :         IF( st->igf != 0 )
    1441             :         {
    1442         637 :             noiseFillingSize = st->hIGFEnc->infoStartLine;
    1443         637 :             move16();
    1444             :         }
    1445             :         ELSE
    1446             :         {
    1447           0 :             st->hIGFEnc->infoStopLine = noiseFillingSize;
    1448           0 :             move16();
    1449             :         }
    1450             : 
    1451      142309 :         FOR( i = st->hIGFEnc->infoStopLine; i < L_frameTCX; i++ )
    1452             :         {
    1453      141672 :             spectrum[i] = L_deposit_l( 0 );
    1454      141672 :             move32();
    1455             :         }
    1456             : 
    1457             :         /*-----------------------------------------------------------*
    1458             :          * Quantization                                              *
    1459             :          *-----------------------------------------------------------*/
    1460             : 
    1461         637 :         IF( hTcxEnc->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
    1462             :         {
    1463             : 
    1464             :             /* Fast estimation of the scalar quantizer step size */
    1465         637 :             test();
    1466         637 :             IF( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) )
    1467             :             {
    1468         603 :                 LtpPitchLag = -1;
    1469         603 :                 move16();
    1470             : 
    1471         603 :                 test();
    1472         603 :                 IF( ( tcxonly == 0 ) && ( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) ) )
    1473             :                 {
    1474         438 :                     tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
    1475         438 :                     tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
    1476         438 :                     LtpPitchLag = div_l( tmp32, tmp1 );
    1477             :                 }
    1478             : 
    1479         603 :                 ctxHmBits = add( ctxHmBits, 1 );       /* ContextHM flag */
    1480         603 :                 sqTargetBits = sub( sqTargetBits, 1 ); /* ContextHM flag */
    1481             : 
    1482         603 :                 OriginalSpectrum = spectrum;
    1483         603 :                 OriginalSpectrum_e = *spectrum_e;
    1484         603 :                 move16();
    1485             : 
    1486         603 :                 tmp1 = -1;
    1487         603 :                 move16();
    1488         603 :                 if ( hTcxEnc->tcxltp != 0 )
    1489             :                 {
    1490         603 :                     tmp1 = hTcxEnc->tcxltp_gain;
    1491         603 :                     move16();
    1492             :                 }
    1493         603 :                 PeriodicityIndex = SearchPeriodicityIndex_fx(
    1494             :                     OriginalSpectrum,
    1495             :                     NULL,
    1496             :                     L_spec,
    1497             :                     sqTargetBits,
    1498             :                     LtpPitchLag,
    1499             :                     tmp1,
    1500             :                     &RelativeScore );
    1501             : 
    1502         603 :                 ConfigureContextHm(
    1503             :                     L_spec,
    1504             :                     sqTargetBits,
    1505             :                     PeriodicityIndex,
    1506             :                     LtpPitchLag,
    1507             :                     hm_cfg );
    1508             : 
    1509         603 :                 tmp1 = 1;
    1510         603 :                 move16();
    1511         603 :                 if ( LT_16( L_spec, 256 ) )
    1512             :                 {
    1513           0 :                     tmp1 = 0;
    1514           0 :                     move16();
    1515             :                 }
    1516         603 :                 NumIndexBits = CountIndexBits( tmp1, PeriodicityIndex );
    1517             : 
    1518             : 
    1519             :                 /* Quantize original spectrum */
    1520             : 
    1521         603 :                 sqGain = SQ_gain_fx( OriginalSpectrum, OriginalSpectrum_e,
    1522         603 :                                      shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ),
    1523             :                                      L_spec,
    1524             :                                      &sqGain_e );
    1525             : 
    1526         603 :                 tcx_scalar_quantization_fx( OriginalSpectrum, OriginalSpectrum_e,
    1527             :                                             sqQ,
    1528             :                                             L_spec,
    1529             :                                             sqGain, sqGain_e,
    1530         603 :                                             hTcxCfg->sq_rounding,
    1531         603 :                                             hTcxEnc->memQuantZeros,
    1532             :                                             tcxonly );
    1533             : 
    1534             :                 /* Estimate original bitrate */
    1535         603 :                 stop = 0;
    1536         603 :                 move16();
    1537             : 
    1538         603 :                 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         603 :                 stopCtxHm = 0;
    1549         603 :                 move16();
    1550             : 
    1551             :                 /* Context Mapping */
    1552         603 :                 sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1553             :                                                                                   L_spec,
    1554             :                                                                                   &lastnzCtxHm,
    1555             :                                                                                   &nEncodedCtxHm,
    1556         603 :                                                                                   sub( sqTargetBits, NumIndexBits ),
    1557             :                                                                                   &stopCtxHm,
    1558             :                                                                                   hm_cfg );
    1559             : 
    1560             :                 /* Decide whether or not to use context mapping */
    1561         603 :                 Selector = sub( s_max( stop, sqBits ), add( s_max( stopCtxHm, sqBitsCtxHm ), NumIndexBits ) );
    1562             : 
    1563         603 :                 test();
    1564         603 :                 test();
    1565         603 :                 IF( ( GT_16( Selector, 2 ) ) || ( ( LE_16( abs_s( Selector ), 2 ) ) &&
    1566             :                                                   ( LT_16( kCtxHmOlRSThr, RelativeScore ) ) ) )
    1567             :                 {
    1568             :                     /* CtxHm is likely better */
    1569          45 :                     sqTargetBits = sub( sqTargetBits, NumIndexBits );
    1570          45 :                     ctxHmBits = add( ctxHmBits, NumIndexBits );
    1571          45 :                     prm_hm[0] = 1;
    1572          45 :                     move16();
    1573          45 :                     prm_hm[1] = PeriodicityIndex;
    1574          45 :                     move16();
    1575          45 :                     *prm_lastnz = lastnzCtxHm;
    1576          45 :                     move16();
    1577          45 :                     sqBits_noStop = sqBits = sqBitsCtxHm;
    1578          45 :                     move16();
    1579          45 :                     move16();
    1580          45 :                     nEncoded = nEncodedCtxHm;
    1581          45 :                     move16();
    1582          45 :                     stop = stopCtxHm;
    1583          45 :                     move16();
    1584             :                 }
    1585             :                 ELSE /* Original is better or not much difference */
    1586             :                 {
    1587         558 :                     prm_hm[0] = 0;
    1588         558 :                     move16();
    1589         558 :                     prm_hm[1] = PeriodicityIndex;
    1590         558 :                     move16();
    1591         558 :                     *prm_lastnz = lastnz;
    1592         558 :                     move16();
    1593         558 :                     PeriodicityIndex = -1;
    1594         558 :                     move16();
    1595             : 
    1596         558 :                     sqBits_noStop = sqBits;
    1597         558 :                     move16();
    1598             :                 }
    1599             : 
    1600             : 
    1601         603 :                 if ( stop != 0 )
    1602             :                 {
    1603             : 
    1604         227 :                     sqBits = stop;
    1605         227 :                     move16();
    1606             :                 }
    1607             :             }
    1608             :             ELSE /* no context hm*/
    1609             :             {
    1610          34 :                 PeriodicityIndex = -1;
    1611          34 :                 move16();
    1612             : 
    1613          34 :                 sqGain = SQ_gain_fx( spectrum, *spectrum_e,
    1614          34 :                                      shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ),
    1615             :                                      L_spec,
    1616             :                                      &sqGain_e );
    1617             : 
    1618             :                 /* Quantize spectrum */
    1619             : 
    1620          34 :                 tcx_scalar_quantization_fx( spectrum, *spectrum_e,
    1621             :                                             sqQ,
    1622             :                                             L_spec,
    1623             :                                             sqGain, sqGain_e,
    1624          34 :                                             hTcxCfg->sq_rounding,
    1625          34 :                                             hTcxEnc->memQuantZeros,
    1626             :                                             tcxonly );
    1627             : 
    1628             :                 /* Estimate bitrate */
    1629          34 :                 stop = 0;
    1630          34 :                 move16();
    1631          34 :                 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          34 :                 sqBits_noStop = sqBits;
    1640          34 :                 move16();
    1641             : 
    1642          34 :                 if ( stop != 0 )
    1643             :                 {
    1644          11 :                     sqBits = stop;
    1645          11 :                     move16();
    1646             :                 }
    1647             :             } /* end of if (ctx_hm) */
    1648             : 
    1649             :             /* Adjust correction factor */
    1650         637 :             tmp1 = sqBits;
    1651         637 :             move16();
    1652             : 
    1653         637 :             if ( s_and( L_spec, sub( L_spec, 1 ) ) == 0 ) /* power-of-2 */
    1654             :             {
    1655           0 :                 tmp1 = add( tmp1, 1 );
    1656             :             }
    1657             : 
    1658         637 :             tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 );
    1659             :             BASOP_SATURATE_WARNING_OFF_EVS
    1660         637 :             hTcxEnc->tcx_target_bits_fac = shl_o( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2, &Overflow );
    1661         637 :             move16();
    1662             :             BASOP_SATURATE_WARNING_ON_EVS
    1663             : 
    1664         637 :             if ( GT_16( hTcxEnc->tcx_target_bits_fac, 0x5000 ) )
    1665             :             {
    1666         205 :                 hTcxEnc->tcx_target_bits_fac = 0x5000;
    1667         205 :                 move16();
    1668             :             }
    1669         637 :             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         637 :             phm_cfg = NULL;
    1677         637 :             move16();
    1678         637 :             if ( PeriodicityIndex >= 0 )
    1679             :             {
    1680          45 :                 phm_cfg = hm_cfg;
    1681          45 :                 move16();
    1682             :             }
    1683        1274 :             sqBits = tcx_scalar_quantization_rateloop_fx( spectrum, *spectrum_e,
    1684             :                                                           sqQ,
    1685             :                                                           L_spec,
    1686             :                                                           &sqGain, &sqGain_e,
    1687         637 :                                                           hTcxCfg->sq_rounding,
    1688         637 :                                                           hTcxEnc->memQuantZeros,
    1689             :                                                           prm_lastnz, /* lastnz */
    1690             :                                                           sqTargetBits,
    1691             :                                                           &nEncoded,
    1692             :                                                           &stop,
    1693             :                                                           sqBits_noStop,
    1694             :                                                           sqBits,
    1695         637 :                                                           hTcxCfg->tcxRateLoopOpt,
    1696             :                                                           tcxonly,
    1697             :                                                           phm_cfg );
    1698             : 
    1699         637 :             IF( ctxHmBits > 0 ) /* Mapping tool is enabled */
    1700             :             {
    1701             :                 /* Truncate spectrum */
    1702         603 :                 set16_fx( sqQ + nEncoded, 0, sub( L_spec, nEncoded ) );
    1703             : 
    1704         603 :                 IF( PeriodicityIndex >= 0 ) /* Mapping is used */
    1705             :                 {
    1706             :                     /* Estimate non-mapped bitrate */
    1707          45 :                     stopCtxHm = 1;
    1708          45 :                     move16();
    1709             : 
    1710          45 :                     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          45 :                     Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    1720             : 
    1721          45 :                     test();
    1722          45 :                     IF( stopCtxHm == 0 && Selector > 0 ) /* Non-mapped is better */
    1723             :                     {
    1724           0 :                         sqTargetBits = add( sqTargetBits, NumIndexBits );
    1725           0 :                         ctxHmBits = sub( ctxHmBits, NumIndexBits );
    1726           0 :                         prm_hm[0] = 0;
    1727           0 :                         move16();
    1728           0 :                         *prm_lastnz = lastnz;
    1729           0 :                         move16();
    1730           0 :                         PeriodicityIndex = -1;
    1731           0 :                         move16();
    1732           0 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    1733           0 :                         move16();
    1734           0 :                         move16();
    1735           0 :                         nEncoded = nEncodedCtxHm;
    1736           0 :                         move16();
    1737           0 :                         stop = stopCtxHm;
    1738           0 :                         move16();
    1739             :                     }
    1740             :                 }
    1741             :                 ELSE /* Mapping is not used */
    1742             :                 {
    1743             :                     /* Estimate mapped bitrate */
    1744         558 :                     stopCtxHm = 1;
    1745         558 :                     move16();
    1746         558 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
    1747             :                                                                                       L_spec,
    1748             :                                                                                       &lastnzCtxHm,
    1749             :                                                                                       &nEncodedCtxHm,
    1750         558 :                                                                                       sub( sqTargetBits, NumIndexBits ),
    1751             :                                                                                       &stopCtxHm,
    1752             :                                                                                       hm_cfg );
    1753             : 
    1754             :                     /* Decide whether or not to use mapping */
    1755         558 :                     Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    1756             : 
    1757         558 :                     test();
    1758         558 :                     IF( stopCtxHm == 0 && Selector > 0 ) /* Mapped is better */
    1759             :                     {
    1760           5 :                         sqTargetBits = sub( sqTargetBits, NumIndexBits );
    1761           5 :                         ctxHmBits = add( ctxHmBits, NumIndexBits );
    1762           5 :                         prm_hm[0] = 1;
    1763           5 :                         move16();
    1764           5 :                         *prm_lastnz = lastnzCtxHm;
    1765           5 :                         move16();
    1766           5 :                         PeriodicityIndex = prm_hm[1];
    1767           5 :                         move16();
    1768           5 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    1769           5 :                         move16();
    1770           5 :                         move16();
    1771           5 :                         nEncoded = nEncodedCtxHm;
    1772           5 :                         move16();
    1773           5 :                         stop = stopCtxHm;
    1774           5 :                         move16();
    1775             :                     }
    1776             :                 }
    1777             :             }
    1778             : 
    1779             :             /* Limit low sqGain for avoiding saturation of the gain quantizer*/
    1780         637 :             tmp1 = mult_r( shl_o( L_spec, 5, &Overflow ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    1781         637 :             s = 15 - 5 - 7;
    1782         637 :             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         637 :             tmp1 = ISqrt16( tmp1, &s );
    1789             : 
    1790         637 :             tmp2 = sub( sqGain_e, s );
    1791         637 :             IF( tmp2 >= 0 )
    1792             :             {
    1793             :                 BASOP_SATURATE_WARNING_OFF_EVS;
    1794         637 :                 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         637 :             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         637 :             IF( stop != 0 )
    1836             :             {
    1837          69 :                 set16_fx( sqQ + nEncoded, 0, sub( L_spec, nEncoded ) );
    1838             :             }
    1839             : 
    1840             :             /* Save quantized Values */
    1841         637 :             tmp32 = L_deposit_l( 0 );
    1842      413757 :             FOR( i = 0; i < L_spec; i++ )
    1843             :             {
    1844      413120 :                 spectrum[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) );
    1845      413120 :                 move32();
    1846             :                 /* noise filling seed */
    1847      413120 :                 tmp32 = L_macNs_co( tmp32, abs_s( sqQ[i] ), i, &Carry, &Overflow );
    1848             :             }
    1849         637 :             *spectrum_e = SPEC_EXP_DEC;
    1850         637 :             move16();
    1851             : 
    1852         637 :             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         637 :         set16_fx( xn_buf16, 0x4000, L_spec );
    1916             : 
    1917         637 :         IF( tcxonly == 0 )
    1918             :         {
    1919             : 
    1920         637 :             AdaptLowFreqDeemph( spectrum, *spectrum_e,
    1921         637 :                                 hTcxEnc->tcx_lpc_shaped_ari,
    1922             :                                 gainlpc, gainlpc_e,
    1923             :                                 L_frame,
    1924             :                                 xn_buf16 /* LF deemphasis factors */
    1925             :             );
    1926             :         }
    1927             : 
    1928         637 :         tcx_get_gain( x_orig, x_orig_e,
    1929         637 :                       spectrum, *spectrum_e,
    1930             :                       L_spec,
    1931             :                       &gain_tcx_opt, &gain_tcx_opt_e,
    1932             :                       &ener, &ener_e );
    1933             : 
    1934         637 :         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         637 :         gain_tcx = gain_tcx_opt;
    1942         637 :         move16();
    1943         637 :         gain_tcx_e = gain_tcx_opt_e;
    1944         637 :         move16();
    1945             : 
    1946             :         /* Save gains for FAC and Residual Q*/
    1947             : 
    1948             :         /*-----------------------------------------------------------*
    1949             :          * Quantize TCX gain                                         *
    1950             :          *-----------------------------------------------------------*/
    1951         637 :         test();
    1952         637 :         IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    1953             :         {
    1954         637 :             QuantizeGain( L_spec, &gain_tcx, &gain_tcx_e, &prm[0] );
    1955             :         }
    1956             : 
    1957             : 
    1958             :         /*-----------------------------------------------------------*
    1959             :          * Residual Quantization                                     *
    1960             :          *-----------------------------------------------------------*/
    1961             : 
    1962         637 :         IF( hTcxCfg->resq )
    1963             :         {
    1964             : 
    1965         637 :             resQTargetBits = sub( sqTargetBits, sqBits );
    1966             : 
    1967         637 :             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         637 :                 move16();
    1986         637 :                 tmpP16 = NULL;
    1987         637 :                 if ( tcxonly == 0 )
    1988             :                 {
    1989         637 :                     move16();
    1990         637 :                     tmpP16 = xn_buf16;
    1991             :                 }
    1992             : 
    1993         637 :                 resQBits = tcx_res_Q_gain_fx( gain_tcx_opt, gain_tcx_opt_e,
    1994             :                                               &gain_tcx, &gain_tcx_e,
    1995         637 :                                               &sqQ[L_spec],
    1996             :                                               resQTargetBits );
    1997             : 
    1998         637 :                 resQBits = tcx_res_Q_spec_fx( x_orig, x_orig_e,
    1999         637 :                                               spectrum, *spectrum_e,
    2000             :                                               L_spec,
    2001             :                                               gain_tcx, gain_tcx_e,
    2002         637 :                                               &sqQ[L_spec],
    2003             :                                               resQTargetBits,
    2004             :                                               resQBits,
    2005         637 :                                               hTcxCfg->sq_rounding,
    2006             :                                               tmpP16 /* LF deemphasis factors */ );
    2007             :             }
    2008             :         }
    2009             : 
    2010             : 
    2011             :         /*-----------------------------------------------------------*
    2012             :          * ALFE tcx only bitrates                                    *
    2013             :          *-----------------------------------------------------------*/
    2014             : 
    2015         637 :         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         637 :             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         637 :             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         637 :                 i = shr( L_frame, 3 );
    2048         637 :                 test();
    2049         637 :                 IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    2050             :                 {
    2051         637 :                     i = idiv1616U( L_frame, 6 );
    2052             :                 }
    2053             : 
    2054         637 :                 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         637 :                 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         637 :                                      hTcxEnc->noiseTiltFactor,
    2083             :                                      &fac_ns, &prm[NOISE_FILL_RANGES] );
    2084             : 
    2085             :                 /* hysteresis for very tonal passages (more stationary noise filling level) */
    2086             : 
    2087         637 :                 IF( EQ_16( prm[NOISE_FILL_RANGES], 1 ) )
    2088             :                 {
    2089          55 :                     hTcxEnc->noiseLevelMemory_cnt = add( 1, abs_s( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
    2090          55 :                     move16();
    2091             :                 }
    2092             :                 ELSE
    2093             :                 {
    2094         582 :                     test();
    2095         582 :                     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         579 :                         hTcxEnc->noiseLevelMemory_cnt = 0;
    2117         579 :                         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         637 :         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         637 :         test();
    2147             :         /* Replication of ACELP formant enhancement for low rates */
    2148         637 :         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         637 :         IF( fac_ns > 0 )
    2154             :         {
    2155         635 :             tmp1 = 0;
    2156         635 :             move16();
    2157         635 :             test();
    2158         635 :             if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    2159             :             {
    2160         635 :                 tmp1 = 1;
    2161         635 :                 move16();
    2162             :             }
    2163             : 
    2164         635 :             i = tcxGetNoiseFillingTilt( A,
    2165             :                                         M,
    2166             :                                         L_frame,
    2167             :                                         tmp1,
    2168             :                                         &hTcxEnc->noiseTiltFactor );
    2169             : 
    2170         635 :             tcx_noise_filling( spectrum, *spectrum_e, nf_seed /* seed */, i, noiseFillingSize, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns, NULL, st->element_mode );
    2171             :         }
    2172         637 :         test();
    2173         637 :         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         637 :         mdct_shaping( spectrum, L_frame, gainlpc, gainlpc_e );
    2203             : 
    2204             :         /*-----------------------------------------------------------*
    2205             :          * Apply gain                                                *
    2206             :          *-----------------------------------------------------------*/
    2207         637 :         IF( st->hTcxCfg->coder_type == INACTIVE )
    2208             :         {
    2209          12 :             gain_tcx = mult_r( gain_tcx, hTcxCfg->na_scale );
    2210             :         }
    2211             : 
    2212      413757 :         FOR( i = 0; i < L_spec; i++ )
    2213             :         {
    2214      413120 :             spectrum[i] = Mpy_32_16_1( spectrum[i], gain_tcx ); // Q(31-(spectrum_e+gain_tcx_e))
    2215      413120 :             move32();
    2216             :         }
    2217         637 :         *spectrum_e = add( *spectrum_e, gain_tcx_e );
    2218         637 :         move16();
    2219             : 
    2220         637 :         stop = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    2221         637 :         move16();
    2222             : 
    2223         637 :         test();
    2224         637 :         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         637 :         IF( hTcxCfg->fIsTNSAllowed != 0 )
    2253             :         {
    2254         376 :             test();
    2255         376 :             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         376 :             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         637 :             s = getScaleFactor32( spectrum, L_frame );
    2285      190317 :             FOR( i = 0; i < L_frame; i++ )
    2286             :             {
    2287      189680 :                 spectrum[i] = L_shl( spectrum[i], s ); // Q(31-(spectrum_e-s))
    2288      189680 :                 move32();
    2289             :             }
    2290         637 :             *spectrum_e = sub( *spectrum_e, s );
    2291             : 
    2292             :             /*-----------------------------------------------------------*
    2293             :              * Compute inverse MDCT of spectrum[].                        *
    2294             :              *-----------------------------------------------------------*/
    2295         637 :             test();
    2296         637 :             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         637 :                 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         603 :                     Q = sub( 31, *spectrum_e );
    2576         603 :                     edct_fx( spectrum, tmp_buf, L_frame, &Q );
    2577             : 
    2578             :                     /* scale by sqrt(L / NORM_MDCT_FACTOR) */
    2579         603 :                     tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
    2580         603 :                     tmp2 = 4;
    2581         603 :                     move16();
    2582         603 :                     tmp1 = Sqrt16( tmp1, &tmp2 );
    2583             : 
    2584      177563 :                     FOR( i = 0; i < L_frame; i++ )
    2585             :                     {
    2586      176960 :                         tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
    2587      176960 :                         move32();
    2588             :                     }
    2589         603 :                     Q = sub( Q, tmp2 );
    2590             : 
    2591             : 
    2592         603 :                     window_ola_fx( tmp_buf,
    2593             :                                    xn_buf16,
    2594             :                                    &Q,
    2595         603 :                                    hTcxEnc->old_out_fx,
    2596             :                                    &hTcxEnc->Q_old_out,
    2597             :                                    L_frame,
    2598         603 :                                    hTcxCfg->tcx_last_overlap_mode,
    2599         603 :                                    hTcxCfg->tcx_curr_overlap_mode,
    2600             :                                    0,
    2601             :                                    0,
    2602             :                                    NULL );
    2603             : 
    2604             :                     /* scale output */
    2605      177563 :                     FOR( i = 0; i < L_frame; i++ )
    2606             :                     {
    2607             : #ifdef ISSUE_1772_replace_shr_o
    2608      176960 :                         xn_buf16[i] = shr_sat( xn_buf16[i], Q );
    2609             : #else
    2610             :                         xn_buf16[i] = shr_o( xn_buf16[i], Q, &Overflow );
    2611             : #endif
    2612      176960 :                         move16();
    2613             :                     }
    2614             : 
    2615         603 :                     aldo = 1;
    2616         603 :                     move16();
    2617             :                 }
    2618             :                 ELSE
    2619             :                 {
    2620             : 
    2621          34 :                     TCX_MDCT_Inverse( spectrum, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    2622          34 :                                       xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    2623             : 
    2624             :                     /*-----------------------------------------------------------*
    2625             :                      * Windowing, overlap and add                                *
    2626             :                      *-----------------------------------------------------------*/
    2627             : 
    2628             :                     /* Window current frame */
    2629          34 :                     tmp4 = 0;
    2630          34 :                     move16();
    2631          34 :                     if ( tcx_offset < 0 )
    2632             :                     {
    2633          34 :                         tmp4 = negate( tcx_offset );
    2634             :                     }
    2635          68 :                     tcx_windowing_synthesis_current_frame( xn_buf16,
    2636          34 :                                                            hTcxCfg->tcx_aldo_window_2,
    2637          34 :                                                            hTcxCfg->tcx_mdct_window_half,
    2638          34 :                                                            hTcxCfg->tcx_mdct_window_minimum,
    2639             :                                                            overlap, /*hTcxCfg->tcx_mdct_window_length*/
    2640          34 :                                                            hTcxCfg->tcx_mdct_window_half_length,
    2641          34 :                                                            hTcxCfg->tcx_mdct_window_min_length,
    2642          34 :                                                            st->last_core == ACELP_CORE,
    2643          34 :                                                            hTcxCfg->tcx_last_overlap_mode, /*left mode*/
    2644             :                                                            hTcxEnc->acelp_zir,
    2645          34 :                                                            hTcxEnc->Txnq,
    2646             :                                                            NULL,
    2647             :                                                            Aq_old,
    2648          34 :                                                            hTcxCfg->tcx_mdct_window_trans,
    2649          34 :                                                            shr( L_frame_glob, 1 ),
    2650             :                                                            tmp4,
    2651          34 :                                                            st->last_core,
    2652             :                                                            0,
    2653             :                                                            0 );
    2654             :                 }
    2655             :             } /* TCX-10 and TCX-only */
    2656             : 
    2657             :             /* Window and overlap-add past frame if past frame is TCX */
    2658         637 :             test();
    2659         637 :             test();
    2660         637 :             test();
    2661         637 :             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 ) ) ) )
    2662             :             {
    2663             : 
    2664           0 :                 IF( hTcxCfg->last_aldo != 0 )
    2665             :                 {
    2666           0 :                     tmp2 = add( hTcxEnc->Q_old_out, TCX_IMDCT_HEADROOM );
    2667             : 
    2668           0 :                     tmp1 = sub( overlap, hTcxCfg->tcx_mdct_window_min_length );
    2669           0 :                     FOR( i = 0; i < tmp1; i++ )
    2670             :                     {
    2671           0 :                         xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
    2672           0 :                         move16();
    2673             :                     }
    2674             : 
    2675             :                     /* fade truncated ALDO window */
    2676           0 :                     tmp1 = sub( overlap, shr( hTcxCfg->tcx_mdct_window_min_length, 1 ) );
    2677           0 :                     FOR( ; i < tmp1; i++ )
    2678             :                     {
    2679           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 );
    2680           0 :                         xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    2681           0 :                         move16();
    2682             :                     }
    2683           0 :                     FOR( ; i < overlap; i++ )
    2684             :                     {
    2685           0 :                         tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im );
    2686           0 :                         xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    2687           0 :                         move16();
    2688             :                     }
    2689             : 
    2690           0 :                     FOR( ; i < L_frame; i++ )
    2691             :                     {
    2692           0 :                         xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    2693           0 :                         move16();
    2694             :                     }
    2695             :                 }
    2696             :                 ELSE
    2697             :                 {
    2698           0 :                     test();
    2699           0 :                     test();
    2700           0 :                     test();
    2701           0 :                     if ( ( frame_cnt > 0 ) && ( stop == 0 ) && ( hTcxCfg->tcx_curr_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) )
    2702             :                     {
    2703           0 :                         stop = 2; /* use minimum overlap between the two TCX-10 windows */
    2704           0 :                         move16();
    2705             :                     }
    2706             : 
    2707           0 :                     tmp1 = stop;
    2708           0 :                     move16();
    2709           0 :                     test();
    2710           0 :                     if ( ( stop == 0 ) || ( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
    2711             :                     {
    2712           0 :                         tmp1 = hTcxCfg->tcx_last_overlap_mode;
    2713           0 :                         move16();
    2714             :                     }
    2715             : 
    2716           0 :                     tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_mdct_window_half,
    2717           0 :                                                         hTcxCfg->tcx_mdct_window_minimum, overlap, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, tmp1 );
    2718             : 
    2719             :                     BASOP_SATURATE_WARNING_OFF_EVS;
    2720           0 :                     FOR( i = 0; i < overlap; i++ )
    2721             :                     {
    2722           0 :                         xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM );
    2723           0 :                         move16();
    2724             :                     }
    2725             : 
    2726           0 :                     IF( LT_16( i, L_frame ) )
    2727             :                     {
    2728           0 :                         FOR( ; i < L_frame; i++ )
    2729             :                         {
    2730           0 :                             xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    2731           0 :                             move16();
    2732             :                         }
    2733             :                     }
    2734             :                     BASOP_SATURATE_WARNING_ON_EVS;
    2735             :                 }
    2736             :             }
    2737             :             ELSE
    2738             :             {
    2739         637 :                 IF( aldo == 0 )
    2740             :                 {
    2741             :                     BASOP_SATURATE_WARNING_OFF_EVS;
    2742       12754 :                     FOR( i = 0; i < L_frame; i++ )
    2743             :                     {
    2744       12720 :                         xn_buf16[i] = shl_o( xn_buf16[i], TCX_IMDCT_HEADROOM, &Overflow );
    2745       12720 :                         move16();
    2746             :                     }
    2747             :                     BASOP_SATURATE_WARNING_ON_EVS;
    2748             :                 }
    2749             :             }
    2750             : 
    2751         637 :             test();
    2752         637 :             test();
    2753         637 :             test();
    2754         637 :             IF( ( aldo == 0 ) &&
    2755             :                 ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
    2756             :                   NE_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) )
    2757             :             {
    2758             :                 /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
    2759        2896 :                 FOR( i = 0; i < nz; i++ )
    2760             :                 {
    2761        2862 :                     hTcxEnc->old_out_fx[i] = shr( xn_buf16[L_frame - nz + i], TCX_IMDCT_HEADROOM );
    2762        2862 :                     move16();
    2763             :                 }
    2764          34 :                 Copy( xn_buf16 + L_frame, hTcxEnc->old_out_fx + nz, overlap );
    2765          34 :                 set16_fx( hTcxEnc->old_out_fx + nz + overlap, 0, nz );
    2766             : 
    2767          34 :                 tcx_windowing_synthesis_past_frame( hTcxEnc->old_out_fx + nz,
    2768          34 :                                                     hTcxCfg->tcx_aldo_window_1_trunc,
    2769          34 :                                                     hTcxCfg->tcx_mdct_window_half,
    2770          34 :                                                     hTcxCfg->tcx_mdct_window_minimum,
    2771             :                                                     overlap,
    2772          34 :                                                     hTcxCfg->tcx_mdct_window_half_length,
    2773          34 :                                                     hTcxCfg->tcx_mdct_window_min_length,
    2774          34 :                                                     hTcxCfg->tcx_curr_overlap_mode );
    2775             : 
    2776             :                 /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
    2777          34 :                 IF( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
    2778             :                 {
    2779        2896 :                     FOR( i = 0; i < nz; i++ )
    2780             :                     {
    2781        2862 :                         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 );
    2782        2862 :                         move16();
    2783             :                     }
    2784          34 :                     hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
    2785          34 :                     move16();
    2786             :                 }
    2787             : 
    2788          34 :                 hTcxEnc->Q_old_out = -TCX_IMDCT_HEADROOM;
    2789          34 :                 move16();
    2790             :             }
    2791         637 :             hTcxCfg->last_aldo = aldo;
    2792         637 :             move16();
    2793             : 
    2794             :             /* Update Txnq */
    2795         637 :             IF( hTcxCfg->last_aldo == 0 )
    2796             :             {
    2797          34 :                 Copy( xn_buf16 + L_frame, hTcxEnc->Txnq, overlap );
    2798             :             }
    2799             : 
    2800             : 
    2801             :             /* Output */
    2802         637 :             Copy( xn_buf16 + shr( overlap, 1 ) - tcx_offset, synth, L_frame_glob );
    2803             :         }
    2804             : 
    2805             :         /* Free internal TCX decoder stack memory */
    2806             :     }
    2807             : 
    2808             :     /* Update L_frame_past */
    2809         637 :     st->L_frame_past = L_frame;
    2810         637 :     move16();
    2811         637 : }
    2812             : 
    2813           0 : static Word16 DecideTonalSideInfo_fx(
    2814             :     Word32 spectrum[], // Qx
    2815             :     const Word16 L_frame_glob,
    2816             :     Word32 SFM2 )
    2817             : {
    2818             :     Word32 SFM, K, K2;
    2819             :     Word16 Tonal_SideInfo;
    2820             : 
    2821           0 :     SFM = SFM_Cal_fx( spectrum, s_min( 200, L_frame_glob ) );
    2822           0 :     test();
    2823           0 :     IF( LE_16( L_frame_glob, 256 ) )
    2824             :     {
    2825           0 :         K = 0x33333333;
    2826           0 :         move32();
    2827           0 :         K2 = 0xCCCCCCD;
    2828           0 :         move32();
    2829             :     }
    2830           0 :     ELSE IF( EQ_16( L_frame_glob, 320 ) || EQ_16( L_frame_glob, 512 ) )
    2831             :     {
    2832           0 :         K = 0x33333333;
    2833           0 :         move32();
    2834           0 :         K2 = 0xCCCCCCD;
    2835           0 :         move32();
    2836             :     }
    2837             :     ELSE /*FrameSize_Core == 640*/
    2838             :     {
    2839           0 :         K = 0x2CCCCCCD;
    2840           0 :         move32();
    2841           0 :         K2 = 0x51EB852;
    2842           0 :         move32();
    2843             :     }
    2844             : 
    2845             : 
    2846           0 :     Tonal_SideInfo = 0;
    2847           0 :     move16();
    2848           0 :     if ( LT_32( SFM, K ) )
    2849             :     {
    2850           0 :         Tonal_SideInfo = 1;
    2851           0 :         move16();
    2852             :     }
    2853           0 :     if ( LT_32( SFM2, K2 ) )
    2854             :     {
    2855           0 :         Tonal_SideInfo = 1;
    2856           0 :         move16();
    2857             :     }
    2858             : 
    2859           0 :     return Tonal_SideInfo;
    2860             : }
    2861             : 
    2862      862816 : void QuantizeTCXSpectrum_fx(
    2863             :     Encoder_State *st,           /* i  : state handle                            */
    2864             :     const Word16 frame_cnt,      /* i  : frame counter in the super_frame        Q0 */
    2865             :     Word32 *x_orig_fx,           /* i  : shaped MDCT spectrum                    Q(31-x_orig_e)*/
    2866             :     Word16 x_orig_e,             /* i  : exp of shaped MDCT spectrum                    */
    2867             :     Word16 *gainlpc_fx,          /* i  : FDNS gains                              Q(15-gainlpc_e)*/
    2868             :     Word16 *gainlpc_e,           /* i  : exp of FDNS gains                              */
    2869             :     const Word16 *Aqind,         /* i  : frame-independent quantized coefficients (M+1) Q0 */
    2870             :     const Word16 tnsSize,        /* i  : number of tns parameters put into prm   Q0 */
    2871             :     const Word16 nb_bits,        /* i  : bit budget                              Q0 */
    2872             :     const Word16 vad_hover_flag, /* i  : VAD hangover flag Q0 */
    2873             :     Word16 *pL_frameTCX,         /* o  : full frame length                       Q0 */
    2874             :     Word16 *pL_frame,            /* o  : frame length                            Q0 */
    2875             :     Word16 *pL_spec,             /* o  : length of the coded spectrum            Q0 */
    2876             :     Word16 *ptcx_offset,         /* o  : folding point offset relative to the end of the previous frame Q0 */
    2877             :     Word16 *pnoiseFillingBorder, /* o  : noise filling border                    Q0 */
    2878             :     Word32 spectrum_fx[],        /* o  : quantized MDCT spectrum                 Q(31-spectrum_e)*/
    2879             :     Word16 *spectrum_e,          /* o  : exp of quantized MDCT spectrum                 */
    2880             :     CONTEXT_HM_CONFIG *hm_cfg,   /* o  : Context-based harmonic model configuration */
    2881             :     Word16 *hm_active,           /* o  : flag indicating if the harmonic model is active */
    2882             :     Word16 lf_deemph_fact_fx[],  /* o  : low frequency deemphasis factors        Q14*/
    2883             :     Word16 *nf_seed,             /* o  : noise filling random seed               Q0*/
    2884             :     Word32 *ener_fx,             /* o  : energy of the quantized spectrum       Q(31-ener_e) */
    2885             :     Word16 *ener_e,              /* o  : exp of energy of the quantized spectrum        */
    2886             :     Word16 *gain_tcx_fx,         /* o  : global gain                            Q(15-gain_tcx_e) */
    2887             :     Word16 *gain_tcx_e,          /* o  : exp of global gain                          */
    2888             :     Word16 prm[]                 /* o  : tcx parameters                          Q0 */
    2889             : )
    2890             : {
    2891      862816 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    2892             :     Word16 i, L_frame, L_frameTCX, L_spec, tcx_offset;
    2893             :     Word16 noiseFillingBorder, LtpPitchLag, PeriodicityIndex;
    2894             :     Word16 lastnzCtxHm, lastnz;
    2895             :     Word16 stop;
    2896             :     Word16 nEncodedCtxHm, stopCtxHm, sqBitsCtxHm, Selector;
    2897             :     Word16 nEncoded, sqBits_noStop;
    2898             :     Word16 NumIndexBits, signaling_bits, sqTargetBits, sqBits, ctxHmBits, resQBits, resQTargetBits;
    2899             :     Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_lastnz, *sqQ, *prm_target;
    2900             :     Word32 total_brate, tmp32;
    2901             :     Word16 RelativeScore_fx, sqGain_fx, sqGain_e, gain_tcx_opt_fx, gain_tcx_opt_e;
    2902             :     Word16 tmp1, tmp2, max_iter, minSqGain;
    2903             :     CONTEXT_HM_CONFIG *phm_cfg;
    2904      862816 :     Word16 att_fx = 0;
    2905      862816 :     move16();
    2906             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2907      862816 :     Flag Overflow = 0;
    2908      862816 :     move16();
    2909      862816 :     Flag Carry = 0;
    2910      862816 :     move16();
    2911             : #endif
    2912             :     /*-----------------------------------------------------------*
    2913             :      * Init                                                      *
    2914             :      *-----------------------------------------------------------*/
    2915             : 
    2916      862816 :     sqGain_fx = MAX_16;
    2917      862816 :     move16();
    2918      862816 :     sqGain_e = 0;
    2919      862816 :     move16();
    2920      862816 :     minSqGain = 0;
    2921      862816 :     move16();
    2922      862816 :     resQTargetBits = 0;
    2923      862816 :     move16();
    2924             : 
    2925      862816 :     NumIndexBits = 0;
    2926      862816 :     move16();
    2927      862816 :     sqBits = 0;
    2928      862816 :     move16();
    2929      862816 :     ctxHmBits = 0;
    2930      862816 :     move16();
    2931      862816 :     resQBits = 0;
    2932      862816 :     move16();
    2933      862816 :     prm_ltp = &prm[1 + NOISE_FILL_RANGES];
    2934      862816 :     prm_tns = prm_ltp + LTPSIZE;
    2935      862816 :     prm_hm = prm_tns + tnsSize;
    2936      862816 :     prm_lastnz = prm_hm + 2;
    2937      862816 :     sqQ = prm_hm + NPRM_CTX_HM;
    2938             : 
    2939      862816 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    2940             :     {
    2941      624490 :         total_brate = st->element_brate;
    2942             :     }
    2943             :     ELSE
    2944             :     {
    2945      238326 :         total_brate = st->total_brate;
    2946             :     }
    2947      862816 :     move32();
    2948             :     /*-----------------------------------------------------------*
    2949             :      * Init lengths                                              *
    2950             :      *-----------------------------------------------------------*/
    2951             : 
    2952             :     /******************************************************************************************/
    2953             : 
    2954      862816 :     L_frame = st->L_frame;
    2955      862816 :     move16();
    2956      862816 :     L_frameTCX = hTcxEnc->L_frameTCX;
    2957      862816 :     move16();
    2958      862816 :     L_spec = st->hTcxCfg->tcx_coded_lines;
    2959      862816 :     move16();
    2960      862816 :     tcx_offset = st->hTcxCfg->tcx_offset;
    2961      862816 :     move16();
    2962             : 
    2963      862816 :     IF( EQ_16( st->core, TCX_10_CORE ) )
    2964             :     {
    2965       31608 :         L_frame = shr( L_frame, 1 );
    2966       31608 :         L_frameTCX = shr( L_frameTCX, 1 );
    2967       31608 :         L_spec = shr( L_spec, 1 );
    2968             :     }
    2969      831208 :     ELSE IF( st->last_core == ACELP_CORE )
    2970             :     {
    2971        9188 :         st->hTcxCfg->last_aldo = 0;
    2972        9188 :         move16();
    2973        9188 :         L_frame = add( L_frame, tcx_offset );
    2974        9188 :         L_frameTCX = add( L_frameTCX, st->hTcxCfg->tcx_offsetFB );
    2975        9188 :         L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
    2976             : 
    2977        9188 :         IF( st->hTcxCfg->lfacNext < 0 )
    2978             :         {
    2979        9188 :             L_frame = sub( L_frame, st->hTcxCfg->lfacNext );
    2980        9188 :             L_frameTCX = sub( L_frameTCX, st->hTcxCfg->lfacNextFB );
    2981        9188 :             tcx_offset = st->hTcxCfg->lfacNext;
    2982        9188 :             move16();
    2983             :         }
    2984             :         ELSE
    2985             :         {
    2986           0 :             tcx_offset = 0;
    2987           0 :             move16();
    2988             :         }
    2989        9188 :         hTcxEnc->noiseLevelMemory_cnt = 0;
    2990        9188 :         move16();
    2991             :     }
    2992             : 
    2993      862816 :     *pL_frameTCX = L_frameTCX;
    2994      862816 :     move16();
    2995      862816 :     *pL_frame = L_frame;
    2996      862816 :     move16();
    2997      862816 :     *pL_spec = L_spec;
    2998      862816 :     move16();
    2999      862816 :     *ptcx_offset = tcx_offset;
    3000      862816 :     move16();
    3001             : 
    3002             :     /* target bitrate for SQ */
    3003      862816 :     sqTargetBits = sub( nb_bits, NBITS_TCX_GAIN + NBITS_NOISE_FILL_LEVEL );
    3004             : 
    3005      862816 :     IF( st->enablePlcWaveadjust )
    3006             :     {
    3007             :         Word16 L_frame_glob;
    3008           0 :         IF( EQ_16( st->core, TCX_20_CORE ) )
    3009             :         {
    3010           0 :             L_frame_glob = st->L_frame;
    3011           0 :             move16();
    3012             :         }
    3013             :         ELSE
    3014             :         {
    3015           0 :             L_frame_glob = shr( st->L_frame, 1 );
    3016             :         }
    3017           0 :         move16();
    3018           0 :         st->Tonal_SideInfo = DecideTonalSideInfo_fx( x_orig_fx, L_frame_glob, st->hTcxCfg->SFM2 );
    3019             :     }
    3020             : 
    3021             :     /* Start with the pre-shaped spectrum*/
    3022             : 
    3023             :     /*scaling buffer to Q31 if exp < 0 to avoid overflow while scaling constants*/
    3024      862816 :     IF( x_orig_e < 0 )
    3025             :     {
    3026         747 :         scale_sig32( x_orig_fx, L_spec, x_orig_e );
    3027         747 :         x_orig_e = 0;
    3028         747 :         move16();
    3029             :     }
    3030             : 
    3031      862816 :     Copy32( x_orig_fx, spectrum_fx, L_spec );
    3032      862816 :     *spectrum_e = x_orig_e;
    3033      862816 :     move16();
    3034             : 
    3035             :     /*-----------------------------------------------------------*
    3036             :      * Bandwidth Limitation                                      *
    3037             :      *-----------------------------------------------------------*/
    3038             : 
    3039      862816 :     noiseFillingBorder = L_spec;
    3040      862816 :     move16();
    3041      862816 :     IF( st->igf )
    3042             :     {
    3043      592605 :         noiseFillingBorder = st->hIGFEnc->infoStartLine;
    3044      592605 :         move16();
    3045             :     }
    3046      862816 :     *pnoiseFillingBorder = noiseFillingBorder;
    3047      862816 :     move16();
    3048             : 
    3049      862816 :     IF( st->igf )
    3050             :     {
    3051    88518813 :         FOR( i = st->hIGFEnc->infoStopLine; i < s_max( L_frame, L_frameTCX ); i++ )
    3052             :         {
    3053    87926208 :             spectrum_fx[i] = 0;
    3054    87926208 :             move32();
    3055             :         }
    3056             :     }
    3057             :     ELSE
    3058             :     {
    3059    14348371 :         FOR( i = noiseFillingBorder; i < s_max( L_frame, L_frameTCX ); i++ )
    3060             :         {
    3061    14078160 :             spectrum_fx[i] = 0;
    3062    14078160 :             move32();
    3063             :         }
    3064             :     }
    3065             : 
    3066             :     /*-----------------------------------------------------------*
    3067             :      * Quantization                                              *
    3068             :      *-----------------------------------------------------------*/
    3069             : 
    3070      862816 :     IF( !hTcxEnc->tcx_lpc_shaped_ari )
    3071             :     {
    3072             :         /* context based arithmetic coder */
    3073             : 
    3074             :         /* initialize signaling to default, i.e. context based AC is inactive */
    3075      845354 :         prm_hm[0] = 0;
    3076      845354 :         move16();
    3077      845354 :         prm_hm[1] = -1;
    3078      845354 :         move16();
    3079             : 
    3080             :         /* Fast estimation of the scalar quantizer step size */
    3081      845354 :         test();
    3082      845354 :         IF( st->hTcxCfg->ctx_hm && ( st->last_core != ACELP_CORE ) )
    3083      181180 :         {
    3084      181180 :             LtpPitchLag = -1;
    3085      181180 :             move16();
    3086             : 
    3087      181180 :             test();
    3088      181180 :             IF( ( st->tcxonly == 0 ) && ( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) ) )
    3089             :             {
    3090       50551 :                 tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
    3091       50551 :                 tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
    3092       50551 :                 LtpPitchLag = div_l( tmp32, tmp1 );
    3093             :             }
    3094             : 
    3095      181180 :             ctxHmBits = add( ctxHmBits, 1 );       /* ContextHM flag */
    3096      181180 :             sqTargetBits = sub( sqTargetBits, 1 ); /* ContextHM flag */
    3097             : 
    3098             :             Word16 LtpGain;
    3099      181180 :             IF( hTcxEnc->tcxltp )
    3100             :             {
    3101      108170 :                 LtpGain = hTcxEnc->tcxltp_gain;
    3102             :             }
    3103             :             ELSE
    3104             :             {
    3105       73010 :                 LtpGain = -MAX_16;
    3106             :             }
    3107      181180 :             move16();
    3108      181180 :             PeriodicityIndex = SearchPeriodicityIndex_fx( spectrum_fx, NULL, L_spec, sqTargetBits, LtpPitchLag, LtpGain, &RelativeScore_fx );
    3109             : 
    3110      181180 :             NumIndexBits = CountIndexBits( (Word16) GE_16( L_spec, (Word16) 256 ), PeriodicityIndex );
    3111             : 
    3112      181180 :             IF( st->element_mode > EVS_MONO )
    3113             :             {
    3114      181180 :                 ConfigureContextHm( L_spec, sub( sqTargetBits, NumIndexBits ), PeriodicityIndex, LtpPitchLag, hm_cfg );
    3115             :             }
    3116             :             ELSE
    3117             :             {
    3118           0 :                 ConfigureContextHm( L_spec, sqTargetBits, PeriodicityIndex, LtpPitchLag, hm_cfg );
    3119             :             }
    3120             : 
    3121             :             /* Quantize original spectrum */
    3122      181180 :             sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, ( mult( hTcxEnc->tcx_target_bits_fac, shl( sqTargetBits, 1 ) ) ), L_spec, &sqGain_e );
    3123             : 
    3124      181180 :             tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    3125             : 
    3126             :             /* Estimate original bitrate */
    3127      181180 :             stop = 0;
    3128      181180 :             move16();
    3129      181180 :             IF( st->element_mode > EVS_MONO )
    3130             :             {
    3131      181180 :                 sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    3132             :             }
    3133             :             ELSE
    3134             :             {
    3135           0 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, NULL );
    3136             :             }
    3137             : 
    3138             :             /* Estimate context mapped bitrate */
    3139      181180 :             stopCtxHm = 0;
    3140      181180 :             move16();
    3141             : 
    3142             :             /* Context Mapping */
    3143      181180 :             IF( st->element_mode > EVS_MONO )
    3144             :             {
    3145      181180 :                 sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
    3146             :             }
    3147             :             ELSE
    3148             :             {
    3149           0 :                 sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
    3150             :             }
    3151             : 
    3152             :             /* Decide whether or not to use context mapping */
    3153      181180 :             Selector = sub( s_max( stop, sqBits ), ( add( s_max( stopCtxHm, sqBitsCtxHm ), NumIndexBits ) ) );
    3154             : 
    3155      181180 :             test();
    3156      181180 :             test();
    3157      181180 :             IF( GT_16( Selector, 2 ) || ( LE_16( abs_s( Selector ), 2 ) && LT_16( kCtxHmOlRSThr, RelativeScore_fx ) ) )
    3158             :             {
    3159             :                 /* CtxHm is likely better */
    3160       12358 :                 sqTargetBits = sub( sqTargetBits, NumIndexBits );
    3161       12358 :                 ctxHmBits = add( ctxHmBits, NumIndexBits );
    3162       12358 :                 prm_hm[0] = 1;
    3163       12358 :                 move16();
    3164       12358 :                 prm_hm[1] = PeriodicityIndex;
    3165       12358 :                 move16();
    3166       12358 :                 *prm_lastnz = lastnzCtxHm;
    3167       12358 :                 move16();
    3168       12358 :                 sqBits_noStop = sqBits = sqBitsCtxHm;
    3169       12358 :                 move16();
    3170       12358 :                 move16();
    3171       12358 :                 nEncoded = nEncodedCtxHm;
    3172       12358 :                 move16();
    3173       12358 :                 stop = stopCtxHm;
    3174       12358 :                 move16();
    3175             :             }
    3176             :             ELSE
    3177             :             {
    3178             :                 /* Original is better or not much difference */
    3179      168822 :                 prm_hm[0] = 0;
    3180      168822 :                 move16();
    3181      168822 :                 prm_hm[1] = PeriodicityIndex;
    3182      168822 :                 move16();
    3183      168822 :                 *prm_lastnz = lastnz;
    3184      168822 :                 move16();
    3185      168822 :                 PeriodicityIndex = -1;
    3186      168822 :                 move16();
    3187             : 
    3188      168822 :                 sqBits_noStop = sqBits;
    3189      168822 :                 move16();
    3190             :             }
    3191             : 
    3192      181180 :             if ( stop != 0 )
    3193             :             {
    3194       66636 :                 sqBits = stop;
    3195       66636 :                 move16();
    3196             :             }
    3197             :         }
    3198             :         ELSE
    3199             :         {
    3200             :             /* no context hm*/
    3201      664174 :             PeriodicityIndex = -1;
    3202      664174 :             move16();
    3203             : 
    3204      664174 :             IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    3205             :             {
    3206      624490 :                 sqGain_fx = SQ_gain_estimate_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e );
    3207             :             }
    3208             :             ELSE
    3209             :             {
    3210       39684 :                 sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e );
    3211             :             }
    3212             :             /* Quantize spectrum */
    3213      664174 :             tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    3214             : 
    3215             :             /* Estimate bitrate */
    3216      664174 :             stop = 0;
    3217      664174 :             move16();
    3218             : 
    3219      664174 :             IF( st->element_mode > EVS_MONO )
    3220             :             {
    3221      664174 :                 sqBits_noStop = sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    3222      664174 :                 move16();
    3223             :             }
    3224             :             ELSE
    3225             :             {
    3226           0 :                 sqBits_noStop = sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, NULL );
    3227           0 :                 move16();
    3228             :             }
    3229             : 
    3230      664174 :             if ( stop != 0 )
    3231             :             {
    3232      345636 :                 sqBits = stop;
    3233      345636 :                 move16();
    3234             :             }
    3235             :         } /* end of if (ctx_hm) */
    3236             : 
    3237             :         /* Adjust correction factor */
    3238      845354 :         tmp1 = sqBits;
    3239      845354 :         move16();
    3240             : 
    3241      845354 :         if ( s_and( L_spec, sub( L_spec, 1 ) ) == 0 ) /* power-of-2 */
    3242             :         {
    3243           0 :             tmp1 = add( tmp1, 1 );
    3244             :         }
    3245             : 
    3246      845354 :         tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 );
    3247             :         BASOP_SATURATE_WARNING_OFF_EVS
    3248      845354 :         hTcxEnc->tcx_target_bits_fac = shl_o( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2, &Overflow );
    3249             :         BASOP_SATURATE_WARNING_ON_EVS
    3250             : 
    3251      845354 :         if ( GT_16( hTcxEnc->tcx_target_bits_fac, 20480 /*1.25 in Q14*/ ) )
    3252             :         {
    3253       86040 :             hTcxEnc->tcx_target_bits_fac = 20480;
    3254       86040 :             move16();
    3255             :         }
    3256      845354 :         if ( LT_16( hTcxEnc->tcx_target_bits_fac, 12288 /*.75 in Q14*/ ) )
    3257             :         {
    3258       56104 :             hTcxEnc->tcx_target_bits_fac = 12288;
    3259       56104 :             move16();
    3260             :         }
    3261             : 
    3262             :         /* Refine quantizer step size with a rate-control-loop (optional) */
    3263      845354 :         phm_cfg = NULL;
    3264      845354 :         move16();
    3265      845354 :         if ( PeriodicityIndex >= 0 )
    3266             :         {
    3267       12358 :             phm_cfg = hm_cfg;
    3268       12358 :             move16();
    3269             :         }
    3270             : 
    3271      845354 :         max_iter = 4;
    3272      845354 :         move16();
    3273      845354 :         if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    3274             :         {
    3275      624490 :             max_iter = 2;
    3276      624490 :             move16();
    3277             :         }
    3278      845354 :         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 );
    3279             : 
    3280      845354 :         IF( ctxHmBits > 0 )
    3281             :         {
    3282             :             /* Mapping tool is enabled */
    3283             :             /* Truncate spectrum */
    3284      181180 :             FOR( i = nEncoded; i < L_spec; i++ )
    3285             :             {
    3286      179726 :                 IF( st->element_mode > EVS_MONO )
    3287             :                 {
    3288      179726 :                     break;
    3289             :                 }
    3290             :                 ELSE
    3291             :                 {
    3292           0 :                     sqQ[i] = 0;
    3293           0 :                     move16();
    3294             :                 }
    3295             :             }
    3296             : 
    3297      181180 :             IF( PeriodicityIndex >= 0 )
    3298             :             {
    3299             :                 /* Mapping is used */
    3300             :                 /* Estimate non-mapped bitrate */
    3301       12358 :                 stopCtxHm = 1;
    3302       12358 :                 move16();
    3303       12358 :                 IF( st->element_mode > EVS_MONO )
    3304             :                 {
    3305             :                     /* Fix: Use updated value for target bits (sqTargetBits + NumIndexBits) before computing non-mapped estimate */
    3306       12358 :                     sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits + NumIndexBits, &stopCtxHm, 0, NULL );
    3307             :                 }
    3308             :                 ELSE
    3309             :                 {
    3310           0 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits, &stopCtxHm, NULL );
    3311             :                 }
    3312             : 
    3313             :                 /* Decide whether or not to revert mapping */
    3314       12358 :                 Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    3315             : 
    3316       12358 :                 IF( st->element_mode > EVS_MONO )
    3317             :                 {
    3318       12358 :                     test();
    3319       12358 :                     test();
    3320       12358 :                     IF( ( stopCtxHm == 0 && Selector > 0 ) || stop ) /* If overflow occured with mapped, select non-mapped */
    3321             :                     {
    3322             :                         /* Non-mapped is better */
    3323         478 :                         sqTargetBits = add( sqTargetBits, NumIndexBits );
    3324         478 :                         ctxHmBits = sub( ctxHmBits, NumIndexBits );
    3325         478 :                         prm_hm[0] = 0;
    3326         478 :                         move16();
    3327         478 :                         *prm_lastnz = lastnz;
    3328         478 :                         move16();
    3329         478 :                         PeriodicityIndex = -1;
    3330         478 :                         move16();
    3331         478 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    3332         478 :                         move16();
    3333         478 :                         move16();
    3334         478 :                         nEncoded = nEncodedCtxHm;
    3335         478 :                         move16();
    3336         478 :                         stop = stopCtxHm;
    3337         478 :                         move16();
    3338             :                     }
    3339             :                 }
    3340             :                 ELSE
    3341             :                 {
    3342           0 :                     test();
    3343           0 :                     IF( stopCtxHm == 0 && Selector > 0 )
    3344             :                     {
    3345             :                         /* Non-mapped is better */
    3346           0 :                         sqTargetBits = add( sqTargetBits, NumIndexBits );
    3347           0 :                         ctxHmBits = sub( ctxHmBits, NumIndexBits );
    3348           0 :                         prm_hm[0] = 0;
    3349           0 :                         move16();
    3350           0 :                         *prm_lastnz = lastnz;
    3351           0 :                         move16();
    3352           0 :                         PeriodicityIndex = -1;
    3353           0 :                         move16();
    3354           0 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    3355           0 :                         move16();
    3356           0 :                         move16();
    3357           0 :                         nEncoded = nEncodedCtxHm;
    3358           0 :                         move16();
    3359           0 :                         stop = stopCtxHm;
    3360           0 :                         move16();
    3361             :                     }
    3362             :                 }
    3363             :             }
    3364             :             ELSE
    3365             :             {
    3366             :                 /* Mapping is not used */
    3367      168822 :                 IF( st->element_mode > EVS_MONO )
    3368             :                 {
    3369             :                     /* Truncate Spectrum */
    3370    87694482 :                     FOR( i = nEncoded; i < L_spec; i++ )
    3371             :                     {
    3372    87525660 :                         sqQ[i] = 0;
    3373    87525660 :                         move16();
    3374             :                     }
    3375             :                 }
    3376             :                 /* Estimate mapped bitrate */
    3377      168822 :                 stopCtxHm = 1;
    3378      168822 :                 move16();
    3379      168822 :                 IF( st->element_mode > EVS_MONO )
    3380             :                 {
    3381      168822 :                     sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
    3382             :                 }
    3383             :                 ELSE
    3384             :                 {
    3385           0 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
    3386             :                 }
    3387             : 
    3388             :                 /* Decide whether or not to use mapping */
    3389      168822 :                 Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
    3390      168822 :                 test();
    3391      168822 :                 IF( stopCtxHm == 0 && Selector > 0 )
    3392             :                 {
    3393             :                     /* Mapped is better */
    3394         752 :                     sqTargetBits = sub( sqTargetBits, NumIndexBits );
    3395         752 :                     ctxHmBits = add( ctxHmBits, NumIndexBits );
    3396         752 :                     prm_hm[0] = 1;
    3397         752 :                     move16();
    3398         752 :                     *prm_lastnz = lastnzCtxHm;
    3399         752 :                     move16();
    3400         752 :                     PeriodicityIndex = prm_hm[1];
    3401         752 :                     move16();
    3402         752 :                     sqBits_noStop = sqBits = sqBitsCtxHm;
    3403         752 :                     move16();
    3404         752 :                     move16();
    3405         752 :                     nEncoded = nEncodedCtxHm;
    3406         752 :                     move16();
    3407         752 :                     stop = stopCtxHm;
    3408         752 :                     move16();
    3409             :                 }
    3410             :             }
    3411             :         }
    3412             : 
    3413             :         /* Limit low sqGain for avoiding saturation of the gain quantizer*/
    3414             :         /*(float) sqrt( (float) NORM_MDCT_FACTOR / (float) L_spec ) in Q14 */
    3415      845354 :         SWITCH( L_spec )
    3416             :         {
    3417           0 :             case 80:
    3418           0 :                 minSqGain = 23170;
    3419           0 :                 BREAK;
    3420           0 :             case 100:
    3421           0 :                 minSqGain = 20724;
    3422           0 :                 BREAK;
    3423        2140 :             case 160:
    3424        2140 :                 minSqGain = 16384;
    3425        2140 :                 BREAK;
    3426           0 :             case 200:
    3427           0 :                 minSqGain = 14654;
    3428           0 :                 BREAK;
    3429           0 :             case 240:
    3430           0 :                 minSqGain = 13377;
    3431           0 :                 BREAK;
    3432           0 :             case 300:
    3433           0 :                 minSqGain = 11965;
    3434           0 :                 BREAK;
    3435       70402 :             case 320:
    3436       70402 :                 minSqGain = 11585;
    3437       70402 :                 BREAK;
    3438         424 :             case 400:
    3439         424 :                 minSqGain = 10362;
    3440         424 :                 BREAK;
    3441       21994 :             case 480:
    3442       21994 :                 minSqGain = 9459;
    3443       21994 :                 BREAK;
    3444           0 :             case 600:
    3445           0 :                 minSqGain = 8461;
    3446           0 :                 BREAK;
    3447      210608 :             case 640:
    3448      210608 :                 minSqGain = 8192;
    3449      210608 :                 BREAK;
    3450        3125 :             case 800:
    3451        3125 :                 minSqGain = 7327;
    3452        3125 :                 BREAK;
    3453      532668 :             case 960:
    3454      532668 :                 minSqGain = 6689;
    3455      532668 :                 BREAK;
    3456        3993 :             case 1200:
    3457        3993 :                 minSqGain = 5983;
    3458        3993 :                 BREAK;
    3459           0 :             case 1440:
    3460           0 :                 minSqGain = 5461;
    3461           0 :                 BREAK;
    3462           0 :             case 1800:
    3463           0 :                 minSqGain = 4885;
    3464           0 :                 BREAK;
    3465           0 :             case 2048:
    3466           0 :                 minSqGain = 4579;
    3467           0 :                 BREAK;
    3468           0 :             default:
    3469           0 :                 assert( 0 );
    3470             :         }
    3471      845354 :         move16();
    3472      845354 :         Word16 shift_tmp = s_max( sqGain_e, 1 );
    3473      845354 :         test();
    3474      845354 :         IF( LT_16( st->hTcxCfg->tcxRateLoopOpt, 3 ) && LT_16( shl( sqGain_fx, sub( sqGain_e, shift_tmp ) ), shl( minSqGain, sub( 1, shift_tmp ) ) ) )
    3475             :         {
    3476        5028 :             sqGain_fx = minSqGain;
    3477        5028 :             move16();
    3478        5028 :             sqGain_e = 1;
    3479        5028 :             move16();
    3480             : 
    3481        5028 :             tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    3482        5028 :             stop = 1;
    3483        5028 :             IF( st->element_mode > EVS_MONO )
    3484             :             {
    3485             :                 /* Ensure non-mapped estimation is used for limiting low sqGain considering that this refinement occurs very rarely */
    3486        5028 :                 PeriodicityIndex = -1;
    3487        5028 :                 move16();
    3488        5028 :                 IF( prm_hm[0] == 1 )
    3489             :                 {
    3490           0 :                     prm_hm[0] = 0;
    3491           0 :                     move16();
    3492           0 :                     sqTargetBits = add( sqTargetBits, NumIndexBits );
    3493           0 :                     ctxHmBits = sub( ctxHmBits, NumIndexBits );
    3494             :                 }
    3495        5028 :                 sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    3496             :             }
    3497             :             ELSE
    3498             :             {
    3499           0 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, PeriodicityIndex >= 0 ? hm_cfg : NULL );
    3500             :             }
    3501             :         }
    3502             : 
    3503             :         /* Truncate spectrum (for CBR) */
    3504      845354 :         IF( stop )
    3505             :         {
    3506    61944292 :             FOR( i = nEncoded; i < L_spec; i++ )
    3507             :             {
    3508    61823140 :                 sqQ[i] = 0;
    3509    61823140 :                 move16();
    3510             :             }
    3511             :         }
    3512             : 
    3513             :         /* Save quantized Values */
    3514      845354 :         *nf_seed = 0;
    3515      845354 :         move16();
    3516   687885114 :         FOR( i = 0; i < L_spec; i++ )
    3517             :         {
    3518   687039760 :             spectrum_fx[i] = (Word32) sqQ[i];
    3519   687039760 :             move32();
    3520             :             /* noise filling seed */
    3521   687039760 :             *nf_seed = (Word16) L_add( *nf_seed, L_mult0( abs_s( sqQ[i] ), shl( i, 1 ) ) );
    3522   687039760 :             move16();
    3523             :         }
    3524             : 
    3525      845354 :         tmp32 = L_deposit_l( 0 );
    3526   687885114 :         FOR( i = 0; i < L_spec; i++ )
    3527             :         {
    3528   687039760 :             spectrum_fx[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) );
    3529   687039760 :             move32();
    3530             :             /* noise filling seed */
    3531   687039760 :             tmp32 = L_macNs_co( tmp32, abs_s( sqQ[i] ), i, &Carry, &Overflow );
    3532             :         }
    3533      845354 :         *spectrum_e = SPEC_EXP_DEC;
    3534      845354 :         move16();
    3535             : 
    3536      845354 :         *nf_seed = extract_l( tmp32 );
    3537             :     }
    3538             :     ELSE
    3539             :     {
    3540             :         /* low rates: envelope based arithmetic coder */
    3541             : 
    3542       17462 :         AdaptLowFreqEmph_fx( spectrum_fx, *spectrum_e, NULL, 0, 0, 1, gainlpc_fx, gainlpc_e, L_frame );
    3543             : 
    3544       17462 :         prm_target = sqQ;
    3545       17462 :         sqQ = prm_target + 1;
    3546             : 
    3547       17462 :         LtpPitchLag = -1;
    3548       17462 :         move16();
    3549             : 
    3550       17462 :         IF( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) )
    3551             :         {
    3552        7683 :             tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
    3553        7683 :             tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
    3554        7683 :             LtpPitchLag = div_l( tmp32, tmp1 );
    3555             :         }
    3556             : 
    3557       17462 :         Word8 tmp8 = 1;
    3558       17462 :         move16();
    3559       17462 :         if ( st->last_core == ACELP_CORE )
    3560             :         {
    3561        1646 :             tmp8 = 0;
    3562        1646 :             move16();
    3563             :         }
    3564       17462 :         Word16 low_complexiety = 0;
    3565       17462 :         move16();
    3566       17462 :         if ( GT_16( st->bwidth, WB ) )
    3567             :         {
    3568       16176 :             low_complexiety = 1;
    3569       16176 :             move16();
    3570             :         }
    3571       17462 :         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 );
    3572             : 
    3573       17462 :         sqTargetBits = sub( sqTargetBits, signaling_bits );
    3574       17462 :         *prm_target = sqTargetBits;
    3575       17462 :         move16();
    3576             : 
    3577             :         /* Noise filling seed */
    3578       17462 :         Word64 seed = 0;
    3579       17462 :         move64();
    3580     3652454 :         FOR( i = 0; i < noiseFillingBorder; ++i )
    3581             :         {
    3582             :             /* *nf_seed += (int16_t) ( abs( (int16_t) spectrum[i] ) * i * 2 ); */
    3583     3634992 :             seed = W_mac_32_32( seed, L_abs( spectrum_fx[i] ), i ); // exp: spectrum_e
    3584             :         }
    3585       17462 :         *nf_seed = extract_l( W_extract_l( W_shr( seed, sub( 31, *spectrum_e ) ) ) ); // Q0
    3586       17462 :         move16();
    3587             :     }
    3588             : 
    3589      862816 :     *hm_active = prm_hm[0];
    3590      862816 :     move16();
    3591             : 
    3592             :     /*-----------------------------------------------------------*
    3593             :      * Compute optimal TCX gain.                                 *
    3594             :      *-----------------------------------------------------------*/
    3595             : 
    3596      862816 :     IF( lf_deemph_fact_fx != NULL )
    3597             :     {
    3598             :         /* initialize LF deemphasis factors in lf_deemph_fact */
    3599   198898486 :         FOR( i = 0; i < L_spec; i++ )
    3600             :         {
    3601   198660160 :             lf_deemph_fact_fx[i] = ONE_IN_Q14;
    3602   198660160 :             move16();
    3603             :         }
    3604             :     }
    3605             : 
    3606      862816 :     IF( !st->tcxonly )
    3607             :     {
    3608      129402 :         AdaptLowFreqDeemph( spectrum_fx, *spectrum_e, hTcxEnc->tcx_lpc_shaped_ari, gainlpc_fx, gainlpc_e, L_frame, lf_deemph_fact_fx );
    3609             :     }
    3610             : 
    3611      862816 :     assert( x_orig_fx != spectrum_fx );
    3612             : 
    3613      862816 :     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 );
    3614             : 
    3615      862816 :     IF( gain_tcx_opt_fx <= 0 )
    3616             :     {
    3617        2306 :         gain_tcx_opt_fx = sqGain_fx;
    3618        2306 :         move16();
    3619        2306 :         gain_tcx_opt_e = sqGain_e;
    3620        2306 :         move16();
    3621             :     }
    3622      862816 :     *gain_tcx_fx = gain_tcx_opt_fx;
    3623      862816 :     move16();
    3624      862816 :     *gain_tcx_e = gain_tcx_opt_e;
    3625      862816 :     move16();
    3626             : 
    3627      862816 :     test();
    3628      862816 :     IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) )
    3629             :     {
    3630       14424 :         calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag );
    3631       14424 :         *gain_tcx_fx = mult( *gain_tcx_fx, att_fx );
    3632       14424 :         move16();
    3633             :     }
    3634             : 
    3635             :     /*-----------------------------------------------------------*
    3636             :      * Quantize TCX gain                                         *
    3637             :      *-----------------------------------------------------------*/
    3638             : 
    3639             :     /*  gain quantization here in case of VBR unvoiced coding; fixes problems of uninitialized global gain values */
    3640      862816 :     test();
    3641      862816 :     IF( GE_32( total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    3642             :     {
    3643      829621 :         QuantizeGain( L_spec, gain_tcx_fx, gain_tcx_e, &prm[0] );
    3644             :     }
    3645             : 
    3646             :     /*-----------------------------------------------------------*
    3647             :      * Residual Quantization                                     *
    3648             :      *-----------------------------------------------------------*/
    3649             : 
    3650      862816 :     IF( st->hTcxCfg->resq )
    3651             :     {
    3652      391706 :         resQTargetBits = sub( sqTargetBits, sqBits );
    3653             : 
    3654      391706 :         IF( hTcxEnc->tcx_lpc_shaped_ari )
    3655             :         {
    3656             :             /* envelope based arithmetic coder */
    3657             :             Word16 *prm_resq;
    3658             : 
    3659       17462 :             prm_resq = sqQ + sub( sqTargetBits, resQTargetBits );
    3660             : 
    3661       17462 :             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 );
    3662             : 
    3663             :             /* Transmit zeros when there bits remain after RESQ */
    3664       18680 :             FOR( i = resQBits; i < resQTargetBits; ++i )
    3665             :             {
    3666        1218 :                 prm_resq[i] = 0;
    3667        1218 :                 move16();
    3668             :             }
    3669             :         }
    3670             :         ELSE
    3671             :         {
    3672             :             /* context based arithmetic coder */
    3673      374244 :             resQBits = tcx_res_Q_gain_fx( gain_tcx_opt_fx, gain_tcx_opt_e, gain_tcx_fx, gain_tcx_e, sqQ + L_spec, resQTargetBits );
    3674      374244 :             IF( st->tcxonly )
    3675             :             {
    3676      262304 :                 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 );
    3677             :             }
    3678             :             ELSE
    3679             :             {
    3680      111940 :                 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 );
    3681             :             }
    3682             :         }
    3683             :     }
    3684             : 
    3685      862816 :     tmp1 = norm_s( *gain_tcx_fx );
    3686      862816 :     *gain_tcx_fx = shl( *gain_tcx_fx, tmp1 );
    3687      862816 :     move16();
    3688      862816 :     *gain_tcx_e = sub( *gain_tcx_e, tmp1 );
    3689      862816 :     move16();
    3690             : 
    3691             :     /*-----------------------------------------------------------*
    3692             :      * ALFE tcx only bitrates                                    *
    3693             :      *-----------------------------------------------------------*/
    3694             : 
    3695      862816 :     IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
    3696             :     {
    3697      238326 :         IF( st->tcxonly )
    3698             :         {
    3699      108924 :             test();
    3700      108924 :             test();
    3701      108924 :             IF( hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !hTcxEnc->fUseTns[frame_cnt] )
    3702             :             {
    3703        3721 :                 PsychAdaptLowFreqDeemph( spectrum_fx, gainlpc_fx, gainlpc_e, NULL );
    3704             :             }
    3705             :         }
    3706             :     }
    3707             : 
    3708      862816 :     return;
    3709             : }
    3710             : 
    3711         637 : void coder_tcx_fx(
    3712             :     Word16 n,
    3713             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    3714             :     Word16 A[],                /* input: quantized coefficients NxAz_q[M+1] */
    3715             :     Word16 Aqind[],            /* input: frame-independent quantized coefficients (M+1) */
    3716             :     Word16 synth[],            /*Qx*/
    3717             :     Word16 L_frame_glob,       /* input: frame length             */
    3718             :     Word16 L_frameTCX_glob,
    3719             :     Word16 L_spec,
    3720             :     Word16 nb_bits,     /*input: bit budget*/
    3721             :     Word8 tcxonly,      /*input: only TCX flag*/
    3722             :     Word32 spectrum[],  /* i/o: MDCT spectrum Q(31-spectrum_e)*/
    3723             :     Word16 *spectrum_e, /* i/o: MDCT spectrum exponent               */
    3724             :     Word16 prm[],       /* output: tcx parameters          */
    3725             :     Encoder_State *st,
    3726             :     CONTEXT_HM_CONFIG *hm_cfg )
    3727             : {
    3728             :     Word16 L_frame;
    3729             :     Word16 left_overlap, right_overlap;
    3730             :     Word16 tnsSize; /* number of tns parameters put into prm */
    3731             :     Word16 tnsBits; /* number of tns bits in the frame */
    3732             :     Word16 ltpBits;
    3733             :     Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
    3734             :     Word16 win[N_MAX + L_MDCT_OVLP_MAX];
    3735             :     Word32 powerSpec[N_MAX];
    3736             :     Word16 powerSpec_e;
    3737             :     Word16 winMDST[N_MAX + L_MDCT_OVLP_MAX];
    3738             :     Word16 *pWinMDST;
    3739             :     Word16 left_overlap_mode, right_overlap_mode;
    3740         637 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    3741             : 
    3742         637 :     left_overlap = right_overlap = -1;
    3743         637 :     move16();
    3744         637 :     move16();
    3745         637 :     tnsSize = 0;
    3746         637 :     move16();
    3747         637 :     tnsBits = 0;
    3748         637 :     move16();
    3749         637 :     ltpBits = 0;
    3750         637 :     move16();
    3751             : 
    3752         637 :     L_frame = L_frameTCX_glob;
    3753         637 :     move16();
    3754             : 
    3755             :     /*-----------------------------------------------------------*
    3756             :      * Windowing                                                 *
    3757             :      *-----------------------------------------------------------*/
    3758         637 :     IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    3759             :     {
    3760             : 
    3761          34 :         WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap,
    3762          34 :                       hTcxEnc->speech_TCX, &L_frame, win, 1, 1 );
    3763             : 
    3764             :         /*-----------------------------------------------------------*
    3765             :          * Compute MDCT                                              *
    3766             :          *-----------------------------------------------------------*/
    3767             : 
    3768          34 :         *spectrum_e = 16;
    3769          34 :         move16();
    3770          34 :         TCX_MDCT( win, spectrum, spectrum_e, left_overlap, sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
    3771             :     }
    3772             :     ELSE
    3773             :     {
    3774             :         Word32 tmp_buf[L_FRAME_PLUS];
    3775             :         Word16 Q, tmp1, tmp2, i;
    3776             : 
    3777         603 :         Q = 0;
    3778         603 :         move16();
    3779             : 
    3780         603 :         wtda_fx( hTcxEnc->new_speech_TCX, &Q, tmp_buf, NULL, NULL, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, L_frame );
    3781             : 
    3782         603 :         left_overlap_mode = hTcxCfg->tcx_last_overlap_mode;
    3783         603 :         move16();
    3784         603 :         if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
    3785             :         {
    3786         594 :             left_overlap_mode = FULL_OVERLAP;
    3787         594 :             move16();
    3788             :         }
    3789         603 :         right_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
    3790         603 :         move16();
    3791         603 :         if ( EQ_16( right_overlap_mode, ALDO_WINDOW ) )
    3792             :         {
    3793         591 :             right_overlap_mode = FULL_OVERLAP;
    3794         591 :             move16();
    3795             :         }
    3796             : 
    3797         603 :         WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, hTcxEnc->speech_TCX, &L_frame, winMDST, 1, 1 );
    3798             : 
    3799             :         /* scale by NORM_MDCT_FACTOR / L */
    3800         603 :         tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
    3801         603 :         tmp2 = 4;
    3802         603 :         move16();
    3803         603 :         tmp1 = ISqrt16( tmp1, &tmp2 );
    3804             : 
    3805      499483 :         FOR( i = 0; i < L_frame; i++ )
    3806             :         {
    3807      498880 :             tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
    3808      498880 :             move32();
    3809             :         }
    3810         603 :         Q = sub( Q, tmp2 );
    3811             : 
    3812             :         /* DCT */
    3813         603 :         edct_fx( tmp_buf, spectrum, L_frame, &Q );
    3814         603 :         *spectrum_e = sub( 31, Q );
    3815         603 :         move16();
    3816             :     }
    3817             : 
    3818             : 
    3819             :     /*-----------------------------------------------------------*
    3820             :      * Attenuate upper end of NB spectrum,                       *
    3821             :      * to simulate ACELP behavior                                *
    3822             :      *-----------------------------------------------------------*/
    3823             : 
    3824         637 :     IF( st->narrowBand != 0 )
    3825             :     {
    3826           0 :         attenuateNbSpectrum_fx( L_frame, spectrum );
    3827             :     }
    3828             : 
    3829             :     /*-----------------------------------------------------------*
    3830             :      * Compute noise-measure flags for spectrum filling          *
    3831             :      * and quantization (0: tonal, 1: noise-like).               *
    3832             :      * Detect low pass if present.                               *
    3833             :      *-----------------------------------------------------------*/
    3834             : 
    3835         637 :     pWinMDST = winMDST;
    3836         637 :     move16();
    3837         637 :     if ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    3838             :     {
    3839          34 :         pWinMDST = win;
    3840          34 :         move16();
    3841             :     }
    3842             : 
    3843         637 :     AnalyzePowerSpectrum_fx( st,
    3844         637 :                              round_fx( L_shl( Mpy_32_16_1( L_mult0( L_frame, st->L_frame ) /*Q0*/,
    3845         637 :                                                            getInvFrameLen( hTcxEnc->L_frameTCX ) /*Q21*/ ) /*Q6*/,
    3846             :                                               16 - 6 ) ),
    3847             :                              L_frame,
    3848             :                              left_overlap, right_overlap,
    3849         637 :                              spectrum, *spectrum_e,
    3850             :                              pWinMDST,
    3851             :                              powerSpec, &powerSpec_e );
    3852         637 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
    3853             :     {
    3854             : 
    3855         376 :         SetTnsConfig( hTcxCfg, sub( L_frame_glob, st->L_frame ) == 0, st->last_core == 0 );
    3856             : 
    3857         376 :         TNSAnalysis_fx( hTcxCfg, L_frame, L_spec, TCX_20, st->last_core == 0, spectrum, hTcxEnc->tnsData, hTcxEnc->fUseTns, &st->hIGFEnc->tns_predictionGain );
    3858             :     }
    3859             :     ELSE
    3860             :     {
    3861         261 :         hTcxEnc->fUseTns[0] = hTcxEnc->fUseTns[1] = 0;
    3862         261 :         move16();
    3863         261 :         move16();
    3864             :     }
    3865             : 
    3866         637 :     IF( st->igf )
    3867             :     {
    3868         637 :         ProcessIGF_fx( st->hIGFEnc, st, spectrum, spectrum_e, powerSpec, &powerSpec_e, 1, hTcxEnc->fUseTns[0], ( st->last_core == ACELP_CORE ), 0 );
    3869             :     }
    3870             : 
    3871         637 :     ShapeSpectrum_fx( hTcxCfg, A, gainlpc, gainlpc_e,
    3872             :                       L_frame_glob,
    3873             :                       L_spec,
    3874             :                       spectrum,
    3875         637 :                       hTcxEnc->fUseTns[0],
    3876             :                       st );
    3877         637 :     if ( st->igf )
    3878             :     {
    3879         637 :         nb_bits = sub( nb_bits, st->hIGFEnc->infoTotalBitsPerFrameWritten );
    3880             :     }
    3881         637 :     IF( hTcxCfg->fIsTNSAllowed != 0 )
    3882             :     {
    3883         376 :         EncodeTnsData_fx( hTcxCfg->pCurrentTnsConfig, hTcxEnc->tnsData, prm + 1 + NOISE_FILL_RANGES + LTPSIZE, &tnsSize, &tnsBits );
    3884             :     }
    3885             : 
    3886         637 :     QuantizeSpectrum_fx( hTcxCfg,
    3887             :                          A,
    3888             :                          Aqind,
    3889             :                          gainlpc, gainlpc_e,
    3890             :                          synth,
    3891             :                          L_frame_glob,
    3892             :                          L_frameTCX_glob,
    3893             :                          L_spec,
    3894         637 :                          sub( sub( nb_bits, tnsBits ), ltpBits ),
    3895             :                          tcxonly,
    3896             :                          spectrum, spectrum_e,
    3897         637 :                          hTcxEnc->tnsData,
    3898         637 :                          hTcxEnc->fUseTns[0],
    3899             :                          tnsSize,
    3900             :                          prm,
    3901             :                          n,
    3902             :                          st,
    3903             :                          hm_cfg );
    3904         637 : }
    3905             : 
    3906             : 
    3907             : /*-------------------------------------------------------------------*
    3908             :  * coder_tcx_post_fx()
    3909             :  *
    3910             :  *
    3911             :  *-------------------------------------------------------------------*/
    3912             : 
    3913         637 : void coder_tcx_post_fx(
    3914             :     Encoder_State *st,
    3915             :     LPD_state *LPDmem,
    3916             :     TCX_CONFIG_HANDLE hTcxCfg,
    3917             :     /* i  : configuration of TCX               */ Word16 *synth,
    3918             :     const Word16 *A,
    3919             :     const Word16 *Ai,
    3920             :     Word16 *wsig,
    3921             :     Word16 Q_new,
    3922             :     Word16 shift )
    3923             : {
    3924             :     Word16 xn_buf[L_FRAME_MAX];
    3925             : 
    3926             :     /* TCX output */
    3927         637 :     Copy( synth, xn_buf, st->L_frame );
    3928             : 
    3929             : 
    3930             :     /*-----------------------------------------------------------*
    3931             :      * Memory update                                             *
    3932             :      *-----------------------------------------------------------*/
    3933             : 
    3934             :     /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
    3935         637 :     tcx_encoder_memory_update_fx( wsig, xn_buf, st->L_frame, Ai, A, hTcxCfg->preemph_fac, LPDmem, st, synth, Q_new, shift );
    3936             : 
    3937         637 :     return;
    3938             : }
    3939      236267 : void coder_tcx_post_ivas_fx(
    3940             :     Encoder_State *st,
    3941             :     LPD_state *LPDmem,
    3942             :     TCX_CONFIG_HANDLE hTcxCfg, /* i  : configuration of TCX               */
    3943             :     Word16 *synth,
    3944             :     const Word16 *A,
    3945             :     const Word16 *Ai,
    3946             :     Word16 *wsig,
    3947             :     Word16 Q_new )
    3948             : {
    3949             :     Word16 xn_buf[L_FRAME_MAX];
    3950             : 
    3951             :     /* TCX output */
    3952      236267 :     Copy( synth, xn_buf, st->L_frame );
    3953             : 
    3954             : 
    3955             :     /*-----------------------------------------------------------*
    3956             :      * Memory update                                             *
    3957             :      *-----------------------------------------------------------*/
    3958             : 
    3959             :     /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
    3960      236267 :     tcx_encoder_memory_update_ivas_fx( wsig, xn_buf, st->L_frame, Ai, A, hTcxCfg->preemph_fac, LPDmem, st, synth, Q_new );
    3961             : 
    3962      236267 :     return;
    3963             : }
    3964             : 
    3965             : 
    3966             : /*-------------------------------------------------------------------*
    3967             :  * InternalTCXDecoder_fx()
    3968             :  *
    3969             :  *
    3970             :  *-------------------------------------------------------------------*/
    3971             : 
    3972      238326 : void InternalTCXDecoder_fx(
    3973             :     Encoder_State *st,               /* i/o: state handle                            */
    3974             :     const Word16 frame_cnt,          /* i  : frame counter in the super_frame        */
    3975             :     const Word16 L_frameTCX,         /* i  : full frame length                       */
    3976             :     const Word16 L_frame,            /* i  : frame length                            */
    3977             :     const Word16 L_spec,             /* i  : length of the coded spectrum            */
    3978             :     const Word16 tcx_offset,         /* i  : folding point offset relative to the end of the previous frame */
    3979             :     const Word16 noiseFillingBorder, /* i  : noise filling border                    */
    3980             :     const Word32 *x_quant_fx,        /* i  : quantized spectrum, exponent same as spectrum_e                      */
    3981             :     const Word32 ener_fx,            /* i  : energy of the quantized spectrum    Q(31-ener_e)    */
    3982             :     const Word16 ener_e,             /* i  : exponent of energy of the quantized spectrum         */
    3983             :     Word16 lf_deemph_fact_fx[],      /* i/o: low frequency deemphasis factors        */
    3984             :     const Word16 fac_ns_fx,          /* i  : noise filling level, Q15                     */
    3985             :     const Word16 nf_seed,            /* i  : noise filling random seed, Q0               */
    3986             :     const Word16 *A_fx,              /* i  : LPC representation of the FDNS gains, Q = 14 - norm_s(A_fx[0])    */
    3987             :     Word16 gainlpc_fx[],             /* i/o: FDNS gains                           Q(15-gainlpc_e)   */
    3988             :     Word16 gainlpc_e[],              /* i/o: FDNS gains exponents                              */
    3989             :     const Word16 hm_active,          /* i  : flag indicating if the harmonic model is active */
    3990             :     Word16 gain_tcx_fx,              /* i/o: global gain / quantized global gain     Q(15-gain_tcx_e)        */
    3991             :     Word16 *gain_tcx_e,              /* i/o: global gain / quantized global gain exponent             */
    3992             :     Word32 spectrum_fx[],            /* o  : dequantized spectrum               Q(31-spectrum_e)     */
    3993             :     Word16 *spectrum_e,              /* o  : exponent of dequantized spectrum                    */
    3994             :     Word16 synth[],                  /* o  : time domain signal                      */
    3995             :     Word16 *gain_tcx_q               /* o  : quantized global gain (at low bitrates), Q0 */
    3996             : )
    3997             : {
    3998      238326 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    3999             :     Word16 i, iStart, noiseTransWidth;
    4000             :     Word16 tcx_last_overlap_mode, overlap;
    4001             :     Word16 nz;   /* non-zero length in ALDO window*/
    4002             :     Word16 aldo; /* ALDO flag in current frame*/
    4003             :     Word16 tmp1, tmp2, tmp3, tmp4, s;
    4004             :     Word16 *tmpP16;
    4005             :     Word16 q_spec, len;
    4006             :     Word32 tmp32;
    4007             :     Word32 xn_buf32[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
    4008             :     Word16 Aq_old_fx[M + 1];
    4009             :     Word32 sns_interpolated_scalefactors_fx[FDNS_NPTS], A_fx32[M + 1];
    4010      238326 :     Word16 *xn_buf16 = (Word16 *) xn_buf32;
    4011             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    4012      238326 :     Flag Overflow = 0;
    4013      238326 :     move32();
    4014             : #endif
    4015             : 
    4016      238326 :     Copy32( x_quant_fx, spectrum_fx, s_max( L_frame, L_spec ) );
    4017             : 
    4018             :     /* Replication of ACELP formant enhancement for low rates */
    4019      238326 :     test();
    4020      238326 :     IF( st->total_brate < ACELP_13k20 || st->rf_mode )
    4021             :     {
    4022       33195 :         tcxFormantEnhancement( lf_deemph_fact_fx, gainlpc_fx, gainlpc_e, spectrum_fx, spectrum_e, L_frame, L_spec );
    4023             :     }
    4024             : 
    4025             :     /*-----------------------------------------------------------*
    4026             :      * Noise Filling.                                            *
    4027             :      *-----------------------------------------------------------*/
    4028             : 
    4029      238326 :     IF( fac_ns_fx > 0 )
    4030             :     {
    4031      219697 :         tmp1 = 0;
    4032      219697 :         move16();
    4033      219697 :         test();
    4034      219697 :         if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
    4035             :         {
    4036      186670 :             tmp1 = 1;
    4037      186670 :             move16();
    4038             :         }
    4039      219697 :         iStart = tcxGetNoiseFillingTilt( A_fx, M, L_frame, tmp1, &hTcxEnc->noiseTiltFactor );
    4040             : 
    4041      219697 :         tmp1 = 0;
    4042      219697 :         move16();
    4043      219697 :         test();
    4044      219697 :         test();
    4045      219697 :         if ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active )
    4046             :         {
    4047       12572 :             tmp1 = 1;
    4048       12572 :             move16();
    4049             :         }
    4050      219697 :         noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame, shr( st->L_frame, 1 ) ), hTcxEnc->tcxltp_gain, tmp1 );
    4051      219697 :         assert( st->element_mode != IVAS_CPE_MDCT );
    4052      219697 :         tcx_noise_filling( spectrum_fx, *spectrum_e, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns_fx, NULL, st->element_mode );
    4053             :     }
    4054             : 
    4055      238326 :     test();
    4056      238326 :     IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 )
    4057             :     {
    4058             :         /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */
    4059       33195 :         s = sub( getScaleFactor32( spectrum_fx, L_spec ), 4 );
    4060       33195 :         tmp32 = L_deposit_l( 1 );
    4061             : 
    4062    21411675 :         FOR( i = 0; i < L_spec; i++ )
    4063             :         {
    4064    21378480 :             tmp1 = round_fx( L_shl( spectrum_fx[i], s ) );
    4065    21378480 :             tmp32 = L_mac0( tmp32, tmp1, tmp1 );
    4066             :         }
    4067             : 
    4068       33195 :         tmp1 = BASOP_Util_Divide3232_Scale( ener_fx, tmp32, &tmp2 );
    4069       33195 :         tmp2 = add( tmp2, sub( ener_e, add( shl( sub( *spectrum_e, s ), 1 ), 1 ) ) );
    4070       33195 :         tmp1 = Sqrt16( tmp1, &tmp2 );
    4071             : 
    4072       33195 :         gain_tcx_fx = mult( gain_tcx_fx, tmp1 ); // Q(15-(gain_tcx_e+tmp2))
    4073       33195 :         *gain_tcx_e = add( *gain_tcx_e, tmp2 );
    4074       33195 :         move16();
    4075             : 
    4076       33195 :         QuantizeGain( L_spec, &gain_tcx_fx, gain_tcx_e, gain_tcx_q );
    4077             :     }
    4078             : 
    4079             :     /*end of noise filling*/
    4080             : 
    4081             :     /*-----------------------------------------------------------*
    4082             :      * Noise shaping in frequency domain (1/Wz)                  *
    4083             :      *-----------------------------------------------------------*/
    4084             : 
    4085      238326 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
    4086             :     {
    4087           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
    4088             : 
    4089           0 :         q_spec = sub( 31, *spectrum_e );
    4090           0 :         sns_interpolate_scalefactors_fx( sns_interpolated_scalefactors_fx, A_fx32, DEC );
    4091           0 :         sns_shape_spectrum_fx( spectrum_fx, &q_spec, st->hTcxCfg->psychParamsCurrent, sns_interpolated_scalefactors_fx, Q16, L_frame, &len );
    4092             : 
    4093           0 :         test();
    4094           0 :         test();
    4095           0 :         IF( NE_16( len, L_frame ) && LT_16( q_spec, sub( 31, *spectrum_e ) ) )
    4096             :         {
    4097           0 :             scale_sig32( spectrum_fx + len, sub( L_frame, len ), sub( q_spec, sub( 15, *spectrum_e ) ) ); // q_spec
    4098             :         }
    4099           0 :         ELSE IF( NE_16( len, L_frame ) && GT_16( q_spec, sub( 31, *spectrum_e ) ) )
    4100             :         {
    4101           0 :             scale_sig32( spectrum_fx, len, sub( sub( 15, *spectrum_e ), q_spec ) ); // Q(31-spectrum_e)
    4102           0 :             q_spec = sub( 31, *spectrum_e );
    4103             :         }
    4104           0 :         *spectrum_e = sub( 31, q_spec );
    4105           0 :         move16();
    4106             :     }
    4107             :     ELSE
    4108             :     {
    4109      238326 :         mdct_noiseShaping_ivas_fx( spectrum_fx, spectrum_e, L_frame, gainlpc_fx, gainlpc_e );
    4110             :     }
    4111             :     /*-----------------------------------------------------------*
    4112             :      * Apply gain                                                *
    4113             :      *-----------------------------------------------------------*/
    4114             : 
    4115      238326 :     IF( st->hTcxCfg->coder_type == INACTIVE )
    4116             :     {
    4117       13524 :         gain_tcx_fx = mult_r( gain_tcx_fx, st->hTcxCfg->na_scale );
    4118             :     }
    4119             : 
    4120   198898486 :     FOR( i = 0; i < L_spec; i++ )
    4121             :     {
    4122   198660160 :         spectrum_fx[i] = Mpy_32_16_1( spectrum_fx[i], gain_tcx_fx );
    4123   198660160 :         move32();
    4124             :     }
    4125      238326 :     *spectrum_e = add( *spectrum_e, *gain_tcx_e );
    4126      238326 :     move16();
    4127             : 
    4128      238326 :     tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    4129      238326 :     move16();
    4130             : 
    4131      238326 :     test();
    4132      238326 :     IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    4133             :     {
    4134        4118 :         Word16 L = L_frame;
    4135        4118 :         move16();
    4136             : 
    4137        4118 :         test();
    4138        4118 :         test();
    4139        4118 :         if ( ( ( st->hTcxCfg->fIsTNSAllowed != 0 ) && ( hTcxEnc->fUseTns[frame_cnt] != 0 ) ) || ( GT_16( L_spec, L_frame ) ) )
    4140             :         {
    4141        4018 :             L = L_spec;
    4142        4018 :             move16();
    4143             :         }
    4144             : 
    4145        4118 :         tcxInvertWindowGrouping( st->hTcxCfg,
    4146             :                                  xn_buf32,
    4147             :                                  spectrum_fx,
    4148             :                                  L,
    4149        4118 :                                  hTcxEnc->fUseTns[frame_cnt],
    4150        4118 :                                  st->last_core,
    4151             :                                  tcx_last_overlap_mode,
    4152             :                                  frame_cnt,
    4153             :                                  0 );
    4154             :     }
    4155             : 
    4156             :     /*-----------------------------------------------------------*
    4157             :      * Temporal Noise Shaping Synthesis                          *
    4158             :      *-----------------------------------------------------------*/
    4159             : 
    4160      238326 :     IF( st->hTcxCfg->fIsTNSAllowed )
    4161             :     {
    4162      161512 :         test();
    4163      161512 :         SetTnsConfig( st->hTcxCfg, (Word16) EQ_16( st->core, TCX_20_CORE ), ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
    4164             : 
    4165             :         /* Apply TNS to get the reconstructed signal */
    4166      161512 :         IF( hTcxEnc->fUseTns[frame_cnt] != 0 )
    4167             :         {
    4168       17618 :             ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frame_cnt], spectrum_fx, 0 );
    4169             : 
    4170       17618 :             test();
    4171       17618 :             IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    4172             :             {
    4173        2365 :                 test();
    4174        2365 :                 test();
    4175        2365 :                 test();
    4176        2365 :                 IF( ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
    4177             :                     ( ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( tcx_last_overlap_mode == 0 ) ) )
    4178             :                 {
    4179        1717 :                     const Word16 L_win = shr( L_spec, 1 );
    4180             :                     /* undo rearrangement of LF sub-window lines for TNS synthesis filter */
    4181        1717 :                     IF( GT_16( L_frame, L_spec ) )
    4182             :                     {
    4183           0 :                         assert( 0 );
    4184             :                     }
    4185             :                     ELSE
    4186             :                     {
    4187        1717 :                         Copy32( spectrum_fx + 8, xn_buf32, L_win );
    4188        1717 :                         Copy32( xn_buf32, spectrum_fx + L_win, 8 );
    4189        1717 :                         Copy32( xn_buf32 + 8, spectrum_fx + 8, L_win - 8 );
    4190             :                     }
    4191             :                 }
    4192             :             }
    4193             :         }
    4194             :     }
    4195             : 
    4196             : 
    4197             :     /*-----------------------------------------------------------*
    4198             :      * Compute inverse MDCT of spectrum[].                        *
    4199             :      *-----------------------------------------------------------*/
    4200             : 
    4201      238326 :     E_LPC_f_lsp_a_conversion( st->lsp_old_fx, Aq_old_fx, M );
    4202      238326 :     overlap = st->hTcxCfg->tcx_mdct_window_length;
    4203      238326 :     nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS );
    4204      238326 :     aldo = 0;
    4205      238326 :     move16();
    4206      238326 :     move16();
    4207             : 
    4208             :     /* normalize spectrum to minimize IMDCT noise */
    4209      238326 :     s = getScaleFactor32( spectrum_fx, L_frame );
    4210   106045126 :     FOR( i = 0; i < L_frame; i++ )
    4211             :     {
    4212   105806800 :         spectrum_fx[i] = L_shl( spectrum_fx[i], s );
    4213   105806800 :         move32();
    4214             :     }
    4215      238326 :     *spectrum_e = sub( *spectrum_e, s );
    4216      238326 :     move16();
    4217             : 
    4218      238326 :     test();
    4219      238326 :     IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
    4220             :     {
    4221        4118 :         IF( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP )
    4222             :         {
    4223             :             Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    4224             :             Word16 L_win, L_spec_TCX5, L_ola, w;
    4225             : 
    4226             :             /* minimum or half overlap, two transforms, grouping into one window */
    4227        1601 :             L_win = shr( L_frame, 1 );
    4228        1601 :             L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
    4229        1601 :             L_ola = st->hTcxCfg->tcx_mdct_window_half_length;
    4230        1601 :             move16();
    4231        1601 :             if ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    4232             :             {
    4233         770 :                 L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
    4234         770 :                 move16();
    4235             :             }
    4236             : 
    4237        1601 :             set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    4238        1601 :             set16_fx( xn_buf16, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */
    4239             : 
    4240        4803 :             FOR( w = 0; w < 2; w++ )
    4241             :             {
    4242             : 
    4243        3202 :                 IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
    4244             :                 {
    4245        1540 :                     TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4246        1540 :                                       win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    4247             :                 }
    4248             :                 ELSE
    4249             :                 {
    4250        1662 :                     TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win,
    4251        1662 :                                       L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    4252             :                 }
    4253             : 
    4254        3202 :                 tmp1 = st->hTcxCfg->tcx_last_overlap_mode;
    4255        3202 :                 move16();
    4256        3202 :                 test();
    4257        3202 :                 test();
    4258        3202 :                 if ( ( w > 0 ) || ( ( w == 0 ) && ( EQ_16( tcx_last_overlap_mode, 2 ) ) ) )
    4259             :                 {
    4260        1942 :                     tmp1 = MIN_OVERLAP;
    4261        1942 :                     move16();
    4262             :                 }
    4263             : 
    4264        3202 :                 tmp2 = 0;
    4265        3202 :                 move16();
    4266        3202 :                 test();
    4267        3202 :                 if ( ( w == 0 ) && ( st->last_core == ACELP_CORE ) )
    4268             :                 {
    4269           0 :                     tmp2 = 1;
    4270           0 :                     move16();
    4271             :                 }
    4272             : 
    4273        3202 :                 tmp3 = st->last_core;
    4274        3202 :                 move16();
    4275        3202 :                 if ( w > 0 )
    4276             :                 {
    4277        1601 :                     tmp3 = 1;
    4278        1601 :                     move16();
    4279             :                 }
    4280             : 
    4281        3202 :                 tmp4 = 0;
    4282        3202 :                 move16();
    4283        3202 :                 if ( tcx_offset < 0 )
    4284             :                 {
    4285           0 :                     tmp4 = negate( tcx_offset );
    4286             :                 }
    4287             : 
    4288        3202 :                 tcx_windowing_synthesis_current_frame( win,
    4289        3202 :                                                        st->hTcxCfg->tcx_aldo_window_2,
    4290        3202 :                                                        st->hTcxCfg->tcx_mdct_window_half,
    4291        3202 :                                                        st->hTcxCfg->tcx_mdct_window_minimum,
    4292             :                                                        L_ola,
    4293        3202 :                                                        st->hTcxCfg->tcx_mdct_window_half_length,
    4294        3202 :                                                        st->hTcxCfg->tcx_mdct_window_min_length,
    4295             :                                                        tmp2,
    4296             :                                                        tmp1,
    4297             :                                                        hTcxEnc->acelp_zir,
    4298        3202 :                                                        hTcxEnc->Txnq,
    4299             :                                                        NULL,
    4300             :                                                        Aq_old_fx,
    4301        3202 :                                                        st->hTcxCfg->tcx_mdct_window_trans,
    4302             :                                                        L_win,
    4303             :                                                        tmp4,
    4304             :                                                        tmp3,
    4305             :                                                        0,
    4306             :                                                        0 );
    4307             : 
    4308        3202 :                 tmp1 = add( tcx_offset, imult1616( w, L_win ) );
    4309        3202 :                 move16();
    4310        3202 :                 tmpP16 = xn_buf16 + sub( tmp1, shr( L_ola, 1 ) );
    4311             : 
    4312        3202 :                 IF( w > 0 )
    4313             :                 {
    4314        1601 :                     tcx_windowing_synthesis_past_frame( tmpP16,
    4315        1601 :                                                         st->hTcxCfg->tcx_aldo_window_1_trunc,
    4316        1601 :                                                         st->hTcxCfg->tcx_mdct_window_half,
    4317        1601 :                                                         st->hTcxCfg->tcx_mdct_window_minimum,
    4318             :                                                         L_ola,
    4319        1601 :                                                         st->hTcxCfg->tcx_mdct_window_half_length,
    4320        1601 :                                                         st->hTcxCfg->tcx_mdct_window_min_length,
    4321             :                                                         2 );
    4322             :                 }
    4323             :                 /* add part of current sub-window overlapping with previous window */
    4324      263522 :                 FOR( i = 0; i < L_ola; i++ )
    4325             :                 {
    4326      260320 :                     tmpP16[i] = add_sat( tmpP16[i], win[i] );
    4327      260320 :                     move16();
    4328             :                 }
    4329             :                 /* copy new sub-window region not overlapping with previous window */
    4330        3202 :                 Copy( win + L_ola, xn_buf16 + add( tmp1, shr( L_ola, 1 ) ), L_win );
    4331             :             }
    4332             :             /* To assure that no garbage values are copied to hLPDmem->Txnq */
    4333        1601 :             set16_fx( xn_buf16 + add( add( L_frame, tcx_offset ), shr( L_ola, 1 ) ),
    4334        1601 :                       0, sub( sub( overlap, tcx_offset ), shr( L_ola, 1 ) ) );
    4335             :         }
    4336        2517 :         ELSE IF( s_and( frame_cnt == 0, ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) )
    4337             :         {
    4338             :             /* special overlap attempt, two transforms, grouping into one window */
    4339             :             Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    4340             :             Word16 L_win, L_spec_TCX5, L_ola, w;
    4341             : 
    4342         596 :             L_win = shr( L_frame, 1 );
    4343         596 :             L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
    4344         596 :             L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
    4345         596 :             move16();
    4346             : 
    4347         596 :             set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    4348             : 
    4349             :             /* Resize overlap (affect only asymmetric window)*/
    4350         596 :             overlap = st->hTcxCfg->tcx_mdct_window_delay;
    4351             :             /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
    4352         596 :             TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4353         596 :                               win + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode );
    4354             : 
    4355             :             /* copy new sub-window region not overlapping with previous window */
    4356         596 :             Copy( win + L_win, xn_buf16 + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
    4357             : 
    4358             :             /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
    4359             : 
    4360         596 :             TCX_MDCT_Inverse( spectrum_fx + L_spec_TCX5, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4361         596 :                               win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
    4362             : 
    4363         596 :             tmp4 = 0;
    4364         596 :             move16();
    4365         596 :             if ( tcx_offset < 0 )
    4366             :             {
    4367           0 :                 tmp4 = negate( tcx_offset );
    4368             :             }
    4369         596 :             tcx_windowing_synthesis_current_frame( win,
    4370         596 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4371         596 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4372         596 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4373             :                                                    L_ola,
    4374         596 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4375         596 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4376             :                                                    0, /* left_rect */
    4377             :                                                    2, /* left_mode */
    4378             :                                                    hTcxEnc->acelp_zir,
    4379         596 :                                                    hTcxEnc->Txnq,
    4380             :                                                    NULL,
    4381             :                                                    Aq_old_fx,
    4382         596 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4383             :                                                    L_win,
    4384             :                                                    tmp4,
    4385             :                                                    1, /* not LPDmem->mode */
    4386             :                                                    0,
    4387             :                                                    0 );
    4388             : 
    4389             : 
    4390         596 :             tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) );
    4391             : 
    4392         596 :             tcx_windowing_synthesis_past_frame( tmpP16,
    4393         596 :                                                 st->hTcxCfg->tcx_aldo_window_1_trunc,
    4394         596 :                                                 st->hTcxCfg->tcx_mdct_window_half,
    4395         596 :                                                 st->hTcxCfg->tcx_mdct_window_minimum,
    4396             :                                                 L_ola,
    4397         596 :                                                 st->hTcxCfg->tcx_mdct_window_half_length,
    4398         596 :                                                 st->hTcxCfg->tcx_mdct_window_min_length,
    4399             :                                                 2 );
    4400             : 
    4401             :             /* add part of current sub-window overlapping with previous window */
    4402       24316 :             FOR( i = 0; i < L_ola; i++ )
    4403             :             {
    4404       23720 :                 tmpP16[i] = add_sat( tmpP16[i], win[i] );
    4405       23720 :                 move16();
    4406             :             }
    4407             : 
    4408             :             /* copy new sub-window region not overlapping with previous window */
    4409        1192 :             Copy( win + L_ola,
    4410         596 :                   xn_buf16 + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ),
    4411             :                   L_win );
    4412             : 
    4413             :             /* extra folding-out on left side of win, for perfect reconstruction */
    4414       83616 :             FOR( w = shr( overlap, 1 ); w < overlap; w++ )
    4415             :             {
    4416       83020 :                 xn_buf16[overlap - 1 - w] = negate( xn_buf16[w] );
    4417       83020 :                 move16();
    4418             :             }
    4419             : 
    4420         596 :             tmp4 = 0;
    4421         596 :             move16();
    4422         596 :             if ( tcx_offset < 0 )
    4423             :             {
    4424           0 :                 tmp4 = negate( tcx_offset );
    4425             :             }
    4426         596 :             tcx_windowing_synthesis_current_frame( xn_buf16,
    4427         596 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4428         596 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4429         596 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4430             :                                                    overlap,
    4431         596 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4432         596 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4433         596 :                                                    st->last_core == ACELP_CORE,
    4434             :                                                    0,
    4435             :                                                    hTcxEnc->acelp_zir,
    4436         596 :                                                    hTcxEnc->Txnq,
    4437             :                                                    NULL,
    4438             :                                                    Aq_old_fx,
    4439         596 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4440             :                                                    L_win,
    4441             :                                                    tmp4,
    4442         596 :                                                    st->last_core,
    4443             :                                                    0,
    4444             :                                                    0 );
    4445             :         }
    4446             :         ELSE /* default, i.e. maximum overlap, single transform, no grouping */
    4447             :         {
    4448             : 
    4449        1921 :             TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4450        1921 :                               xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    4451             : 
    4452        1921 :             tmp1 = tcx_last_overlap_mode;
    4453        1921 :             move16();
    4454        1921 :             test();
    4455        1921 :             test();
    4456        1921 :             if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) )
    4457             :             {
    4458         596 :                 tmp1 = 2;
    4459         596 :                 move16();
    4460             :             }
    4461             : 
    4462        1921 :             tmp4 = 0;
    4463        1921 :             move16();
    4464        1921 :             if ( tcx_offset < 0 )
    4465             :             {
    4466           0 :                 tmp4 = negate( tcx_offset );
    4467             :             }
    4468        3842 :             tcx_windowing_synthesis_current_frame( xn_buf16,
    4469        1921 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4470        1921 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4471        1921 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4472             :                                                    overlap, /*hTcxCfg->tcx_mdct_window_length*/
    4473        1921 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4474        1921 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4475        1921 :                                                    st->last_core == ACELP_CORE,
    4476             :                                                    tmp1,
    4477             :                                                    hTcxEnc->acelp_zir,
    4478        1921 :                                                    hTcxEnc->Txnq,
    4479             :                                                    NULL,
    4480             :                                                    Aq_old_fx,
    4481        1921 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4482        1921 :                                                    shr( st->L_frame, 2 ),
    4483             :                                                    tmp4,
    4484        1921 :                                                    st->last_core,
    4485             :                                                    0,
    4486             :                                                    0 );
    4487             : 
    4488             :         } /* tcx_last_overlap_mode > 0 */
    4489             :     }
    4490             :     ELSE /* frame is TCX-20 or not TCX-only */
    4491             :     {
    4492      234208 :         IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
    4493             :         {
    4494             :             Word32 tmp_buf[L_FRAME_PLUS];
    4495             :             Word16 Q;
    4496             : 
    4497             :             /* DCT */
    4498      226349 :             Q = sub( 31, *spectrum_e );
    4499      226349 :             edct_ivas_fx( spectrum_fx, tmp_buf, L_frame, &Q );
    4500             : 
    4501             :             /* scale by sqrt(L / NORM_MDCT_FACTOR) */
    4502      226349 :             tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
    4503      226349 :             tmp2 = 4;
    4504      226349 :             move16();
    4505      226349 :             tmp1 = Sqrt16( tmp1, &tmp2 );
    4506             : 
    4507   101757549 :             FOR( i = 0; i < L_frame; i++ )
    4508             :             {
    4509   101531200 :                 tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
    4510   101531200 :                 move32();
    4511             :             }
    4512      226349 :             Q = sub( Q, tmp2 );
    4513             : 
    4514             : 
    4515      226349 :             window_ola_fx( tmp_buf,
    4516             :                            xn_buf16,
    4517             :                            &Q,
    4518      226349 :                            hTcxEnc->old_out_fx,
    4519             :                            &hTcxEnc->Q_old_out,
    4520             :                            L_frame,
    4521      226349 :                            st->hTcxCfg->tcx_last_overlap_mode,
    4522      226349 :                            st->hTcxCfg->tcx_curr_overlap_mode,
    4523             :                            0,
    4524             :                            0,
    4525             :                            NULL );
    4526             : 
    4527             :             /* scale output */
    4528   101757549 :             FOR( i = 0; i < L_frame; i++ )
    4529             :             {
    4530             : #ifdef ISSUE_1772_replace_shr_o
    4531   101531200 :                 xn_buf16[i] = shr_sat( xn_buf16[i], Q );
    4532             : #else
    4533             :                 xn_buf16[i] = shr_o( xn_buf16[i], Q, &Overflow );
    4534             : #endif
    4535   101531200 :                 move16();
    4536             :             }
    4537             : 
    4538      226349 :             aldo = 1;
    4539      226349 :             move16();
    4540             :         }
    4541             :         ELSE
    4542             :         {
    4543             : 
    4544        7859 :             TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
    4545        7859 :                               xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
    4546             : 
    4547             :             /*-----------------------------------------------------------*
    4548             :              * Windowing, overlap and add                                *
    4549             :              *-----------------------------------------------------------*/
    4550             : 
    4551             :             /* Window current frame */
    4552        7859 :             tmp4 = 0;
    4553        7859 :             move16();
    4554        7859 :             if ( tcx_offset < 0 )
    4555             :             {
    4556        7859 :                 tmp4 = negate( tcx_offset );
    4557             :             }
    4558       15718 :             tcx_windowing_synthesis_current_frame( xn_buf16,
    4559        7859 :                                                    st->hTcxCfg->tcx_aldo_window_2,
    4560        7859 :                                                    st->hTcxCfg->tcx_mdct_window_half,
    4561        7859 :                                                    st->hTcxCfg->tcx_mdct_window_minimum,
    4562             :                                                    overlap, /*hTcxCfg->tcx_mdct_window_length*/
    4563        7859 :                                                    st->hTcxCfg->tcx_mdct_window_half_length,
    4564        7859 :                                                    st->hTcxCfg->tcx_mdct_window_min_length,
    4565        7859 :                                                    st->last_core == ACELP_CORE,
    4566        7859 :                                                    st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/
    4567             :                                                    hTcxEnc->acelp_zir,
    4568        7859 :                                                    hTcxEnc->Txnq,
    4569             :                                                    NULL,
    4570             :                                                    Aq_old_fx,
    4571        7859 :                                                    st->hTcxCfg->tcx_mdct_window_trans,
    4572        7859 :                                                    shr( st->L_frame, 1 ),
    4573             :                                                    tmp4,
    4574        7859 :                                                    st->last_core,
    4575             :                                                    0,
    4576             :                                                    0 );
    4577             :         }
    4578             :     } /* TCX-10 and TCX-only */
    4579             : 
    4580             :     /* Window and overlap-add past frame if past frame is TCX */
    4581      238326 :     test();
    4582      238326 :     test();
    4583      238326 :     test();
    4584      238326 :     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 ) ) ) )
    4585             :     {
    4586             : 
    4587        4118 :         IF( st->hTcxCfg->last_aldo != 0 )
    4588             :         {
    4589        1922 :             tmp2 = add( hTcxEnc->Q_old_out, TCX_IMDCT_HEADROOM );
    4590             : 
    4591        1922 :             tmp1 = sub( overlap, st->hTcxCfg->tcx_mdct_window_min_length );
    4592      461522 :             FOR( i = 0; i < tmp1; i++ )
    4593             :             {
    4594      459600 :                 xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
    4595      459600 :                 move16();
    4596             :             }
    4597             : 
    4598             :             /* fade truncated ALDO window */
    4599        1922 :             tmp1 = sub( overlap, shr( st->hTcxCfg->tcx_mdct_window_min_length, 1 ) );
    4600       40222 :             FOR( ; i < tmp1; i++ )
    4601             :             {
    4602       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 );
    4603       38300 :                 xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    4604       38300 :                 move16();
    4605             :             }
    4606       40222 :             FOR( ; i < overlap; i++ )
    4607             :             {
    4608       38300 :                 tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im );
    4609       38300 :                 xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
    4610       38300 :                 move16();
    4611             :             }
    4612             : 
    4613       78522 :             FOR( ; i < L_frame; i++ )
    4614             :             {
    4615       76600 :                 xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    4616       76600 :                 move16();
    4617             :             }
    4618             :         }
    4619             :         ELSE
    4620             :         {
    4621        2196 :             test();
    4622        2196 :             test();
    4623        2196 :             test();
    4624        2196 :             if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( st->last_core != ACELP_CORE ) )
    4625             :             {
    4626         596 :                 tcx_last_overlap_mode = 2; /* use minimum overlap between the two TCX-10 windows */
    4627         596 :                 move16();
    4628             :             }
    4629             : 
    4630        2196 :             tmp1 = tcx_last_overlap_mode;
    4631        2196 :             move16();
    4632        2196 :             test();
    4633        2196 :             if ( ( tcx_last_overlap_mode == 0 ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
    4634             :             {
    4635        1056 :                 tmp1 = st->hTcxCfg->tcx_last_overlap_mode;
    4636        1056 :                 move16();
    4637             :             }
    4638             : 
    4639        2196 :             tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half,
    4640        2196 :                                                 st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, tmp1 );
    4641             : 
    4642             :             BASOP_SATURATE_WARNING_OFF_EVS;
    4643      615116 :             FOR( i = 0; i < overlap; i++ )
    4644             :             {
    4645      612920 :                 xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM );
    4646      612920 :                 move16();
    4647             :             }
    4648             : 
    4649        2196 :             IF( LT_16( i, L_frame ) )
    4650             :             {
    4651       89756 :                 FOR( ; i < L_frame; i++ )
    4652             :                 {
    4653       87560 :                     xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
    4654       87560 :                     move16();
    4655             :                 }
    4656             :             }
    4657             :             BASOP_SATURATE_WARNING_ON_EVS;
    4658             :         }
    4659             :     }
    4660             :     ELSE
    4661             :     {
    4662      234208 :         IF( aldo == 0 )
    4663             :         {
    4664             :             BASOP_SATURATE_WARNING_OFF_EVS;
    4665     2970179 :             FOR( i = 0; i < L_frame; i++ )
    4666             :             {
    4667     2962320 :                 xn_buf16[i] = shl_o( xn_buf16[i], TCX_IMDCT_HEADROOM, &Overflow );
    4668     2962320 :                 move16();
    4669             :             }
    4670             :             BASOP_SATURATE_WARNING_ON_EVS;
    4671             :         }
    4672             :     }
    4673             : 
    4674      238326 :     test();
    4675      238326 :     test();
    4676      238326 :     test();
    4677      238326 :     IF( ( aldo == 0 ) &&
    4678             :         ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
    4679             :           NE_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) )
    4680             :     {
    4681             :         /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
    4682     1045800 :         FOR( i = 0; i < nz; i++ )
    4683             :         {
    4684     1035882 :             hTcxEnc->old_out_fx[i] = shr( xn_buf16[L_frame - nz + i], TCX_IMDCT_HEADROOM );
    4685     1035882 :             move16();
    4686             :         }
    4687        9918 :         Copy( xn_buf16 + L_frame, hTcxEnc->old_out_fx + nz, overlap );
    4688        9918 :         set16_fx( hTcxEnc->old_out_fx + nz + overlap, 0, nz );
    4689             : 
    4690        9918 :         tcx_windowing_synthesis_past_frame( hTcxEnc->old_out_fx + nz,
    4691        9918 :                                             st->hTcxCfg->tcx_aldo_window_1_trunc,
    4692        9918 :                                             st->hTcxCfg->tcx_mdct_window_half,
    4693        9918 :                                             st->hTcxCfg->tcx_mdct_window_minimum,
    4694             :                                             overlap,
    4695        9918 :                                             st->hTcxCfg->tcx_mdct_window_half_length,
    4696        9918 :                                             st->hTcxCfg->tcx_mdct_window_min_length,
    4697        9918 :                                             st->hTcxCfg->tcx_curr_overlap_mode );
    4698             : 
    4699             :         /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
    4700        9918 :         IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP )
    4701             :         {
    4702      855824 :             FOR( i = 0; i < nz; i++ )
    4703             :             {
    4704      846990 :                 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 );
    4705      846990 :                 move16();
    4706             :             }
    4707             :         }
    4708             : 
    4709        9918 :         hTcxEnc->Q_old_out = -TCX_IMDCT_HEADROOM;
    4710        9918 :         move16();
    4711             :     }
    4712      238326 :     st->hTcxCfg->last_aldo = aldo;
    4713      238326 :     move16();
    4714             : 
    4715             :     /* Update Txnq */
    4716      238326 :     IF( st->hTcxCfg->last_aldo == 0 )
    4717             :     {
    4718       11977 :         Copy( xn_buf16 + L_frame, hTcxEnc->Txnq, overlap );
    4719             :     }
    4720             : 
    4721      238326 :     tmp1 = L_frame;
    4722      238326 :     move16();
    4723      238326 :     if ( EQ_16( st->core, TCX_20_CORE ) )
    4724             :     {
    4725      234208 :         tmp1 = st->L_frame;
    4726      234208 :         move16();
    4727             :     }
    4728             : 
    4729             :     /* Output */
    4730      238326 :     Copy( xn_buf16 + shr( overlap, 1 ) - tcx_offset, synth, tmp1 );
    4731             : 
    4732      238326 :     return;
    4733             : }
    4734             : 
    4735             : 
    4736      686982 : void TNSAnalysisStereo_fx(
    4737             :     Encoder_State **sts,                            /* i  : encoder state handle                    */
    4738             :     Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o  : MDST spectrum                       Qx*/
    4739             :     const Word16 bWhitenedDomain,                   /* i  : whitened domain flag                    Q0*/
    4740             :     Word16 tnsSize[CPE_CHANNELS][NB_DIV],           /* i  : number of tns parameters put into prm   Q0*/
    4741             :     Word16 tnsBits[CPE_CHANNELS][NB_DIV],           /* i  : number of tns bits in the frame         Q0*/
    4742             :     Word16 param_core[][NB_DIV * NPRM_DIV],         /* o  : TNS parameters                          Q0*/
    4743             :     const Word16 mct_on                             /* i  : flag mct block (1) or stereo (0)        Q0*/
    4744             : )
    4745             : {
    4746             :     Word16 ch, k, L_spec, L_frame, nSubframes, iFilter;
    4747             :     Word32 *spectrum_fx, sum;
    4748      686982 :     Encoder_State *st = NULL;
    4749      686982 :     TCX_ENC_HANDLE hTcxEnc = NULL;
    4750             :     Word16 individual_decision[NB_DIV];
    4751      686982 :     Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx;
    4752      686982 :     move32();
    4753      686982 :     Word16 maxPredictionGain_e = 0, meanPredictionGain_e;
    4754      686982 :     move16();
    4755      686982 :     Word16 sum_e = 0;
    4756      686982 :     move16();
    4757      686982 :     individual_decision[0] = 0;
    4758      686982 :     move16();
    4759      686982 :     individual_decision[1] = 0;
    4760      686982 :     move16();
    4761      686982 :     L_spec = -1;
    4762      686982 :     move16();
    4763      686982 :     L_frame = -1;
    4764      686982 :     move16();
    4765             : 
    4766             :     /* TNS filter analysis, loop over channels */
    4767     2060946 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    4768             :     {
    4769     1373964 :         st = sts[ch];
    4770     1373964 :         IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    4771             :         {
    4772      139018 :             CONTINUE;
    4773             :         }
    4774             : 
    4775     1234946 :         hTcxEnc = st->hTcxEnc;
    4776             : 
    4777     1234946 :         IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) )
    4778             :         {
    4779     1207456 :             nSubframes = 1;
    4780             :         }
    4781             :         ELSE
    4782             :         {
    4783       27490 :             nSubframes = NB_DIV;
    4784             :         }
    4785     1234946 :         move16();
    4786             : 
    4787     2497382 :         FOR( k = 0; k < nSubframes; k++ )
    4788             :         {
    4789             :             /* reset tns on whitened domain flag */
    4790     1262436 :             IF( !bWhitenedDomain )
    4791             :             {
    4792      638088 :                 hTcxEnc->bTnsOnWhithenedSpectra[k] = 0;
    4793      638088 :                 move16();
    4794      638088 :                 hTcxEnc->fUseTns[k] = 0;
    4795      638088 :                 move16();
    4796             :             }
    4797     1262436 :             test();
    4798     1262436 :             test();
    4799     1262436 :             IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    4800             :             {
    4801     1241660 :                 spectrum_fx = hTcxEnc->spectrum_fx[k];
    4802             : 
    4803     1241660 :                 L_frame = hTcxEnc->L_frameTCX;
    4804     1241660 :                 move16();
    4805     1241660 :                 st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
    4806     1241660 :                 L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
    4807     1241660 :                 move16();
    4808             :                 /*-----------------------------------------------------------*
    4809             :                  * Temporal Noise Shaping analysis                           *
    4810             :                  *-----------------------------------------------------------*/
    4811             : 
    4812     1241660 :                 IF( EQ_16( hTcxEnc->transform_type[k], TCX_5 ) )
    4813             :                 {
    4814             :                     /* rearrange LF sub-window lines prior to TNS analysis & filtering */
    4815       14218 :                     tcx5TnsGrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), spectrum_fx );
    4816             :                 }
    4817             : 
    4818             :                 /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */
    4819             : 
    4820     1241660 :                 ResetTnsData( &hTcxEnc->tnsData[k] );
    4821     1241660 :                 IF( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 )
    4822             :                 {
    4823           0 :                     BREAK;
    4824             :                 }
    4825             : 
    4826     1241660 :                 CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] );
    4827             :             }
    4828             :         }
    4829             :     }
    4830             : 
    4831      686982 :     IF( !mct_on )
    4832             :     {
    4833             :         /* TNS decision */
    4834             :         /* if framing differs between channels, keep the filter decision per channel */
    4835      164646 :         test();
    4836      164646 :         test();
    4837      164646 :         IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) &&
    4838             :               NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) ||
    4839             :             NE_16( sts[0]->hTcxCfg->fIsTNSAllowed, sts[1]->hTcxCfg->fIsTNSAllowed ) )
    4840             :         {
    4841        1196 :             individual_decision[0] = individual_decision[1] = 1;
    4842        1196 :             move16();
    4843        1196 :             move16();
    4844             :         }
    4845      163450 :         ELSE IF( bWhitenedDomain )
    4846             :         {
    4847       81725 :             IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) )
    4848             :             {
    4849       79981 :                 nSubframes = 1;
    4850             :             }
    4851             :             ELSE
    4852             :             {
    4853        1744 :                 nSubframes = NB_DIV;
    4854             :             }
    4855       81725 :             move16();
    4856      165194 :             FOR( k = 0; k < nSubframes; k++ )
    4857             :             {
    4858       83469 :                 IF( NE_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    4859             :                 {
    4860         424 :                     individual_decision[k] = 1;
    4861         424 :                     move16();
    4862             :                 }
    4863             :             }
    4864             :         }
    4865             : 
    4866             :         /* framing equal, check for similar filters, if very similar (also indicator for and M signal),
    4867             :          * use at least the same decision, maybe use the same filter
    4868             :          */
    4869             :         {
    4870             :             Word8 isTCX10;
    4871             : 
    4872      164646 :             IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) )
    4873             :             {
    4874      160590 :                 nSubframes = 1;
    4875      160590 :                 isTCX10 = 0;
    4876             :             }
    4877             :             ELSE
    4878             :             {
    4879        4056 :                 nSubframes = NB_DIV;
    4880        4056 :                 isTCX10 = 1;
    4881             :             }
    4882      164646 :             move16();
    4883      164646 :             move16();
    4884      333348 :             FOR( k = 0; k < nSubframes; k++ )
    4885             :             {
    4886      168702 :                 test();
    4887      168702 :                 test();
    4888      168702 :                 test();
    4889      168702 :                 IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    4890             :                 {
    4891      164221 :                     Word32 maxPredGain_fx = -ONE_IN_Q31;
    4892      164221 :                     move32();
    4893      164221 :                     Word16 maxPredGain_e = 0;
    4894      164221 :                     move16();
    4895      164221 :                     sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )];
    4896      164221 :                     sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )];
    4897             : 
    4898      472102 :                     FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    4899             :                     {
    4900             :                         STnsFilter *pFilter[2];
    4901             :                         struct TnsParameters const *pTnsParameters[2];
    4902      307881 :                         pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter;
    4903      307881 :                         pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
    4904      307881 :                         pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter;
    4905      307881 :                         pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
    4906             : 
    4907             :                         /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of
    4908             :                          * both filters for the decision
    4909             :                          */
    4910             : 
    4911      307881 :                         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
    4912             : 
    4913             :                         /* maxPredictionGain = max( maxPredictionGain, meanPredictionGain );*/
    4914      307881 :                         IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, meanPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */
    4915             :                         {
    4916      203736 :                             maxPredictionGain_fx = meanPredictionGain_fx;
    4917      203736 :                             maxPredictionGain_e = meanPredictionGain_e;
    4918      203736 :                             move32();
    4919      203736 :                             move16();
    4920             :                         }
    4921             : 
    4922      307881 :                         test();
    4923      307881 :                         test();
    4924      307881 :                         test();
    4925      307881 :                         IF( GT_32( pFilter[0]->predictionGain32, L_shl_sat( ( pTnsParameters[0]->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter[0]->predictionGain_e ) ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) &&
    4926             :                             GT_32( pFilter[1]->predictionGain32, L_shl_sat( ( pTnsParameters[1]->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter[1]->predictionGain_e ) ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) )
    4927             :                         {
    4928        4867 :                             pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */
    4929        4867 :                             move32();
    4930        4867 :                             move32();
    4931        4867 :                             pFilter[0]->predictionGain_e = pFilter[1]->predictionGain_e = meanPredictionGain_e; /* more TNS filter sync at 48kbps */
    4932        4867 :                             move16();
    4933        4867 :                             move16();
    4934        4867 :                             pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */
    4935        4867 :                             move16();
    4936             :                         }
    4937      307881 :                         sum_e = s_max( pFilter[0]->predictionGain_e, pFilter[1]->predictionGain_e );
    4938      307881 :                         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
    4939             : 
    4940      307881 :                         IF( LT_32( L_shl_sat( sum, sub( sum_e, meanPredictionGain_e ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) &&
    4941             :                             ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) )
    4942      204582 :                         {
    4943             : 
    4944      204582 :                             Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15
    4945      204582 :                             Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) );
    4946             : 
    4947             :                             /* maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); */
    4948      204582 :                             IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, maxPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */
    4949             :                             {
    4950      153571 :                                 maxPredGain_fx = meanPredictionGain_fx;
    4951      153571 :                                 maxPredGain_e = meanPredictionGain_e;
    4952      153571 :                                 move32();
    4953      153571 :                                 move16();
    4954             :                             }
    4955             : 
    4956      204582 :                             test();
    4957      204582 :                             test();
    4958      204582 :                             IF( GT_32( meanPredictionGain_fx, L_shl_sat( ( pTnsParameters[0]->minPredictionGain_32 ), sub( PRED_GAIN_E, meanPredictionGain_e ) ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) )
    4959             :                             {
    4960        7132 :                                 test();
    4961        7132 :                                 test();
    4962        7132 :                                 test();
    4963        7132 :                                 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*/ ) )
    4964             :                                 {
    4965             : 
    4966        6470 :                                     sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
    4967        6470 :                                     move16();
    4968             :                                     /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    4969             :                                     this may result in crash later. Changing the filter type here so the order is taken here in further section */
    4970        6470 :                                     IF( pFilter[0]->order != 0 )
    4971             :                                     {
    4972        6470 :                                         pFilter[0]->filterType = TNS_FILTER_ON;
    4973        6470 :                                         move16();
    4974             :                                     }
    4975             :                                     ELSE
    4976             :                                     {
    4977           0 :                                         pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
    4978           0 :                                         move16();
    4979             :                                     }
    4980        6470 :                                     sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
    4981        6470 :                                     move16();
    4982        6470 :                                     IF( pFilter[1]->order != 0 )
    4983             :                                     {
    4984        6470 :                                         pFilter[1]->filterType = TNS_FILTER_ON;
    4985        6470 :                                         move16();
    4986             :                                     }
    4987             :                                     ELSE
    4988             :                                     {
    4989           0 :                                         pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
    4990           0 :                                         move16();
    4991             :                                     }
    4992             :                                 }
    4993             :                                 ELSE
    4994             :                                 {
    4995             :                                     Word16 maxEnergyChange_fx;
    4996         662 :                                     maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 );
    4997             : 
    4998         662 :                                     IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) )
    4999             :                                     {
    5000         652 :                                         sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
    5001         652 :                                         move16();
    5002             :                                         /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    5003             :                                         this may result in crash later. Changing the filter type here so the order is taken here in further section */
    5004         652 :                                         IF( pFilter[0]->order != 0 )
    5005             :                                         {
    5006         652 :                                             pFilter[0]->filterType = TNS_FILTER_ON;
    5007         652 :                                             move16();
    5008             :                                         }
    5009             :                                         ELSE
    5010             :                                         {
    5011           0 :                                             pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
    5012           0 :                                             move16();
    5013             :                                         }
    5014         652 :                                         sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
    5015         652 :                                         move16();
    5016         652 :                                         IF( pFilter[1]->order != 0 )
    5017             :                                         {
    5018         652 :                                             pFilter[1]->filterType = TNS_FILTER_ON;
    5019         652 :                                             move16();
    5020             :                                         }
    5021             :                                         ELSE
    5022             :                                         {
    5023           0 :                                             pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
    5024           0 :                                             move16();
    5025             :                                         }
    5026             :                                     }
    5027             :                                     ELSE
    5028             :                                     {
    5029          10 :                                         pFilter[0]->filterType = TNS_FILTER_OFF;
    5030          10 :                                         move16();
    5031          10 :                                         pFilter[1]->filterType = TNS_FILTER_OFF;
    5032          10 :                                         move16();
    5033             :                                     }
    5034             :                                 }
    5035             :                             }
    5036      197450 :                             ELSE IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
    5037             :                             {
    5038         222 :                                 pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
    5039         222 :                                 pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
    5040         222 :                                 move16();
    5041         222 :                                 move16();
    5042         222 :                                 sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
    5043         222 :                                 move16();
    5044         222 :                                 sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
    5045         222 :                                 move16();
    5046             :                             }
    5047      197228 :                             ELSE IF( NE_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) /* sanity check */
    5048             :                             {
    5049           0 :                                 assert( 0 );
    5050             :                             }
    5051             :                             ELSE
    5052             :                             {
    5053      197228 :                                 pFilter[0]->filterType = TNS_FILTER_OFF;
    5054      197228 :                                 move16();
    5055      197228 :                                 pFilter[1]->filterType = TNS_FILTER_OFF;
    5056      197228 :                                 move16();
    5057             :                             }
    5058             : 
    5059      204582 :                             test();
    5060      204582 :                             test();
    5061      204582 :                             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 ) )
    5062             :                             {
    5063        6010 :                                 Word16 tmpIntValue = 0;
    5064        6010 :                                 move16();
    5065             :                                 Word16 tmpCoeff[TNS_MAX_FILTER_ORDER];
    5066        6010 :                                 Word16 i, maxOrder = s_max( pFilter[0]->order, pFilter[1]->order );
    5067             : 
    5068        6010 :                                 set16_fx( tmpCoeff, 0, TNS_MAX_FILTER_ORDER );
    5069       45723 :                                 FOR( i = 0; i < maxOrder; i++ )
    5070             :                                 {
    5071       39713 :                                     tmpIntValue = s_max( tmpIntValue, abs_s( sub( pFilter[0]->coefIndex[i], pFilter[1]->coefIndex[i] ) ) );
    5072             :                                 }
    5073             : 
    5074        6010 :                                 IF( EQ_16( tmpIntValue, 1 ) ) /* the TNS coefficients are sufficiently similar to equalize the two filters */
    5075             :                                 {
    5076       27609 :                                     FOR( i = maxOrder - 1; i >= 0; i-- )
    5077             :                                     {
    5078       24004 :                                         IF( LT_16( abs_s( pFilter[0]->coefIndex[i] ), abs_s( pFilter[1]->coefIndex[i] ) ) )
    5079             :                                         {
    5080        4390 :                                             tmpCoeff[i] = pFilter[0]->coefIndex[i];
    5081             :                                         }
    5082             :                                         ELSE
    5083             :                                         {
    5084       19614 :                                             tmpCoeff[i] = pFilter[1]->coefIndex[i];
    5085             :                                         }
    5086       24004 :                                         move16();
    5087       24004 :                                         IF( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) )
    5088             :                                         {
    5089        5866 :                                             maxOrder = sub( maxOrder, 1 );
    5090             :                                         }
    5091             :                                         ELSE
    5092             :                                         {
    5093       18138 :                                             tmpIntValue = 0;
    5094       18138 :                                             move16();
    5095             :                                         }
    5096             :                                     }
    5097             :                                     /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */
    5098        3605 :                                     IF( maxOrder > 0 )
    5099             :                                     {
    5100       32445 :                                         FOR( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- )
    5101             :                                         {
    5102       28840 :                                             pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i];
    5103       28840 :                                             move16();
    5104       28840 :                                             move16();
    5105             :                                         }
    5106             : 
    5107        3605 :                                         pFilter[0]->order = pFilter[1]->order = maxOrder;
    5108        3605 :                                         move16();
    5109        3605 :                                         move16();
    5110             :                                     }
    5111             :                                 }
    5112             :                             }
    5113             :                         }
    5114             :                         ELSE
    5115             :                         {
    5116      103299 :                             individual_decision[k] = 1;
    5117      103299 :                             move16();
    5118             :                         }
    5119             :                     }
    5120             : 
    5121      164221 :                     IF( individual_decision[k] == 0 )
    5122             :                     {
    5123       81500 :                         IF( ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) )
    5124             :                         {
    5125        3446 :                             sts[0]->hTcxEnc->fUseTns[k] = 1;
    5126             :                         }
    5127             :                         ELSE
    5128             :                         {
    5129       78054 :                             sts[0]->hTcxEnc->fUseTns[k] = 0;
    5130             :                         }
    5131       81500 :                         move16();
    5132             : 
    5133       81500 :                         IF( ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) )
    5134             :                         {
    5135        3446 :                             sts[1]->hTcxEnc->fUseTns[k] = 1;
    5136             :                         }
    5137             :                         ELSE
    5138             :                         {
    5139       78054 :                             sts[1]->hTcxEnc->fUseTns[k] = 0;
    5140             :                         }
    5141       81500 :                         move16();
    5142             :                     }
    5143             :                     ELSE
    5144             :                     {
    5145       82721 :                         sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
    5146       82721 :                         move16();
    5147       82721 :                         sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
    5148       82721 :                         move16();
    5149       82721 :                         sts[0]->hTcxEnc->fUseTns[k] = 0;
    5150       82721 :                         move16();
    5151       82721 :                         sts[1]->hTcxEnc->fUseTns[k] = 0;
    5152       82721 :                         move16();
    5153      241045 :                         FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5154             :                         {
    5155      158324 :                             sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
    5156      158324 :                             move16();
    5157      158324 :                             sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
    5158      158324 :                             move16();
    5159             :                         }
    5160             :                     }
    5161             : 
    5162      164221 :                     test();
    5163      164221 :                     test();
    5164      164221 :                     test();
    5165      164221 :                     IF( !bWhitenedDomain && individual_decision[k] == 0 &&
    5166             :                         LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) &&
    5167             :                         NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) )
    5168             :                     {
    5169       40120 :                         sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
    5170       40120 :                         move16();
    5171       40120 :                         sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
    5172       40120 :                         move16();
    5173       40120 :                         sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
    5174       40120 :                         move16();
    5175       40120 :                         sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
    5176       40120 :                         move16();
    5177       40120 :                         sts[0]->hTcxEnc->fUseTns[k] = 0;
    5178       40120 :                         move16();
    5179       40120 :                         sts[1]->hTcxEnc->fUseTns[k] = 0;
    5180       40120 :                         move16();
    5181      113745 :                         FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5182             :                         {
    5183       73625 :                             ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter );
    5184       73625 :                             ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter );
    5185             :                         }
    5186             :                     }
    5187             : 
    5188             :                     /* maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); */
    5189      164221 :                     IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* exp: maxPredGain_e */
    5190             :                     {
    5191           0 :                         maxPredictionGain_fx = maxPredGain_fx;
    5192           0 :                         maxPredictionGain_e = maxPredGain_e;
    5193           0 :                         move32();
    5194           0 :                         move16();
    5195             :                     }
    5196             :                 }
    5197             :             }
    5198             :         }
    5199             :     }
    5200             : 
    5201             :     /* individual decision for each channel */
    5202     2060946 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5203             :     {
    5204     1373964 :         IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    5205             :         {
    5206      139018 :             CONTINUE;
    5207             :         }
    5208             : 
    5209             :         Word8 isTCX10;
    5210             : 
    5211     1234946 :         IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
    5212             :         {
    5213     1207456 :             nSubframes = 1;
    5214     1207456 :             isTCX10 = 0;
    5215             :         }
    5216             :         ELSE
    5217             :         {
    5218       27490 :             nSubframes = NB_DIV;
    5219       27490 :             isTCX10 = 1;
    5220             :         }
    5221     1234946 :         move16();
    5222     1234946 :         move16();
    5223             : 
    5224     2497382 :         FOR( k = 0; k < nSubframes; k++ )
    5225             :         {
    5226     1262436 :             test();
    5227     1262436 :             test();
    5228     1262436 :             test();
    5229     1262436 :             test();
    5230     1262436 :             IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) &&
    5231             :                 ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    5232             :             {
    5233     1078660 :                 Word32 maxPredGain_fx = -ONE_IN_Q31; // Q31
    5234     1078660 :                 move32();
    5235     1078660 :                 Word16 maxPredGain_e = 0;
    5236     1078660 :                 move16();
    5237     1078660 :                 sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
    5238             : 
    5239     3153942 :                 FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5240             :                 {
    5241             :                     STnsFilter *pFilter;
    5242             :                     struct TnsParameters const *pTnsParameters;
    5243     2075282 :                     pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
    5244     2075282 :                     pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
    5245             : 
    5246             :                     // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 );
    5247     2075282 :                     IF( GT_32( pFilter->predictionGain32, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, pFilter->predictionGain_e ) ) ) ) /* pFilter->predictionGain_e */
    5248             :                     {
    5249     1412828 :                         maxPredGain_fx = pFilter->predictionGain32;
    5250     1412828 :                         maxPredGain_e = pFilter->predictionGain_e;
    5251     1412828 :                         move32();
    5252     1412828 :                         move16();
    5253             :                     }
    5254             : 
    5255     2075282 :                     test();
    5256     2075282 :                     IF( GT_32( pFilter->predictionGain32, L_shl_sat( ( pTnsParameters->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter->predictionGain_e ) ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) )
    5257             :                     {
    5258      128297 :                         test();
    5259      128297 :                         test();
    5260      128297 :                         IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( sts[ch]->hTcxEnc->tcxltp_gain, 19660 /*.6f in Q15*/ ) )
    5261             :                         {
    5262      110288 :                             sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
    5263      110288 :                             move16();
    5264             :                             /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    5265             :                             this may result in crash later. Changing the filter type here so the order is taken here in further section */
    5266      110288 :                             IF( pFilter->order != 0 )
    5267             :                             {
    5268      110288 :                                 pFilter->filterType = TNS_FILTER_ON;
    5269      110288 :                                 move16();
    5270             :                             }
    5271             :                             ELSE
    5272             :                             {
    5273           0 :                                 pFilter->filterType = TNS_FILTER_ON_ZERO;
    5274           0 :                                 move16();
    5275             :                             }
    5276             :                         }
    5277             :                         ELSE
    5278             :                         {
    5279       18009 :                             Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 );
    5280             : 
    5281       18009 :                             IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) )
    5282             :                             {
    5283       16999 :                                 sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
    5284       16999 :                                 move16();
    5285             :                                 /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
    5286             :                                 this may result in crash later. Changing the filter type here so the order is taken here in further section */
    5287       16999 :                                 IF( pFilter->order != 0 )
    5288             :                                 {
    5289       16999 :                                     pFilter->filterType = TNS_FILTER_ON;
    5290       16999 :                                     move16();
    5291             :                                 }
    5292             :                                 ELSE
    5293             :                                 {
    5294           0 :                                     pFilter->filterType = TNS_FILTER_ON_ZERO;
    5295           0 :                                     move16();
    5296             :                                 }
    5297             :                             }
    5298             :                             ELSE
    5299             :                             {
    5300        1010 :                                 pFilter->filterType = TNS_FILTER_OFF;
    5301        1010 :                                 move16();
    5302             :                             }
    5303             :                         }
    5304             :                     }
    5305     1946985 :                     ELSE IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
    5306             :                     {
    5307       11942 :                         pFilter->filterType = TNS_FILTER_ON_ZERO;
    5308       11942 :                         move16();
    5309       11942 :                         sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
    5310       11942 :                         move16();
    5311             :                     }
    5312             :                     ELSE
    5313             :                     {
    5314     1935043 :                         pFilter->filterType = TNS_FILTER_OFF;
    5315     1935043 :                         move16();
    5316             :                     }
    5317             :                 }
    5318             : 
    5319     1078660 :                 sts[ch]->hTcxEnc->fUseTns[k] = 0;
    5320     1078660 :                 move16();
    5321     1078660 :                 if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 )
    5322             :                 {
    5323      117337 :                     sts[ch]->hTcxEnc->fUseTns[k] = 1;
    5324      117337 :                     move16();
    5325             :                 }
    5326             : 
    5327     1078660 :                 test();
    5328     1078660 :                 test();
    5329     1078660 :                 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 ) )
    5330             :                 {
    5331      537072 :                     sts[ch]->hTcxEnc->fUseTns[k] = 0;
    5332      537072 :                     move16();
    5333      537072 :                     sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
    5334      537072 :                     move16();
    5335      537072 :                     sts[ch]->hTcxEnc->tnsData[k].nFilters = 0;
    5336      537072 :                     move16();
    5337     1569351 :                     FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5338             :                     {
    5339     1032279 :                         ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
    5340     1032279 :                         sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
    5341     1032279 :                         move16();
    5342             :                     }
    5343             :                 }
    5344             : 
    5345             :                 // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx );
    5346     1078660 :                 IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* maxPredGain_e */
    5347             :                 {
    5348      778343 :                     maxPredictionGain_fx = maxPredGain_fx;
    5349      778343 :                     maxPredictionGain_e = maxPredGain_e;
    5350      778343 :                     move32();
    5351      778343 :                     move16();
    5352             :                 }
    5353             :             }
    5354             :         }
    5355             :     }
    5356             : 
    5357             : 
    5358             :     /* we have the decision, set filter data accordingly */
    5359     2060946 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5360             :     {
    5361     1373964 :         IF( EQ_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    5362             :         {
    5363      139018 :             CONTINUE;
    5364             :         }
    5365             : 
    5366     1234946 :         IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
    5367             :         {
    5368     1207456 :             nSubframes = 1;
    5369             :         }
    5370             :         ELSE
    5371             :         {
    5372       27490 :             nSubframes = NB_DIV;
    5373             :         }
    5374     1234946 :         move16();
    5375     2497382 :         FOR( k = 0; k < nSubframes; k++ )
    5376             :         {
    5377     1262436 :             test();
    5378     1262436 :             test();
    5379     1262436 :             IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    5380             :             {
    5381     1241660 :                 sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
    5382             : 
    5383     3616056 :                 FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5384             :                 {
    5385             :                     STnsFilter *pFilter;
    5386     2374396 :                     pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
    5387     2374396 :                     SWITCH( pFilter->filterType )
    5388             :                     {
    5389     2284555 :                         case TNS_FILTER_OFF:
    5390     2284555 :                             ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
    5391     2284555 :                             BREAK;
    5392        9082 :                         case TNS_FILTER_ON_ZERO:
    5393             :                             /* 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 */
    5394        9082 :                             ClearTnsFilterCoefficients( pFilter );
    5395        9082 :                             pFilter->order = 1;
    5396        9082 :                             move16();
    5397        9082 :                             BREAK;
    5398             :                     }
    5399     2374396 :                 }
    5400             :             }
    5401             :         }
    5402             :     }
    5403             : 
    5404             :     /* Apply filters, loop over channels */
    5405     2060946 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5406             :     {
    5407     1373964 :         st = sts[ch];
    5408     1373964 :         IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
    5409             :         {
    5410      139018 :             CONTINUE;
    5411             :         }
    5412             : 
    5413     1234946 :         IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
    5414             :         {
    5415     1207456 :             nSubframes = 1;
    5416             :         }
    5417             :         ELSE
    5418             :         {
    5419       27490 :             nSubframes = NB_DIV;
    5420             :         }
    5421     1234946 :         move16();
    5422             : 
    5423     2497382 :         FOR( k = 0; k < nSubframes; k++ )
    5424             :         {
    5425     1262436 :             test();
    5426     1262436 :             test();
    5427     1262436 :             test();
    5428     1262436 :             test();
    5429     1262436 :             test();
    5430     1262436 :             IF( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */
    5431             :                 sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] &&
    5432             :                 sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] )
    5433             :             {
    5434       18275 :                 Word16 equalFilterData = 0;
    5435       18275 :                 move16();
    5436       18275 :                 test();
    5437       18275 :                 test();
    5438       36535 :                 if ( EQ_16( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ) &&
    5439       34263 :                      EQ_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) &&
    5440       16003 :                      EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) )
    5441             :                 {
    5442       14662 :                     equalFilterData = 1;
    5443       14662 :                     move16();
    5444             :                 }
    5445             : 
    5446       18275 :                 IF( equalFilterData )
    5447             :                 {
    5448       30356 :                     FOR( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
    5449             :                     {
    5450       26126 :                         const Word16 *pDataCh0 = (const Word16 *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter];
    5451       26126 :                         const Word16 *pDataCh1 = (const Word16 *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter];
    5452       26126 :                         Word16 i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */
    5453             : 
    5454       26126 :                         move16();
    5455       26126 :                         test();
    5456      221639 :                         WHILE( ( i >= 0 ) && EQ_16( pDataCh0[i], pDataCh1[i] ) )
    5457             :                         {
    5458      195513 :                             test();
    5459      195513 :                             i = sub( i, 1 );
    5460             :                         }
    5461       26126 :                         IF( i >= 0 )
    5462             :                         {
    5463       10432 :                             equalFilterData = 0;
    5464       10432 :                             move16();
    5465       10432 :                             BREAK;
    5466             :                         }
    5467             :                     }
    5468       14662 :                     IF( equalFilterData )
    5469             :                     {
    5470        4230 :                         st->hTcxEnc->tnsData[k].nFilters = i_mult( st->hTcxEnc->tnsData[k].nFilters, -1 ); /* signals common TNS */
    5471        4230 :                         move16();
    5472             :                     }
    5473             :                 }
    5474             :             }
    5475     1262436 :             test();
    5476     1262436 :             test();
    5477     1262436 :             IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
    5478             :             {
    5479     1241660 :                 L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
    5480     1241660 :                 move16();
    5481     1241660 :                 spectrum_fx = st->hTcxEnc->spectrum_fx[k];
    5482             :                 /* If TNS should be used then get the residual after applying it inplace in the spectrum */
    5483     1241660 :                 IF( st->hTcxEnc->fUseTns[k] )
    5484             :                 {
    5485       69615 :                     st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
    5486             : 
    5487       69615 :                     ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum_fx, 1 );
    5488             :                 }
    5489             : 
    5490     1241660 :                 IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) )
    5491             :                 {
    5492       14218 :                     tcx5TnsUngrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), st->hTcxEnc->spectrum_fx[k], ENC );
    5493             :                 }
    5494             : 
    5495     1241660 :                 st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k];
    5496     1241660 :                 move16();
    5497     1241660 :                 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 );
    5498             :             }
    5499             : 
    5500     1262436 :             IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) )
    5501             :             {
    5502       28436 :                 tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[k] );
    5503       28436 :                 tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][k] );
    5504             :             }
    5505             :         }
    5506             :     }
    5507      686982 :     return;
    5508             : }

Generated by: LCOV version 1.14