LCOV - code coverage report
Current view: top level - lib_enc - mdct_classifier_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 523 530 98.7 %
Date: 2025-09-14 03:13:15 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h"
       7             : #include "cnst.h"
       8             : //#include "prot_fx.h"
       9             : #include "rom_com.h"
      10             : #include "prot_fx.h"      /* Function prototypes                    */
      11             : #include "prot_fx_enc.h"  /* Function prototypes                    */
      12             : #include "prot_fx_enc.h"  /* Function prototypes                   */
      13             : #include "ivas_prot_fx.h" /* Function prototypes                   */
      14             : 
      15             : /*--------------------------------------------------------------------------*
      16             :  * Local constants
      17             :  *--------------------------------------------------------------------------*/
      18             : 
      19             : #define MDCT_CLASSIFER_SMOOTH_FILT_COEFF 26214       /* 0.8 in Q15 */
      20             : #define MDCT_CLASSIFER_THRESH_UP         13107       /* 1.6 in Q13 */
      21             : #define MDCT_CLASSIFER_THRESH_DOWN       9011        /* 1.1 in Q13 */
      22             : #define MDCT_CLASSIFER_HQ_LOCAL          ( 3 << 13 ) /* Q13, Define those local to make the filtering operation robust in case classes numbers are changed */
      23             : #define MDCT_CLASSIFER_TCX_LOCAL         ( 1 << 13 ) /* Q13 */
      24             : // IVAS_CODE
      25             : #define GAIN2_START_WB 6
      26             : #define GAIN3_START_WB 12
      27             : #define GAIN4_START_WB 9
      28             : #define H1_START_WB    17
      29             : #define H2_START_WB    14
      30             : #define H_LENGTH_WB    3
      31             : 
      32             : #define GAIN2_START_SWB 8
      33             : #define GAIN3_START_SWB 16
      34             : 
      35             : #define GAIN2_START_SWB_RS 3
      36             : #define GAIN3_START_SWB_RS 4
      37             : 
      38             : #define GAIN4_START_SWB 12
      39             : #define H1_START_SWB    25
      40             : #define H2_START_SWB    20
      41             : #define H_LENGTH_SWB    5
      42             : 
      43             : /*-----------------------------------------------------------------------------
      44             :  * dft_mag_square_fx()
      45             :  *
      46             :  * Square magnitude of fft spectrum
      47             :  *----------------------------------------------------------------------------*/
      48       82075 : static void dft_mag_square_fx(
      49             :     const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1]  Qx*/
      50             :     Word32 magSq[],   /* o : Magnitude square spectrum */
      51             :     const Word16 n    /* i : Input vector length */
      52             : )
      53             : {
      54             :     Word16 i, l;
      55             :     const Word16 *pRe, *pIm;
      56             :     Word32 *pMagSq, acc;
      57             : 
      58             :     /* Magnitude square at 0. */
      59       82075 :     pMagSq = &magSq[0];
      60       82075 :     pRe = &x[0]; // Qx
      61       82075 :     *pMagSq++ = L_mult0( *pRe, *pRe );
      62       82075 :     pRe++;
      63       82075 :     move32();
      64             : 
      65             :     /* From 1 to (N/2 - 1). */
      66       82075 :     l = sub( shr( n, 1 ), 1 ); /* N/2 - 1. */
      67       82075 :     pIm = &x[n];
      68       82075 :     pIm--;
      69    10505600 :     FOR( i = 0; i < l; i++ )
      70             :     {
      71    10423525 :         acc = L_mult0( *pRe, *pRe );
      72    10423525 :         pRe++;
      73    10423525 :         *pMagSq++ = L_mac0( acc, *pIm, *pIm ); // 2*Qx
      74    10423525 :         pIm--;
      75    10423525 :         move32();
      76             :     }
      77             : 
      78             :     /* The magnitude square at N/2 */
      79       82075 :     *pMagSq = L_mult0( *pRe, *pRe ); // 2*Qx
      80       82075 :     move32();
      81       82075 :     return;
      82             : }
      83             : /*-------------------------------------------------------------------*
      84             :  * mdct_classifier()
      85             :  *
      86             :  * MDCT signal classifier for HQ_CORE/TCX_20_CORE
      87             :  *-------------------------------------------------------------------*/
      88             : 
      89         438 : Word16 mdct_classifier_fx(                         /* o: MDCT A/B decision                         */
      90             :                            const Word16 *fft_buff, /* i: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */
      91             :                            Encoder_State *st_fx,   /* i/o: Encoder state variable                  */
      92             :                            Word32 *cldfbBuf_Ener,  // enerBuffer_exp
      93             :                            Word16 enerBuffer_exp,
      94             :                            const Word32 brate /* i  : current brate, IVAS: nominal bitrate, EVS: st->total_brate */
      95             : )
      96             : {
      97             :     Word16 c;
      98             :     Word32 magSq[129], *pMagSq, nf, pe;
      99             :     Word16 k;
     100             :     Word16 np;
     101             :     Word32 max_cand;
     102             :     Word16 max_i;
     103             :     Word32 p_energy_man, n_energy_man, man;
     104             :     Word16 p_energy_exp, n_energy_exp, expo;
     105             :     Word16 d_acc;
     106             :     Word16 pos_last;
     107             :     Word16 clas_sec;
     108             :     Word16 clas_final;
     109             :     Word16 condition1, condition2;
     110             :     Word16 factor;
     111             :     Word32 acc;
     112             :     UWord16 lsb16;
     113             :     UWord32 lsb32;
     114             :     Word32 gain1, gain2, gain3, gain11, gain4;
     115             :     Word32 peak_l, peak_h, avrg_l, avrg_h, peak_H1, avrg_H1, peak_H2, avrg_H2;
     116             :     Word16 condition3, condition4;
     117         438 :     Word32 gain1_tmp = 0, gain2_tmp = 0;
     118             :     Word16 exp, exp1, exp2, exp3;
     119             :     Word32 L_tmp, L_tmp1;
     120         438 :     TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc;
     121             : #ifndef ISSUE_1867_replace_overflow_libenc
     122             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     123             :     Flag Overflow = 0;
     124             : #endif
     125             : #endif
     126         438 :     test();
     127             :     {
     128             : 
     129         438 :         dft_mag_square_fx( fft_buff, magSq, 256 );
     130             :     }
     131         438 :     nf = L_add( magSq[0], 0 );
     132         438 :     pe = L_add( magSq[0], 0 );
     133         438 :     np = 0;
     134         438 :     move16();
     135         438 :     max_cand = L_negate( 1 );
     136         438 :     max_i = 0;
     137         438 :     move16();
     138         438 :     p_energy_man = L_deposit_l( 0 );
     139         438 :     n_energy_man = L_deposit_l( 0 );
     140         438 :     p_energy_exp = n_energy_exp = 32;
     141         438 :     move16();
     142         438 :     move16();
     143         438 :     d_acc = 0;
     144         438 :     move16();
     145         438 :     pos_last = -1;
     146         438 :     move16();
     147             : 
     148         438 :     pMagSq = magSq;
     149       56502 :     FOR( k = 0; k < 128; k++ )
     150             :     {
     151             :         /* NB: a*f + b*(1 - f)      needs two multiplies
     152             :          *     = (a - b)*f + b      saves one multiply     */
     153       56064 :         IF( GT_32( *( ++pMagSq ), nf ) )
     154             :         {
     155       30136 :             factor = 31385;
     156       30136 :             move16(); /* 0.9578 in Q15 */
     157             :         }
     158             :         ELSE
     159             :         {
     160       25928 :             factor = 21207;
     161       25928 :             move16(); /* 0.6472 in Q15 */
     162             :         }
     163       56064 :         acc = L_sub( nf, *pMagSq );
     164       56064 :         Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
     165       56064 :         nf = L_add( acc, *pMagSq );
     166       56064 :         IF( GT_32( *pMagSq, pe ) )
     167             :         {
     168       10538 :             factor = 13840;
     169       10538 :             move16(); /* 0.42237 in Q15 */
     170             :         }
     171             :         ELSE
     172             :         {
     173       45526 :             factor = 26308;
     174       45526 :             move16(); /* 0.80285 in Q15 */
     175             :         }
     176       56064 :         acc = L_sub( pe, *pMagSq );
     177       56064 :         Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
     178       56064 :         pe = L_add( acc, *pMagSq );
     179       56064 :         Mpy_32_16_ss( pe, 20972, &acc, &lsb16 ); /* 0.64 in Q15 */
     180       56064 :         IF( GT_32( *pMagSq, acc ) )
     181             :         {
     182       16943 :             IF( GT_32( *pMagSq, max_cand ) )
     183             :             {
     184       13442 :                 max_cand = L_add( *pMagSq, 0 );
     185       13442 :                 max_i = add( 2, k );
     186             :             }
     187             :         }
     188             :         ELSE
     189             :         {
     190       39121 :             IF( max_i > 0 )
     191             :             {
     192        8345 :                 IF( ( np > 0 ) )
     193             :                 {
     194        7907 :                     d_acc = sub( add( d_acc, max_i ), pos_last );
     195             :                 }
     196        8345 :                 np = add( np, 1 );
     197        8345 :                 pos_last = max_i;
     198        8345 :                 move16();
     199             :             }
     200             : 
     201       39121 :             max_cand = L_negate( 1 );
     202       39121 :             max_i = 0;
     203       39121 :             move16();
     204             :         }
     205             : 
     206       56064 :         IF( pe != 0 )
     207             :         {
     208       56064 :             expo = norm_l( pe );
     209       56064 :             man = L_shl( pe, expo );                // expo
     210       56064 :             Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */
     211       56064 :             expo = shl( expo, 1 );                  /* Multiply by 2 due to squaring. */
     212       56064 :             floating_point_add( &p_energy_man, &p_energy_exp, man, expo );
     213             :         }
     214       56064 :         IF( nf != 0 )
     215             :         {
     216       56058 :             expo = norm_l( nf );
     217       56058 :             man = L_shl( nf, expo );
     218       56058 :             Mpy_32_32_ss( man, man, &man, &lsb32 ); /* nf square */
     219       56058 :             expo = shl( expo, 1 );                  /* Multiply by 2 due to squaring. */
     220       56058 :             floating_point_add( &n_energy_man, &n_energy_exp, man, expo );
     221             :         }
     222             :     }
     223             : 
     224         438 :     gain1 = L_deposit_l( 0 );
     225         438 :     gain2 = L_deposit_l( 0 );
     226         438 :     gain3 = L_deposit_l( 0 );
     227             : 
     228        3942 :     FOR( k = 0; k < 8; k++ )
     229             :     {
     230        3504 :         gain1 = L_add( gain1, L_shr( cldfbBuf_Ener[k], 3 ) );
     231        3504 :         gain2 = L_add( gain2, L_shr( cldfbBuf_Ener[k + 8], 3 ) );
     232        3504 :         gain3 = L_add( gain3, L_shr( cldfbBuf_Ener[k + 16], 3 ) );
     233             :     }
     234             : 
     235             :     /* gain11 = 8*(gain1 - cldfbBuf_Ener[0]/8)/7; */
     236         438 :     acc = L_shr( cldfbBuf_Ener[0], 3 );
     237         438 :     acc = L_sub( gain1, acc );
     238         438 :     acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ );
     239         438 :     gain11 = L_shl( acc, 3 );
     240         438 :     gain4 = L_deposit_l( 0 );
     241        5694 :     FOR( k = 0; k < 12; k++ )
     242             :     {
     243        5256 :         gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 /*(1/12).Q15*/ ) );
     244             :     }
     245             : 
     246             : 
     247         438 :     peak_H1 = L_add( cldfbBuf_Ener[25], 0 );
     248         438 :     Mpy_32_16_ss( cldfbBuf_Ener[25], 6554 /*0.4.Q15*/, &avrg_H1, &lsb16 );
     249        2190 :     FOR( k = 1; k < 5; k++ )
     250             :     {
     251        1752 :         IF( GT_32( cldfbBuf_Ener[k + 25], peak_H1 ) )
     252             :         {
     253         447 :             peak_H1 = L_add( cldfbBuf_Ener[k + 25], 0 );
     254             :         }
     255        1752 :         avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 /*0.4.Q15*/ ) );
     256             :     }
     257             : 
     258         438 :     peak_H2 = L_add( cldfbBuf_Ener[20], 0 );
     259         438 :     Mpy_32_16_ss( cldfbBuf_Ener[20], 6554 /*0.4.Q15*/, &avrg_H2, &lsb16 );
     260        2190 :     FOR( k = 1; k < 5; k++ )
     261             :     {
     262        1752 :         IF( GT_32( cldfbBuf_Ener[k + 20], peak_H2 ) )
     263             :         {
     264         439 :             peak_H2 = L_add( cldfbBuf_Ener[k + 20], 0 );
     265             :         }
     266        1752 :         avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 /*0.4.Q15*/ ) );
     267             :     }
     268             :     // End
     269         438 :     peak_l = L_deposit_l( 0 );
     270         438 :     avrg_l = L_deposit_l( 0 );
     271         438 :     peak_h = L_deposit_l( 0 );
     272         438 :     avrg_h = L_deposit_l( 0 );
     273       14454 :     FOR( k = 0; k < 32; k++ )
     274             :     {
     275       14016 :         avrg_l = L_add( avrg_l, L_shr( magSq[k + 20], 5 ) );
     276       14016 :         avrg_h = L_add( avrg_h, L_shr( magSq[k + 96], 5 ) );
     277       14016 :         IF( GT_32( magSq[k + 20], peak_l ) )
     278             :         {
     279        2077 :             peak_l = L_add( magSq[k + 20], 0 );
     280             :         }
     281       14016 :         IF( GT_32( magSq[k + 96], peak_h ) )
     282             :         {
     283        1867 :             peak_h = L_add( magSq[k + 96], 0 );
     284             :         }
     285             :     }
     286             : 
     287             :     /* Compute: d_acc - 12*(np -1). */
     288         438 :     acc = L_deposit_l( d_acc );
     289         438 :     IF( L_msu( acc, 12 / 2, sub( np, 1 ) ) > 0 ) /* 12/2 is to compensate the fractional mode multiply */
     290             :     {
     291           1 :         condition1 = 1; /* Signifies: d_acc/(np - 1) > 12 */
     292           1 :         move16();
     293             :     }
     294             :     ELSE
     295             :     {
     296         437 :         condition1 = 0; /* Signifies: d_acc/(np - 1) <= 12 */
     297         437 :         move16();
     298             :         /* NB: For np = 0 or 1, it fits this condition. */
     299             :     }
     300             : 
     301             :     /* Compute: p_energy - 147.87276*n_energy. */
     302         438 :     IF( n_energy_man != 0 )
     303             :     {
     304         438 :         Mpy_32_16_ss( n_energy_man, 18928, &acc, &lsb16 ); /* 147.87276 in Q7 */
     305         438 :         expo = sub( n_energy_exp, 15 - 7 );                /* Due to 18928 in Q7 */
     306         438 :         acc = L_negate( acc );                             /* To facilitate the following floating_point_add() to perform subtraction. */
     307         438 :         floating_point_add( &acc, &expo, p_energy_man, p_energy_exp );
     308             :     }
     309             :     ELSE
     310             :     {
     311           0 :         acc = L_deposit_l( 0 );
     312             :     }
     313         438 :     IF( acc > 0 )
     314             :     {
     315          37 :         condition2 = 1; /* Signifies: p_energy / n_energy > 147.87276 */
     316          37 :         move16();
     317             :     }
     318             :     ELSE
     319             :     {
     320         401 :         condition2 = 0; /* Signifies: p_energy / n_energy <= 147.87276 */
     321         401 :         move16();
     322             :     }
     323             : 
     324         438 :     condition3 = 0;
     325         438 :     move16();
     326         438 :     condition4 = 0;
     327         438 :     move16();
     328             : 
     329         438 :     L_tmp = Mult_32_16( peak_h, 12603 /*1/2.56.Q15*/ );
     330         438 :     IF( GT_32( peak_l, L_tmp ) )
     331             :     {
     332         354 :         exp = norm_l( peak_l );
     333             :     }
     334             :     ELSE
     335             :     {
     336          84 :         exp = norm_l( L_tmp );
     337             :     }
     338         438 :     IF( GT_32( avrg_h, avrg_l ) )
     339             :     {
     340         183 :         exp1 = norm_l( avrg_h );
     341             :     }
     342             :     ELSE
     343             :     {
     344         255 :         exp1 = norm_l( avrg_l );
     345             :     }
     346             : 
     347         438 :     L_tmp1 = Mult_32_16( peak_l, 12603 /*1/2.56.Q15*/ );
     348         438 :     IF( GT_32( peak_h, L_tmp1 ) )
     349             :     {
     350         211 :         exp2 = norm_l( peak_h );
     351             :     }
     352             :     ELSE
     353             :     {
     354         227 :         exp2 = norm_l( L_tmp1 );
     355             :     }
     356             : 
     357         438 :     test();
     358         438 :     test();
     359         438 :     test();
     360         438 :     test();
     361             : #ifdef ISSUE_1867_replace_overflow_libenc
     362         438 :     IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_sat( avrg_H1, 1 ) ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( L_tmp, exp ), L_shl( avrg_l, exp1 ) ) ) || GT_32( Mult_32_32( L_shl( L_tmp1, exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) )
     363             : #else
     364             :     IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_o( avrg_H1, 1, &Overflow ) ) ) || ( LT_32( Mult_32_32( L_shl_o( peak_l, exp, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( L_tmp, exp, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) || GT_32( Mult_32_32( L_shl_o( L_tmp1, exp2, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( peak_h, exp2, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) ) )
     365             : #endif
     366             :     {
     367         127 :         condition3 = 1;
     368         127 :         move16();
     369             :     }
     370             : 
     371         438 :     L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ );
     372         438 :     IF( GT_32( peak_l, L_tmp ) )
     373             :     {
     374         351 :         exp = norm_l( peak_l );
     375             :     }
     376             :     ELSE
     377             :     {
     378          87 :         exp = norm_l( L_tmp );
     379             :     }
     380             : 
     381         438 :     L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ );
     382         438 :     IF( GT_32( peak_h, L_tmp1 ) )
     383             :     {
     384         247 :         exp2 = norm_l( peak_h );
     385             :     }
     386             :     ELSE
     387             :     {
     388         191 :         exp2 = norm_l( L_tmp1 );
     389             :     }
     390             : 
     391         438 :     IF( GT_32( peak_h, L_shl( L_tmp1, 1 ) ) )
     392             :     {
     393         211 :         exp3 = norm_l( peak_h );
     394             :     }
     395             :     ELSE
     396             :     {
     397         227 :         exp3 = sub( norm_l( L_tmp1 ), 1 );
     398             :     }
     399             : 
     400         438 :     test();
     401         438 :     test();
     402         438 :     test();
     403         438 :     test();
     404         438 :     test();
     405         438 :     test();
     406         438 :     test();
     407         438 :     test();
     408         438 :     test();
     409         438 :     IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) )
     410             :     {
     411          26 :         condition4 = 1;
     412          26 :         move16();
     413             :     }
     414             : 
     415         438 :     test();
     416         438 :     test();
     417         438 :     test();
     418         438 :     test();
     419         438 :     IF( ( GE_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) && GT_32( st_fx->input_Fs, 16000 ) && ( s_xor( condition1, condition2 ) != 0 || condition3 ) ) || ( ( LT_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) || EQ_32( st_fx->input_Fs, 16000 ) ) && condition4 ) )
     420             :     {
     421          26 :         c = MDCT_CLASSIFER_HQ_LOCAL; /* Q13 */
     422          26 :         move16();
     423             :     }
     424             :     ELSE
     425             :     {
     426         412 :         c = MDCT_CLASSIFER_TCX_LOCAL; /* Q13 */
     427         412 :         move16();
     428             :     }
     429             : 
     430             :     /* Smooth decision from instantaneous decision*/
     431         438 :     acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF );      /* st_fx->clas_sec_old_fx in Q13 */
     432         438 :     clas_sec = mac_r( acc, c, 0x7fff /*1.Q15*/ - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */
     433             :     /* Do thresholding with hysteresis */
     434         438 :     IF( GT_16( st_fx->last_enerBuffer_exp, enerBuffer_exp ) )
     435             :     {
     436         151 :         gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp
     437         151 :         move32();
     438         151 :         gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp
     439         151 :         move32();
     440             :     }
     441             :     ELSE
     442             :     {
     443         287 :         hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp
     444         287 :         move32();
     445         287 :         hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp
     446         287 :         move32();
     447         287 :         gain1_tmp = gain1;
     448         287 :         move32();
     449         287 :         gain2_tmp = gain2;
     450         287 :         move32();
     451             :     }
     452             : 
     453         438 :     test();
     454         438 :     test();
     455         438 :     test();
     456         438 :     test();
     457         438 :     test();
     458         438 :     test();
     459             : #ifdef ISSUE_1867_replace_overflow_libenc
     460         438 :     IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_sat( gain1_tmp, 1 ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_sat( gain2_tmp, 1 ) ) ) ) )
     461             : #else
     462             :     IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_o( gain1_tmp, 1, &Overflow ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_o( gain2_tmp, 1, &Overflow ) ) ) ) )
     463             : #endif
     464             :     {
     465         203 :         clas_final = hTcxEnc->clas_final_old;
     466         203 :         move16();
     467             :     }
     468         235 :     ELSE IF( GT_16( clas_sec, hTcxEnc->clas_sec_old_fx ) && GT_16( clas_sec, MDCT_CLASSIFER_THRESH_UP ) ) /* Going up? */
     469             :     {
     470           9 :         clas_final = HQ_CORE; /* Q0 */
     471           9 :         move16();
     472             :     }
     473         226 :     ELSE IF( LT_16( clas_sec, MDCT_CLASSIFER_THRESH_DOWN ) ) /* Going down */
     474             :     {
     475         160 :         clas_final = TCX_20_CORE;
     476         160 :         move16();
     477             :     }
     478             :     ELSE
     479             :     {
     480          66 :         clas_final = hTcxEnc->clas_final_old;
     481          66 :         move16();
     482             :     }
     483             : 
     484         438 :     test();
     485         438 :     test();
     486         438 :     test();
     487             :     /* Prevent the usage of MDCTA on noisy-speech or inactive */
     488         438 :     if ( EQ_16( st_fx->mdct_sw_enable, MODE2 ) && ( EQ_16( st_fx->flag_noisy_speech_snr, 1 ) || st_fx->vad_flag == 0 ) && EQ_16( clas_final, HQ_CORE ) )
     489             :     {
     490           0 :         clas_final = TCX_20_CORE;
     491           0 :         move16();
     492             :     }
     493             :     /* Restrict usage of HQ_core to supported operating range */
     494             :     /* EVS: brate == st->total_brate */
     495             :     /* IVAS: brate is the nominal bitrate while st->total_brate may fluctuate. This sets a hard limit for HQ at HQ_16k40 */
     496         438 :     test();
     497         438 :     test();
     498         438 :     test();
     499         438 :     if ( LE_32( st_fx->total_brate, HQ_16k40 ) || LT_32( brate, HQ_16k40 ) || EQ_16( st_fx->bwidth, NB ) || GT_32( brate, IVAS_48k ) )
     500             :     {
     501           0 :         clas_final = TCX_20_CORE;
     502           0 :         move16();
     503             :     }
     504             : 
     505             :     /* Memory update */
     506         438 :     hTcxEnc->clas_sec_old_fx = clas_sec;
     507         438 :     move16(); /* Q13 */
     508         438 :     hTcxEnc->clas_final_old = clas_final;
     509         438 :     move16(); /* Q0 */
     510         438 :     hTcxEnc->last_gain1 = gain1;
     511         438 :     move32();
     512         438 :     hTcxEnc->last_gain2 = gain2;
     513         438 :     move32();
     514         438 :     st_fx->last_enerBuffer_exp = enerBuffer_exp;
     515         438 :     move16();
     516             : 
     517         438 :     return clas_final; /* Q0 */
     518             : }
     519             : 
     520       90087 : Word16 mdct_classifier_ivas_fx(
     521             :     Encoder_State *st,         /* i/o: Encoder state variable                  */
     522             :     const Word16 *fft_buff,    /* i  : FFT spectrum from fft_rel               */
     523             :     const Word32 enerBuffer[], /* i  : energy buffer                           enerBuffer_exp*/
     524             :     Word16 enerBuffer_exp,
     525             :     const Word32 brate /* i  : current brate, IVAS: nominal bitrate, EVS: st->total_brate */
     526             : )
     527             : {
     528             :     Word16 c;
     529             :     Word32 X[129];
     530             :     Word16 k;
     531             :     Word32 nf;
     532             :     Word32 pe;
     533             :     Word16 np;
     534             :     Word32 max_cand;
     535             :     Word16 max_i;
     536             :     Word32 p_energy_man, n_energy_man, man;
     537             :     Word16 p_energy_exp, n_energy_exp, expo;
     538             :     Word16 d_acc;
     539             :     Word16 pos_last;
     540             :     Word16 clas_sec;
     541             :     Word16 clas_final;
     542             :     Word16 i;
     543             :     Word32 gain1, gain2, gain3, gain11, gain4;
     544             :     Word32 peak_l, peak_h, avrg_l, avrg_h, peak_H1, avrg_H1, peak_H2, avrg_H2;
     545             :     Word16 condition1, condition2;
     546             :     Word16 condition3, condition4;
     547             :     Word16 gain2_start, gain3_start, gain4_start, H1_start, H2_start, H_length;
     548             :     Word16 factor;
     549             :     Word32 acc;
     550             :     UWord16 lsb16;
     551             :     UWord32 lsb32;
     552       90087 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     553             :     Word16 exp, exp1, exp2, exp3;
     554       90087 :     Word32 gain1_tmp = 0, gain2_tmp = 0;
     555             :     Word32 L_tmp, L_tmp1;
     556             : #ifndef ISSUE_1867_replace_overflow_libenc
     557             :     Flag Overflow = 0;
     558             :     move16();
     559             : #endif
     560       90087 :     move16();
     561       90087 :     move16();
     562             : 
     563       90087 :     test();
     564       90087 :     IF( EQ_32( st->input_Fs, 32000 ) || EQ_32( st->input_Fs, 48000 ) )
     565             :     {
     566       86979 :         gain2_start = GAIN2_START_SWB;
     567       86979 :         gain3_start = GAIN3_START_SWB;
     568       86979 :         gain4_start = GAIN4_START_SWB;
     569       86979 :         H1_start = H1_START_SWB;
     570       86979 :         H2_start = H2_START_SWB;
     571       86979 :         H_length = H_LENGTH_SWB;
     572       86979 :         move16();
     573       86979 :         move16();
     574       86979 :         move16();
     575       86979 :         move16();
     576       86979 :         move16();
     577       86979 :         move16();
     578             :     }
     579        3108 :     ELSE IF( EQ_32( st->input_Fs, 16000 ) )
     580             :     {
     581        3108 :         gain2_start = GAIN2_START_WB;
     582        3108 :         gain3_start = GAIN3_START_WB;
     583        3108 :         gain4_start = GAIN4_START_WB;
     584        3108 :         H1_start = H1_START_WB;
     585        3108 :         H2_start = H2_START_WB;
     586        3108 :         H_length = H_LENGTH_WB;
     587        3108 :         move16();
     588        3108 :         move16();
     589        3108 :         move16();
     590        3108 :         move16();
     591        3108 :         move16();
     592        3108 :         move16();
     593             :     }
     594             :     ELSE
     595             :     {
     596           0 :         assert( !"Unknown sampling frequency in MDCT_classifier" );
     597             :         H1_start = -1;    /* to avoid compilation warning */
     598             :         H2_start = -1;    /* to avoid compilation warning */
     599             :         H_length = -1;    /* to avoid compilation warning */
     600             :         gain2_start = -1; /* to avoid compilation warning */
     601             :         gain3_start = -1; /* to avoid compilation warning */
     602             :         gain4_start = -1; /* to avoid compilation warning */
     603             :         move16();
     604             :         move16();
     605             :         move16();
     606             :         move16();
     607             :         move16();
     608             :         move16();
     609             :     }
     610             : 
     611       90087 :     IF( NE_16( st->element_mode, IVAS_CPE_DFT ) )
     612             :     {
     613       81637 :         dft_mag_square_fx( fft_buff, X, 256 );
     614             :     }
     615             :     ELSE
     616             :     {
     617             :         Word16 norm_val;
     618             : 
     619        8450 :         norm_val = i_mult( L_FFT, shr( L_FFT, 2 ) );
     620     1090050 :         FOR( k = 0; k < 128; k++ )
     621             :         {
     622     1081600 :             X[k + 1] = Mpy_32_16_1( st->Bin_E_old_fx[k], norm_val );
     623             :         }
     624        8450 :         X[0] = X[1];
     625        8450 :         move32();
     626             :     }
     627             : 
     628       90087 :     nf = L_add( X[0], 0 );
     629       90087 :     pe = L_add( X[0], 0 );
     630       90087 :     np = 0;
     631       90087 :     move16();
     632             : 
     633       90087 :     max_cand = L_negate( 1 );
     634       90087 :     max_i = 0;
     635       90087 :     move16();
     636             : 
     637       90087 :     p_energy_man = L_deposit_l( 0 );
     638       90087 :     n_energy_man = L_deposit_l( 0 );
     639       90087 :     p_energy_exp = n_energy_exp = 32;
     640       90087 :     move16();
     641       90087 :     move16();
     642       90087 :     d_acc = 0;
     643       90087 :     move16();
     644       90087 :     pos_last = -1;
     645       90087 :     move16();
     646             : 
     647    11621223 :     FOR( k = 0; k < 128; k++ )
     648             :     {
     649             :         /* NB: a*f + b*(1 - f)      needs two multiplies
     650             :          *     = (a - b)*f + b      saves one multiply     */
     651    11531136 :         IF( GT_32( X[k + 1], nf ) )
     652             :         {
     653     5606832 :             factor = 31385;
     654     5606832 :             move16(); /* 0.9578 in Q15 */
     655             :         }
     656             :         ELSE
     657             :         {
     658     5924304 :             factor = 21207;
     659     5924304 :             move16(); /* 0.6472 in Q15 */
     660             :         }
     661             : 
     662    11531136 :         acc = L_sub( nf, X[k + 1] );
     663    11531136 :         Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
     664    11531136 :         nf = L_add( acc, X[k + 1] );
     665             : 
     666    11531136 :         IF( GT_32( X[k + 1], pe ) )
     667             :         {
     668     1990321 :             factor = 13840;
     669     1990321 :             move16(); /* 0.42237 in Q15 */
     670             :         }
     671             :         ELSE
     672             :         {
     673     9540815 :             factor = 26308;
     674     9540815 :             move16(); /* 0.80285 in Q15 */
     675             :         }
     676             : 
     677    11531136 :         acc = L_sub( pe, X[k + 1] );
     678    11531136 :         Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
     679    11531136 :         pe = L_add( acc, X[k + 1] );
     680    11531136 :         Mpy_32_16_ss( pe, 20972, &acc, &lsb16 ); /* 0.64 in Q15 */
     681             : 
     682    11531136 :         IF( GT_32( X[k + 1], acc ) )
     683             :         {
     684     3122817 :             IF( GT_32( X[k + 1], max_cand ) )
     685             :             {
     686     2547485 :                 max_cand = X[k + 1];
     687     2547485 :                 move32();
     688     2547485 :                 max_i = add( 2, k );
     689             :             }
     690             :         }
     691             :         ELSE
     692             :         {
     693     8408319 :             IF( max_i > 0 )
     694             :             {
     695     1611807 :                 IF( np > 0 )
     696             :                 {
     697     1521720 :                     d_acc = sub( add( d_acc, max_i ), pos_last );
     698             :                 }
     699     1611807 :                 np = add( np, 1 );
     700     1611807 :                 pos_last = max_i;
     701     1611807 :                 move16();
     702             :             }
     703             : 
     704     8408319 :             max_cand = L_negate( 1 );
     705     8408319 :             max_i = 0;
     706     8408319 :             move16();
     707             :         }
     708             : 
     709    11531136 :         IF( pe != 0 )
     710             :         {
     711    11531136 :             expo = norm_l( pe );
     712    11531136 :             man = L_shl( pe, expo );                // expo
     713    11531136 :             Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */
     714    11531136 :             expo = shl( expo, 1 );                  /* Multiply by 2 due to squaring. */
     715    11531136 :             floating_point_add( &p_energy_man, &p_energy_exp, man, expo );
     716             :         }
     717    11531136 :         IF( nf != 0 )
     718             :         {
     719    11531128 :             expo = norm_l( nf );
     720    11531128 :             man = L_shl( nf, expo );
     721    11531128 :             Mpy_32_32_ss( man, man, &man, &lsb32 ); /* nf square */
     722    11531128 :             expo = shl( expo, 1 );                  /* Multiply by 2 due to squaring. */
     723    11531128 :             floating_point_add( &n_energy_man, &n_energy_exp, man, expo );
     724             :         }
     725             :     }
     726             : 
     727       90087 :     gain1 = L_deposit_l( 0 );
     728       90087 :     gain2 = L_deposit_l( 0 );
     729       90087 :     gain3 = L_deposit_l( 0 );
     730             : 
     731      804567 :     FOR( i = 0; i < gain2_start; i++ )
     732             :     {
     733      714480 :         IF( EQ_16( gain2_start, GAIN2_START_SWB ) )
     734             :         {
     735      695832 :             gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) );               // enerBuffer_exp - 3
     736      695832 :             gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); // enerBuffer_exp - 3
     737      695832 :             gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); // enerBuffer_exp - 3
     738             :         }
     739             :         ELSE
     740             :         {
     741       18648 :             gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) );                            // enerBuffer_exp
     742       18648 :             gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp
     743       18648 :             gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp
     744             :         }
     745             :     }
     746             : 
     747             : 
     748       90087 :     IF( EQ_16( gain2_start, GAIN2_START_SWB ) )
     749             :     {
     750       86979 :         acc = L_shr( enerBuffer[0], 3 );             // enerBuffer_exp - 3
     751       86979 :         acc = L_sub( gain1, acc );                   // enerBuffer_exp - 3
     752       86979 :         acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); // enerBuffer_exp - 3
     753       86979 :         gain11 = L_shl( acc, 3 );                    // enerBuffer_exp
     754       86979 :         gain4 = L_deposit_l( 0 );
     755             :     }
     756             :     ELSE
     757             :     {
     758        3108 :         acc = Mult_32_16( enerBuffer[0], 5461 /*0.16.Q15*/ ); // enerBuffer_exp
     759        3108 :         acc = L_sub( gain1, acc );                            // enerBuffer_exp
     760        3108 :         acc = Mult_32_16( acc, 6553 /*0.4.Q15*/ );            // enerBuffer_exp
     761        3108 :         gain11 = (Word32) W_mult_32_16( acc, 6 );
     762        3108 :         gain4 = L_deposit_l( 0 );
     763             :     }
     764             : 
     765       90087 :     gain4 = L_deposit_l( 0 );
     766     1161807 :     FOR( i = 0; i < gain4_start; i++ )
     767             :     {
     768     1071720 :         IF( EQ_16( gain4_start, GAIN4_START_SWB ) )
     769             :         {
     770     1043748 :             gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 /*(1/12).Q15*/ ) );
     771             :         }
     772             :         ELSE
     773             :         {
     774       27972 :             gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 /*(1/9).Q1.15*/ ) );
     775             :         }
     776             :     }
     777             : 
     778       90087 :     peak_H1 = enerBuffer[H1_start]; // enerBuffer_exp
     779       90087 :     move32();
     780             : 
     781       90087 :     avrg_H1 = enerBuffer[H1_start]; // enerBuffer_exp
     782       90087 :     move32();
     783             : 
     784      444219 :     FOR( i = 1; i < H_length; i++ )
     785             :     {
     786      354132 :         IF( GT_32( enerBuffer[H1_start + i], peak_H1 ) )
     787             :         {
     788       95938 :             peak_H1 = enerBuffer[H1_start + i]; // enerBuffer_exp
     789       95938 :             move32();
     790             :         }
     791      354132 :         avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); // enerBuffer_exp
     792             :     }
     793             : 
     794       90087 :     peak_H2 = enerBuffer[H2_start];
     795       90087 :     move32();
     796             : 
     797       90087 :     avrg_H2 = enerBuffer[H2_start];
     798       90087 :     move32();
     799             : 
     800      444219 :     FOR( i = 1; i < H_length; i++ )
     801             :     {
     802      354132 :         IF( GT_32( enerBuffer[H2_start + i], peak_H2 ) )
     803             :         {
     804       88065 :             peak_H2 = enerBuffer[H2_start + i];
     805       88065 :             move32();
     806             :         }
     807      354132 :         avrg_H2 = L_add( avrg_H2, enerBuffer[H2_start + i] );
     808             :     }
     809             : 
     810       90087 :     peak_l = L_deposit_l( 0 );
     811       90087 :     avrg_l = L_deposit_l( 0 );
     812       90087 :     peak_h = L_deposit_l( 0 );
     813       90087 :     avrg_h = L_deposit_l( 0 );
     814             : 
     815     2972871 :     FOR( i = 0; i < 32; i++ )
     816             :     {
     817     2882784 :         avrg_l = L_add( avrg_l, L_shr( X[20 + i], 5 ) );
     818     2882784 :         avrg_h = L_add( avrg_h, L_shr( X[96 + i], 5 ) );
     819     2882784 :         IF( GT_32( X[20 + i], peak_l ) )
     820             :         {
     821      351865 :             peak_l = L_add( X[20 + i], 0 );
     822             :         }
     823     2882784 :         IF( GT_32( X[96 + i], peak_h ) )
     824             :         {
     825      394618 :             peak_h = L_add( X[96 + i], 0 );
     826             :         }
     827             :     }
     828             : 
     829             :     /* Compute: d_acc - 12*(np -1). */
     830       90087 :     acc = L_deposit_l( d_acc );
     831       90087 :     IF( L_msu( acc, 12 / 2, sub( np, 1 ) ) > 0 ) /* 12/2 is to compensate the fractional mode multiply */
     832             :     {
     833        3267 :         condition1 = 1; /* Signifies: d_acc/(np - 1) > 12 */
     834        3267 :         move16();
     835             :     }
     836             :     ELSE
     837             :     {
     838       86820 :         condition1 = 0; /* Signifies: d_acc/(np - 1) <= 12 */
     839       86820 :         move16();
     840             :         /* NB: For np = 0 or 1, it fits this condition. */
     841             :     }
     842             : 
     843             :     /* Compute: p_energy - 147.87276*n_energy. */
     844       90087 :     IF( n_energy_man != 0 )
     845             :     {
     846       90087 :         Mpy_32_16_ss( n_energy_man, 18928, &acc, &lsb16 ); /* 147.87276 in Q7 */
     847       90087 :         expo = sub( n_energy_exp, 15 - 7 );                /* Due to 18928 in Q7 */
     848       90087 :         acc = L_negate( acc );                             /* To facilitate the following floating_point_add() to perform subtraction. */
     849       90087 :         floating_point_add( &acc, &expo, p_energy_man, p_energy_exp );
     850             :     }
     851             :     ELSE
     852             :     {
     853           0 :         acc = L_deposit_l( 0 );
     854             :     }
     855       90087 :     IF( acc > 0 )
     856             :     {
     857        8142 :         condition2 = 1; /* Signifies: p_energy / n_energy > 147.87276 */
     858        8142 :         move16();
     859             :     }
     860             :     ELSE
     861             :     {
     862       81945 :         condition2 = 0; /* Signifies: p_energy / n_energy <= 147.87276 */
     863       81945 :         move16();
     864             :     }
     865             : 
     866       90087 :     condition3 = 0;
     867       90087 :     move16();
     868       90087 :     condition4 = 0;
     869       90087 :     move16();
     870             : 
     871       90087 :     L_tmp = Mult_32_16( peak_h, 12603 );
     872       90087 :     IF( GT_32( peak_l, L_tmp ) )
     873             :     {
     874       81746 :         exp = norm_l( peak_l );
     875             :     }
     876             :     ELSE
     877             :     {
     878        8341 :         exp = norm_l( L_tmp );
     879             :     }
     880       90087 :     IF( GT_32( avrg_h, avrg_l ) )
     881             :     {
     882       18737 :         exp1 = norm_l( avrg_h );
     883             :     }
     884             :     ELSE
     885             :     {
     886       71350 :         exp1 = norm_l( avrg_l );
     887             :     }
     888             : 
     889       90087 :     L_tmp1 = Mult_32_16( peak_l, 12603 );
     890       90087 :     IF( GT_32( peak_h, L_tmp1 ) )
     891             :     {
     892       24963 :         exp2 = norm_l( peak_h );
     893             :     }
     894             :     ELSE
     895             :     {
     896       65124 :         exp2 = norm_l( L_tmp1 );
     897             :     }
     898             : 
     899       90087 :     test();
     900       90087 :     test();
     901       90087 :     test();
     902       90087 :     test();
     903             : #ifdef ISSUE_1867_replace_overflow_libenc
     904       90087 :     IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_sat( avrg_H1, 1 ) ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( L_tmp, exp ), L_shl( avrg_l, exp1 ) ) ) || GT_32( Mult_32_32( L_shl( L_tmp1, exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) )
     905             : #else
     906             :     IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_o( avrg_H1, 1, &Overflow ) ) ) || ( LT_32( Mult_32_32( L_shl_o( peak_l, exp, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( L_tmp, exp, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) || GT_32( Mult_32_32( L_shl_o( L_tmp1, exp2, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( peak_h, exp2, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) ) )
     907             : #endif
     908             :     {
     909       22815 :         condition3 = 1;
     910       22815 :         move16();
     911             :     }
     912             : 
     913       90087 :     L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ );
     914       90087 :     IF( GT_32( peak_l, L_tmp ) )
     915             :     {
     916       81626 :         exp = norm_l( peak_l );
     917             :     }
     918             :     ELSE
     919             :     {
     920        8461 :         exp = norm_l( L_tmp );
     921             :     }
     922             : 
     923       90087 :     L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ );
     924       90087 :     IF( GT_32( peak_h, L_tmp1 ) )
     925             :     {
     926       31698 :         exp2 = norm_l( peak_h );
     927             :     }
     928             :     ELSE
     929             :     {
     930       58389 :         exp2 = norm_l( L_tmp1 );
     931             :     }
     932             : 
     933       90087 :     IF( GT_32( peak_h, L_shl( L_tmp1, 1 ) ) )
     934             :     {
     935       24829 :         exp3 = norm_l( peak_h );
     936             :     }
     937             :     ELSE
     938             :     {
     939       65258 :         exp3 = sub( norm_l( L_tmp1 ), 1 );
     940             :     }
     941             : 
     942       90087 :     test();
     943       90087 :     test();
     944       90087 :     test();
     945       90087 :     test();
     946       90087 :     test();
     947       90087 :     test();
     948       90087 :     test();
     949       90087 :     test();
     950       90087 :     test();
     951       90087 :     IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) ||
     952             :         ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) )
     953             :     {
     954        7415 :         condition4 = 1;
     955        7415 :         move16();
     956             :     }
     957             : 
     958       90087 :     test();
     959       90087 :     test();
     960       90087 :     test();
     961       90087 :     test();
     962       90087 :     test();
     963       90087 :     test();
     964             : 
     965       90087 :     IF( ( GE_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) && GT_32( st->input_Fs, 16000 ) && ( s_xor( condition1, condition2 ) != 0 || condition3 ) ) || ( ( LT_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) || EQ_32( st->input_Fs, 16000 ) ) && condition4 ) )
     966             :     {
     967        8543 :         c = MDCT_CLASSIFER_HQ_LOCAL; /* Q13 */
     968        8543 :         move16();
     969             :     }
     970             :     ELSE
     971             :     {
     972       81544 :         c = MDCT_CLASSIFER_TCX_LOCAL; /* Q13 */
     973       81544 :         move16();
     974             :     }
     975             : 
     976             :     /* Smooth decision from instantaneous decision*/
     977       90087 :     acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */
     978       90087 :     clas_sec = mac_r( acc, c, 0x7fff - MDCT_CLASSIFER_SMOOTH_FILT_COEFF );      /* clas_sec and c are in Q13 */
     979             : 
     980             :     /* Do thresholding with hysteresis */
     981             : 
     982       90087 :     IF( GT_16( st->last_enerBuffer_exp, enerBuffer_exp ) )
     983             :     {
     984       25421 :         gain1_tmp = L_shr( gain1, sub( st->last_enerBuffer_exp, enerBuffer_exp ) );
     985       25421 :         move32();
     986       25421 :         gain2_tmp = L_shr( gain2, sub( st->last_enerBuffer_exp, enerBuffer_exp ) );
     987       25421 :         move32();
     988             :     }
     989             :     ELSE
     990             :     {
     991       64666 :         hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st->last_enerBuffer_exp ) );
     992       64666 :         move32();
     993       64666 :         hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st->last_enerBuffer_exp ) );
     994       64666 :         move32();
     995       64666 :         gain1_tmp = gain1;
     996       64666 :         move32();
     997       64666 :         gain2_tmp = gain2;
     998       64666 :         move32();
     999             :     }
    1000             : 
    1001       90087 :     test();
    1002       90087 :     test();
    1003       90087 :     test();
    1004       90087 :     test();
    1005       90087 :     test();
    1006       90087 :     test();
    1007             : 
    1008             : #ifdef ISSUE_1867_replace_overflow_libenc
    1009       90087 :     IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_sat( gain1_tmp, 1 ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_sat( gain2_tmp, 1 ) ) ) ) )
    1010             : #else
    1011             :     IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_o( gain1_tmp, 1, &Overflow ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_o( gain2_tmp, 1, &Overflow ) ) ) ) )
    1012             : #endif
    1013             :     {
    1014       53119 :         clas_final = hTcxEnc->clas_final_old;
    1015       53119 :         move16();
    1016             :     }
    1017       36968 :     ELSE IF( GT_16( clas_sec, hTcxEnc->clas_sec_old_fx ) && GT_16( clas_sec, MDCT_CLASSIFER_THRESH_UP ) ) /* Going up? */
    1018             :     {
    1019        2934 :         clas_final = HQ_CORE; /* Q0 */
    1020        2934 :         move16();
    1021             :     }
    1022       34034 :     ELSE IF( LT_16( clas_sec, MDCT_CLASSIFER_THRESH_DOWN ) ) /* Going down */
    1023             :     {
    1024       24610 :         clas_final = TCX_20_CORE;
    1025       24610 :         move16();
    1026             :     }
    1027             :     ELSE
    1028             :     {
    1029        9424 :         clas_final = hTcxEnc->clas_final_old;
    1030        9424 :         move16();
    1031             :     }
    1032             : 
    1033             : 
    1034             :     /* Prevent the usage of HQ_CORE on noisy-speech or inactive */
    1035       90087 :     test();
    1036       90087 :     test();
    1037       90087 :     test();
    1038       90087 :     if ( EQ_16( st->mdct_sw_enable, MODE2 || st->element_mode > EVS_MONO ) && ( EQ_16( st->flag_noisy_speech_snr, 1 ) || st->vad_flag == 0 ) && EQ_16( clas_final, HQ_CORE ) )
    1039             :     {
    1040         138 :         clas_final = TCX_20_CORE;
    1041         138 :         move16();
    1042             :     }
    1043             : 
    1044             :     /* Restrict usage of HQ_core to supported operating range */
    1045             :     /* EVS: brate == st->total_brate */
    1046             :     /* IVAS: brate is the nominal bitrate while st->total_brate may fluctuate. This sets a hard limit for HQ at HQ_16k40 */
    1047       90087 :     test();
    1048       90087 :     test();
    1049       90087 :     test();
    1050       90087 :     if ( LE_32( st->total_brate, HQ_16k40 ) || LT_32( brate, HQ_16k40 ) || EQ_16( st->bwidth, NB ) || GT_32( brate, IVAS_48k ) )
    1051             :     {
    1052       47728 :         clas_final = TCX_20_CORE;
    1053       47728 :         move16();
    1054             :     }
    1055             : 
    1056             : 
    1057             :     /* Memory update */
    1058             : 
    1059       90087 :     hTcxEnc->clas_sec_old_fx = clas_sec;
    1060       90087 :     move16(); /* Q13 */
    1061       90087 :     hTcxEnc->clas_final_old = clas_final;
    1062       90087 :     move16(); /* Q0 */
    1063       90087 :     hTcxEnc->last_gain1 = gain1;
    1064       90087 :     move32();
    1065       90087 :     hTcxEnc->last_gain2 = gain2;
    1066       90087 :     move32();
    1067       90087 :     st->last_enerBuffer_exp = enerBuffer_exp;
    1068       90087 :     move16();
    1069             : 
    1070       90087 :     return clas_final;
    1071             : }

Generated by: LCOV version 1.14