LCOV - code coverage report
Current view: top level - lib_enc - tcx_utils_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1691 2037 83.0 %
Date: 2025-05-03 01:55:50 Functions: 27 29 93.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 "stl.h"
      10             : #include "options.h"
      11             : #include "cnst.h"
      12             : //#include "prot_fx.h"
      13             : #include "rom_basop_util.h"
      14             : #include "basop_util.h"
      15             : #include "rom_com.h"
      16             : #include "prot_fx.h"     /* Function prototypes                    */
      17             : #include "prot_fx_enc.h" /* Function prototypes                    */
      18             : #include "ivas_prot_fx.h"
      19             : 
      20             : #define inv_int InvIntTable
      21             : extern const Word16 int_sqr[17];
      22             : 
      23             : #define ONE_POINT_ONE_FIVE_Q7  147
      24             : #define ONE_POINT_ONE_FIVE_Q23 9646899
      25             : 
      26     4960735 : static Word16 quantize( Word32 x, Word16 invGain, Word16 shift, Word32 offset )
      27             : {
      28             :     Word16 tmp16;
      29             :     Word32 tmp32;
      30             : 
      31     4960735 :     tmp32 = Mpy_32_16_1( L_abs( x ), invGain ); /* multiply */
      32     4960735 :     tmp32 = L_shl( tmp32, shift );              /* convert to 15Q16 */
      33     4960735 :     tmp32 = L_add( tmp32, offset );             /* add offset */
      34     4960735 :     tmp16 = extract_h( tmp32 );                 /* truncate */
      35     4960735 :     IF( x < 0 )
      36             :     {
      37     2453802 :         tmp16 = negate( tmp16 ); /* restore sign */
      38             :     }
      39             : 
      40     4960735 :     return tmp16;
      41             : }
      42             : 
      43             : /* compute noise-measure flags for spectrum filling and quantization (0: tonal, 1: noise-like) */
      44      459396 : void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec,
      45             :                                      Word16 L_frame,
      46             :                                      Word16 startLine,
      47             :                                      Word8 resetMemory,
      48             :                                      Word8 *noiseFlags,
      49             :                                      Word16 lowpassLine )
      50             : {
      51             :     Word16 i, lastTone, j;
      52             :     Word32 s, c;
      53             :     Word16 tmp16;
      54      459396 :     Word32 tmp1, tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
      55      459396 :     move32();
      56             : 
      57      459396 :     IF( resetMemory != 0 )
      58             :     {
      59    25695778 :         FOR( i = 0; i < lowpassLine; i++ )
      60             :         {
      61    25669280 :             noiseFlags[i] = 0;
      62    25669280 :             move16();
      63             :         }
      64             :     }
      65             : 
      66      459396 :     FOR( i = lowpassLine; i < L_frame; i++ )
      67             :     {
      68           0 :         noiseFlags[i] = 1;
      69           0 :         move16();
      70             :     }
      71             : 
      72      459396 :     test();
      73      459396 :     IF( powerSpec != NULL && LT_16( add( startLine, 6 ), L_frame ) )
      74             :     {
      75      453550 :         lastTone = 0;
      76      453550 :         move16();
      77             : 
      78             :         /* noise-measure flags for spectrum filling and quantization (0: tonal, 1: noise-like) */
      79      453550 :         i = sub( startLine, 1 );
      80      453550 :         s = 0;
      81      453550 :         move32();
      82     7256800 :         FOR( j = -7; j < 8; j++ )
      83             :         {
      84     6803250 :             s = L_add( s, L_shr( powerSpec[i + j], 4 ) );
      85             :         }
      86      453550 :         tmp16 = sub( lowpassLine, 7 );
      87   287521225 :         FOR( i = i + 1; i < tmp16; i++ )
      88             :         {
      89   287067675 :             c = L_shr( powerSpec[i - 1], 4 );
      90   287067675 :             c = L_add( c, L_shr( powerSpec[i], 4 ) );
      91   287067675 :             c = L_add( c, L_shr( powerSpec[i + 1], 4 ) );
      92             : 
      93   287067675 :             s = L_sub( s, L_shr( powerSpec[i - 8], 4 ) );
      94   287067675 :             s = L_add( s, L_shr( powerSpec[i + 7], 4 ) );
      95             : 
      96   287067675 :             tmp1 = L_shr( c, 2 );
      97   287067675 :             IF( noiseFlags[i] == 0 )
      98             :             {
      99    20840916 :                 c = L_shl( c, 1 );
     100             :             }
     101   287067675 :             IF( noiseFlags[i] == 0 )
     102             :             {
     103    20840916 :                 tmp2 = L_sub( c, tmp1 ); /* 1.75 * c */
     104             :             }
     105   287067675 :             IF( noiseFlags[i] != 0 )
     106             :             {
     107   266226759 :                 tmp2 = L_add( c, tmp1 ); /* 1.25 * c */
     108             :             }
     109             : 
     110   287067675 :             tmp2 = L_sub( s, tmp2 );
     111   287067675 :             if ( tmp2 >= 0 )
     112             :             {
     113   285433054 :                 noiseFlags[i] = 1;
     114   285433054 :                 move16();
     115             :             }
     116   287067675 :             if ( tmp2 < 0 )
     117             :             {
     118     1634621 :                 noiseFlags[i] = 0;
     119     1634621 :                 move16();
     120             :             }
     121   287067675 :             if ( tmp2 < 0 )
     122             :             {
     123     1634621 :                 lastTone = i;
     124     1634621 :                 move16();
     125             :             }
     126             :         }
     127             : 
     128             :         /* lower L_frame*startRatio lines are tonal (0), upper 7 lines are processed separately */
     129      453550 :         tmp16 = sub( lowpassLine, 1 );
     130     3174850 :         FOR( ; i < tmp16; i++ )
     131             :         {
     132     2721300 :             c = L_shr( powerSpec[i - 1], 4 );
     133     2721300 :             c = L_add( c, L_shr( powerSpec[i], 4 ) );
     134     2721300 :             c = L_add( c, L_shr( powerSpec[i + 1], 4 ) );
     135             : 
     136     2721300 :             tmp1 = L_shr( c, 2 );
     137     2721300 :             IF( noiseFlags[i] == 0 )
     138             :             {
     139      162590 :                 c = L_shl( c, 1 );
     140             :             }
     141     2721300 :             IF( noiseFlags[i] == 0 )
     142             :             {
     143      162590 :                 tmp2 = L_sub( c, tmp1 ); /* 1.75 * c */
     144             :             }
     145     2721300 :             IF( noiseFlags[i] != 0 )
     146             :             {
     147     2558710 :                 tmp2 = L_add( c, tmp1 ); /* 1.25 * c */
     148             :             }
     149             : 
     150             :             /* running sum can't be updated any more, just use the latest one */
     151     2721300 :             tmp2 = L_sub( s, tmp2 );
     152     2721300 :             if ( tmp2 >= 0 )
     153             :             {
     154     2715147 :                 noiseFlags[i] = 1;
     155     2715147 :                 move16();
     156             :             }
     157     2721300 :             if ( tmp2 < 0 )
     158             :             {
     159        6153 :                 noiseFlags[i] = 0;
     160        6153 :                 move16();
     161             :                 /* lastTone = i; */
     162             :             }
     163             :         }
     164      453550 :         noiseFlags[i] = 1; /* uppermost line is defined as noise-like (1) */
     165      453550 :         move16();
     166             : 
     167      453550 :         if ( lastTone > 0 ) /* spread uppermost tonal line one line upward */
     168             :         {
     169      142633 :             noiseFlags[lastTone + 1] = 0;
     170      142633 :             move16();
     171             :         }
     172             :     }
     173      459396 : }
     174             : 
     175      143349 : void ComputeSpectrumNoiseMeasure_ivas_fx( Word64 *powerSpec, /* Qx */
     176             :                                           Word16 L_frame,    /* Q0 */
     177             :                                           Word16 startLine,  /* Q0 */
     178             :                                           Word8 resetMemory, /* Q0 */
     179             :                                           Word8 *noiseFlags, /* Q0 */
     180             :                                           Word16 lowpassLine /* Q0 */
     181             : )
     182             : {
     183             :     Word16 i, lastTone, j, exp;
     184             :     Word32 c;
     185             :     Word64 s, temp;
     186             : 
     187      143349 :     IF( resetMemory != 0 )
     188             :     {
     189     6242343 :         FOR( i = 0; i < lowpassLine; i++ )
     190             :         {
     191     6235040 :             noiseFlags[i] = 0;
     192     6235040 :             move16();
     193             :         }
     194             :     }
     195             : 
     196      143349 :     FOR( i = lowpassLine; i < L_frame; i++ )
     197             :     {
     198           0 :         noiseFlags[i] = 1;
     199           0 :         move16();
     200             :     }
     201             : 
     202      143349 :     test();
     203      143349 :     IF( powerSpec != NULL && LT_16( add( startLine, 6 ), L_frame ) )
     204             :     {
     205      130457 :         lastTone = 0;
     206      130457 :         move16();
     207             : 
     208             :         /* noise-measure flags for spectrum filling and quantization (0: tonal, 1: noise-like) */
     209      130457 :         i = sub( startLine, 1 );
     210             :         /*  s = powerSpec[i - 7] + powerSpec[i - 6] + powerSpec[i - 5] +
     211             :             powerSpec[i - 4] + powerSpec[i - 3] + powerSpec[i - 2] +
     212             :             powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1] +
     213             :             powerSpec[i + 2] + powerSpec[i + 3] + powerSpec[i + 4] +
     214             :             powerSpec[i + 5] + powerSpec[i + 6] + powerSpec[i + 7]; */
     215             : 
     216      130457 :         s = powerSpec[i - 7]; // Qx
     217      130457 :         move64();
     218     1956855 :         FOR( j = -6; j < 8; j++ )
     219             :         {
     220     1826398 :             s = W_add( s, powerSpec[i + j] ); // Qx
     221             :         }
     222             : 
     223    61511530 :         FOR( i = i + 1; i < lowpassLine - 7; i++ )
     224             :         {
     225             :             /* c = powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1]; */
     226    61381073 :             temp = W_add( W_add( powerSpec[i - 1], powerSpec[i] ), powerSpec[i + 1] );
     227    61381073 :             exp = W_norm( temp );
     228    61381073 :             c = W_extract_h( W_shl( temp, exp ) ); // Qx+exp-32
     229             : 
     230             :             /* s += powerSpec[i + 7] - powerSpec[i - 8]; */
     231    61381073 :             s = W_sub( s, powerSpec[i - 8] ); // Qx
     232    61381073 :             s = W_add( s, powerSpec[i + 7] ); // Qx
     233             : 
     234             :             /* ( 1.75f - 0.5f * noiseFlags[i] ) * c */
     235    61381073 :             temp = W_mult_32_32( c, L_msu0( 28672 /* 1.75 in Q14*/, 8192 /* 0.5 in Q14 */, noiseFlags[i] ) ); // Qx+exp-32+14+1 = Qx+exp-17
     236             : 
     237    61381073 :             IF( GE_64( W_shl( s, sub( exp, Q17 ) ), temp ) /* s >= ( 1.75f - 0.5f * noiseFlags[i] ) * c */ ) // Qx+exp-17
     238             :             {
     239    61237140 :                 noiseFlags[i] = 1;
     240    61237140 :                 move16();
     241             :             }
     242             :             ELSE
     243             :             {
     244      143933 :                 noiseFlags[i] = 0;
     245      143933 :                 lastTone = i;
     246      143933 :                 move16();
     247      143933 :                 move16();
     248             :             }
     249             :         }
     250             : 
     251             :         /* lower L_frame*startRatio lines are tonal (0), upper 7 lines are processed separately */
     252      913199 :         FOR( ; i < lowpassLine - 1; i++ )
     253             :         {
     254             :             /* c = powerSpec[i - 1] + powerSpec[i] + powerSpec[i + 1]; */
     255      782742 :             temp = W_add( W_add( powerSpec[i - 1], powerSpec[i] ), powerSpec[i + 1] );
     256      782742 :             exp = W_norm( temp );
     257      782742 :             c = W_extract_h( W_shl( temp, exp ) ); // Qx+exp-32
     258             : 
     259             :             /* ( 1.75f - 0.5f * noiseFlags[i] ) * c */
     260      782742 :             temp = W_mult_32_32( c, L_msu0( 28672 /* 1.75 in Q14*/, 8192 /* 0.5 in Q14 */, noiseFlags[i] ) ); // Qx+exp-32+14+1 = Qx+exp-17
     261             : 
     262      782742 :             IF( GE_64( W_shl( s, sub( exp, Q17 ) ), temp ) /* s >= ( 1.75f - 0.5f * noiseFlags[i] ) * c */ ) // Qx+exp-17
     263             :             {
     264      778870 :                 noiseFlags[i] = 1;
     265      778870 :                 move16();
     266             :             }
     267             :             ELSE
     268             :             {
     269        3872 :                 noiseFlags[i] = 0;
     270        3872 :                 lastTone = i;
     271        3872 :                 move16();
     272        3872 :                 move16();
     273             :             }
     274             :         }
     275      130457 :         noiseFlags[i] = 1; /* uppermost line is defined as noise-like (1) */
     276      130457 :         move16();
     277             : 
     278      130457 :         if ( lastTone > 0 ) /* spread uppermost tonal line one line upward */
     279             :         {
     280       25130 :             noiseFlags[lastTone + 1] = 0;
     281       25130 :             move16();
     282             :         }
     283             :     }
     284      143349 : }
     285             : 
     286       88615 : static void detectLowpassFac( const Word32 *powerSpec, Word16 powerSpec_e, Word16 L_frame, Word8 rectWin, Word16 *pLpFac, Word16 lowpassLine )
     287             : {
     288             :     Word16 i, tmp;
     289             :     Word32 threshold;
     290             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     291       88615 :     Flag Overflow = 0;
     292       88615 :     move32();
     293             : #endif
     294             : 
     295             : 
     296       88615 :     threshold = 256l /*0.1f * 2*NORM_MDCT_FACTOR Q3*/; /* Q3 */
     297       88615 :     move32();
     298             :     BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, because threshold is being compared to powerSpec[i] below. */
     299       88615 :         threshold = L_shl_o( threshold, sub( 28, powerSpec_e ), &Overflow );
     300             : 
     301       88615 :     IF( rectWin != 0 )
     302             :     {
     303             :         /* compensate for bad side-lobe attenuation with asymmetric windows */
     304        5717 :         threshold = L_shl_o( threshold, 1, &Overflow );
     305             :     }
     306             :     BASOP_SATURATE_WARNING_ON_EVS
     307             : 
     308       88615 :     tmp = shr( lowpassLine, 1 );
     309     1819571 :     FOR( i = lowpassLine - 1; i >= tmp; i-- )
     310             :     {
     311     1813303 :         IF( GT_32( powerSpec[i], threshold ) )
     312             :         {
     313       82347 :             BREAK;
     314             :         }
     315             :     }
     316             : 
     317       88615 :     tmp = getInvFrameLen( L_frame );
     318             : 
     319       88615 :     tmp = mult_r( 22938 /*0.7f Q15*/, round_fx( L_shl( L_mult0( add( i, 1 ), tmp ), 9 ) ) );
     320       88615 :     *pLpFac = add( tmp, mult_r( 9830 /*0.3f Q15*/, *pLpFac ) );
     321       88615 :     move16();
     322       88615 : }
     323             : 
     324             : /*-----------------------------------------------------------*
     325             :  * Compute noise-measure flags for spectrum filling          *
     326             :  * and quantization (0: tonal, 1: noise-like).               *
     327             :  * Detect low pass if present.                               *
     328             :  *-----------------------------------------------------------*/
     329         662 : void AnalyzePowerSpectrum_fx(
     330             :     Encoder_State *st,           /* i/o: encoder states                                  */
     331             :     Word16 L_frame,              /* input: frame length                                  */
     332             :     Word16 L_frameTCX,           /* input: full band frame length                        */
     333             :     Word16 left_overlap,         /* input: left overlap length                           */
     334             :     Word16 right_overlap,        /* input: right overlap length                          */
     335             :     Word32 const mdctSpectrum[], /* input: MDCT spectrum                                 */
     336             :     Word16 mdctSpectrum_e,
     337             :     Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */
     338             :     Word32 powerSpec[],    /* output: Power spectrum. Can point to signal          */
     339             :     Word16 *powerSpec_e )
     340             : {
     341             :     Word16 i, iStart, iEnd, lowpassLine;
     342             :     Word16 tmp, s1, s2;
     343             :     Word32 tmp32;
     344             :     Word8 tmp8;
     345         662 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     346             : 
     347         662 :     lowpassLine = L_frameTCX;
     348         662 :     move16();
     349             : 
     350         662 :     *powerSpec_e = 16;
     351         662 :     move16();
     352         662 :     TCX_MDST( signal, powerSpec, powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
     353             : 
     354         662 :     iStart = 0;
     355         662 :     move16();
     356         662 :     iEnd = L_frameTCX;
     357         662 :     move16();
     358             : 
     359         662 :     IF( st->narrowBand != 0 )
     360             :     {
     361           0 :         attenuateNbSpectrum_fx( L_frameTCX, powerSpec );
     362             :     }
     363             : 
     364             :     /* get shift to common exponent */
     365         662 :     s1 = 0;
     366         662 :     move16();
     367         662 :     s2 = 0;
     368         662 :     move16();
     369         662 :     tmp = sub( mdctSpectrum_e, *powerSpec_e );
     370         662 :     IF( tmp > 0 )
     371             :     {
     372         376 :         s2 = negate( tmp );
     373             :     }
     374         662 :     if ( tmp < 0 )
     375             :     {
     376           0 :         s1 = tmp;
     377           0 :         move16();
     378             :     }
     379             : 
     380             :     /* get headroom */
     381         662 :     tmp = sub( getScaleFactor32( mdctSpectrum, L_frameTCX ), s1 );
     382         662 :     tmp = s_min( tmp, sub( getScaleFactor32( powerSpec, L_frameTCX ), s2 ) );
     383         662 :     s1 = add( s1, tmp );
     384         662 :     s2 = add( s2, tmp );
     385             : 
     386             :     /* power spectrum: MDCT^2 + MDST^2 */
     387      561302 :     FOR( i = iStart; i < iEnd; i++ )
     388             :     {
     389      560640 :         tmp = round_fx_sat( L_shl_sat( mdctSpectrum[i], s1 ) );
     390      560640 :         tmp32 = L_mult0( tmp, tmp );
     391             : 
     392      560640 :         tmp = round_fx_sat( L_shl_sat( powerSpec[i], s2 ) );
     393      560640 :         tmp32 = L_mac0( tmp32, tmp, tmp );
     394             : 
     395      560640 :         powerSpec[i] = tmp32;
     396      560640 :         move32();
     397             :     }
     398             : 
     399         662 :     *powerSpec_e = add( shl( sub( mdctSpectrum_e, s1 ), 1 ), 1 );
     400         662 :     move16();
     401             : 
     402         662 :     tmp8 = 0;
     403         662 :     move16();
     404         662 :     test();
     405         662 :     if ( L_msu0( L_mult0( st->L_frame, extract_l( st->last_sr_core ) ), st->L_frame_past, extract_l( st->sr_core ) ) != 0 || NE_16( st->last_core, TCX_20_CORE ) )
     406             :     {
     407          86 :         tmp8 = 1;
     408          86 :         move16();
     409             :     }
     410             : 
     411         662 :     ComputeSpectrumNoiseMeasure_fx( powerSpec,
     412             :                                     L_frameTCX,
     413         662 :                                     divide3216( L_mult( hTcxEnc->nmStartLine, L_frame ), st->L_frame ),
     414             :                                     tmp8,
     415         662 :                                     hTcxEnc->memQuantZeros,
     416             :                                     lowpassLine );
     417             : 
     418         662 :     IF( LE_32( st->total_brate, ACELP_24k40 ) )
     419             :     {
     420         662 :         lowpassLine = shl( mult( st->hTcxCfg->bandwidth, L_frame ), 1 );
     421             : 
     422         662 :         detectLowpassFac( powerSpec, *powerSpec_e,
     423             :                           L_frame,
     424         662 :                           sub( st->last_core, ACELP_CORE ) == 0,
     425             :                           &hTcxEnc->measuredBwRatio,
     426             :                           lowpassLine );
     427             :     }
     428             :     ELSE
     429             :     {
     430           0 :         hTcxEnc->measuredBwRatio = 0x4000;
     431           0 :         move16();
     432             :     }
     433         662 : }
     434             : 
     435      232556 : void AnalyzePowerSpectrum_ivas_fx(
     436             :     Encoder_State *st,           /* i/o: encoder states                                  */
     437             :     Word16 L_frame,              /* input: frame length                                  */
     438             :     Word16 L_frameTCX,           /* input: full band frame length                        */
     439             :     Word16 left_overlap,         /* input: left overlap length                           */
     440             :     Word16 right_overlap,        /* input: right overlap length                          */
     441             :     Word32 const mdctSpectrum[], /* input: MDCT spectrum                                 */
     442             :     Word16 mdctSpectrum_e,
     443             :     Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */
     444             :     const Word16 q_signal,
     445             :     Word32 powerSpec[], /* output: Power spectrum. Can point to signal          */
     446             :     Word16 powerSpec_e[] )
     447             : {
     448             :     Word16 i, iStart, iEnd, lowpassLine;
     449             :     Word16 shift;
     450             :     Word32 tmp32;
     451             :     Word8 tmp8;
     452      232556 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     453             :     Word32 common_powerSpec[N_MAX + L_MDCT_OVLP_MAX];
     454      232556 :     lowpassLine = L_frameTCX;
     455      232556 :     move16();
     456             : 
     457      232556 :     Word16 temp_powerSpec_e = sub( 16, q_signal );
     458      232556 :     TCX_MDST( signal, powerSpec, &temp_powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
     459             : 
     460      232556 :     shift = L_norm_arr( powerSpec, N_MAX + L_MDCT_OVLP_MAX );
     461      232556 :     scale_sig32( powerSpec, N_MAX + L_MDCT_OVLP_MAX, shift );
     462      232556 :     set16_fx( powerSpec_e, sub( temp_powerSpec_e, shift ), N_MAX + L_MDCT_OVLP_MAX );
     463             : 
     464      232556 :     iStart = 0;
     465      232556 :     move16();
     466      232556 :     iEnd = L_frameTCX;
     467      232556 :     move16();
     468             : 
     469      232556 :     IF( st->narrowBand != 0 )
     470             :     {
     471           0 :         attenuateNbSpectrum_fx( L_frameTCX, powerSpec );
     472             :     }
     473             : 
     474      232556 :     temp_powerSpec_e = MIN16B;
     475      232556 :     move16();
     476             :     /* power spectrum: MDCT^2 + MDST^2 */
     477   215802316 :     FOR( i = iStart; i < iEnd; i++ )
     478             :     {
     479   215569760 :         powerSpec[i] = Mpy_32_32( powerSpec[i], powerSpec[i] );
     480   215569760 :         move32();
     481   215569760 :         shift = norm_l( mdctSpectrum[i] );
     482   215569760 :         tmp32 = L_shl( mdctSpectrum[i], shift );
     483   215569760 :         powerSpec[i] = BASOP_Util_Add_Mant32Exp( powerSpec[i], shl( powerSpec_e[i], 1 ), Mpy_32_32( tmp32, tmp32 ), shl( sub( mdctSpectrum_e, shift ), 1 ), &powerSpec_e[i] );
     484   215569760 :         move32();
     485   215569760 :         IF( LT_16( powerSpec_e[i], -31 ) )
     486             :         {
     487          18 :             powerSpec[i] = L_shl( powerSpec[i], sub( powerSpec_e[i], -31 ) );
     488          18 :             move32();
     489          18 :             powerSpec_e[i] = -31;
     490          18 :             move16();
     491             :         }
     492   215569760 :         temp_powerSpec_e = s_max( temp_powerSpec_e, powerSpec_e[i] );
     493             :     }
     494             : 
     495   376973276 :     FOR( i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ )
     496             :     {
     497   376740720 :         common_powerSpec[i] = L_shl( powerSpec[i], sub( powerSpec_e[i], temp_powerSpec_e ) );
     498   376740720 :         move32();
     499             :     }
     500             : 
     501      232556 :     tmp8 = 0;
     502      232556 :     move16();
     503      232556 :     test();
     504      232556 :     if ( L_msu0( L_mult0( st->L_frame, extract_l( st->last_sr_core ) ), st->L_frame_past, extract_l( st->sr_core ) ) != 0 || NE_16( st->last_core, TCX_20_CORE ) )
     505             :     {
     506       18959 :         tmp8 = 1;
     507       18959 :         move16();
     508             :     }
     509             : 
     510      232556 :     ComputeSpectrumNoiseMeasure_fx( common_powerSpec,
     511             :                                     L_frameTCX,
     512      232556 :                                     divide3216( L_mult( hTcxEnc->nmStartLine, L_frame ), st->L_frame ),
     513             :                                     tmp8,
     514      232556 :                                     hTcxEnc->memQuantZeros,
     515             :                                     lowpassLine );
     516             : 
     517      232556 :     IF( LE_32( st->total_brate, ACELP_24k40 ) )
     518             :     {
     519       87953 :         lowpassLine = shl( mult( st->hTcxCfg->bandwidth, L_frame ), 1 );
     520             : 
     521       87953 :         detectLowpassFac( common_powerSpec, temp_powerSpec_e,
     522             :                           L_frame,
     523       87953 :                           sub( st->last_core, ACELP_CORE ) == 0,
     524             :                           &hTcxEnc->measuredBwRatio,
     525             :                           lowpassLine );
     526             :     }
     527             :     ELSE
     528             :     {
     529      144603 :         hTcxEnc->measuredBwRatio = 0x4000;
     530      144603 :         move16();
     531             :     }
     532      232556 : }
     533             : 
     534      689927 : void AdaptLowFreqEmph_fx( Word32 x[],
     535             :                           Word16 x_e,
     536             :                           Word16 xq[],
     537             :                           Word16 invGain,
     538             :                           Word16 invGain_e,
     539             :                           Word16 tcx_lpc_shaped_ari,
     540             :                           Word16 lpcGains[],
     541             :                           Word16 lpcGains_e[],
     542             :                           const Word16 lg )
     543             : {
     544             :     Word16 i, i_max, i_max_old, lg_4, tmp16, s;
     545             :     Word32 tmp32;
     546             : 
     547             : 
     548      689927 :     IF( tcx_lpc_shaped_ari == 0 )
     549             :     {
     550      672432 :         lg_4 = shr( lg, 2 );
     551             : 
     552             :         /* 1. find first magnitude maximum in lower quarter of spectrum */
     553      672432 :         invGain_e = add( invGain_e, 1 );
     554      672432 :         i_max = -1;
     555      672432 :         move16();
     556             : 
     557     7953070 :         FOR( i = 0; i < lg_4; i++ )
     558             :         {
     559     7929980 :             tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain );            /* multiply */
     560     7929980 :             tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
     561             : 
     562     7929980 :             test();
     563     7929980 :             IF( ( GE_16( abs_s( xq[i] ), 2 ) ) && ( tmp32 >= 0x3A000 ) ) /* 0x3A000 -> 3.625 (15Q16) */
     564             :             {
     565             : 
     566             :                 /* Debug initialization to catch illegal cases of xq[i] */
     567      649342 :                 tmp16 = 0;
     568      649342 :                 move16();
     569             : 
     570      649342 :                 if ( xq[i] > 0 )
     571             :                 {
     572      323027 :                     tmp16 = 2;
     573      323027 :                     move16();
     574             :                 }
     575      649342 :                 if ( xq[i] < 0 )
     576             :                 {
     577      326315 :                     tmp16 = -2;
     578      326315 :                     move16();
     579             :                 }
     580             : 
     581      649342 :                 assert( tmp16 != 0 );
     582             : 
     583      649342 :                 xq[i] = add( xq[i], tmp16 );
     584      649342 :                 move16();
     585             : 
     586      649342 :                 i_max = i;
     587      649342 :                 move16();
     588      649342 :                 BREAK;
     589             :             }
     590             :         }
     591             : 
     592      672432 :         s = sub( add( x_e, invGain_e ), 15 );
     593             : 
     594             :         /* 2. compress value range of all xq up to i_max: add two steps */
     595     3415030 :         FOR( i = 0; i < i_max; i++ )
     596             :         {
     597     2742598 :             xq[i] = quantize( x[i], invGain, s, 0x6000 );
     598     2742598 :             move16();
     599             :         }
     600             : 
     601             :         /* 3. find first mag. maximum below i_max which is half as high */
     602      672432 :         i_max_old = i_max;
     603      672432 :         move16();
     604             : 
     605      672432 :         IF( i_max_old >= 0 )
     606             :         {
     607      649342 :             invGain_e = add( invGain_e, 1 );
     608      649342 :             i_max = -1; /* reset first maximum, update inverse gain */
     609      649342 :             move16();
     610             : 
     611     2249795 :             FOR( i = 0; i < lg_4; i++ )
     612             :             {
     613     2249795 :                 tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain );            /* multiply */
     614     2249795 :                 tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
     615             : 
     616     2249795 :                 test();
     617     2249795 :                 IF( ( GE_16( abs_s( xq[i] ), 2 ) ) && ( tmp32 >= 0x3A000 ) ) /* 0x3A000 -> 3.625 (15Q16) */
     618             :                 {
     619             : 
     620             :                     /* Debug initialization to catch illegal cases of xq[i] */
     621      649342 :                     tmp16 = 0;
     622      649342 :                     move16();
     623             : 
     624      649342 :                     if ( xq[i] > 0 )
     625             :                     {
     626      325067 :                         tmp16 = 2;
     627      325067 :                         move16();
     628             :                     }
     629      649342 :                     if ( xq[i] < 0 )
     630             :                     {
     631      324275 :                         tmp16 = -2;
     632      324275 :                         move16();
     633             :                     }
     634             : 
     635      649342 :                     assert( tmp16 != 0 );
     636             : 
     637      649342 :                     xq[i] = add( xq[i], tmp16 );
     638      649342 :                     move16();
     639             : 
     640      649342 :                     i_max = i;
     641      649342 :                     move16();
     642      649342 :                     BREAK;
     643             :                 }
     644             :             }
     645             :         }
     646             : 
     647      672432 :         s = sub( add( x_e, invGain_e ), 15 );
     648             : 
     649             :         /* 4. re-compress and quantize all xq up to half-height i_max+1 */
     650     2272885 :         FOR( i = 0; i < i_max; i++ )
     651             :         {
     652     1600453 :             xq[i] = quantize( x[i], invGain, s, 0x6000 );
     653     1600453 :             move16();
     654             :         }
     655             : 
     656             :         /* 5. always compress 2 lines; lines could be at index 0 and 1! */
     657      672432 :         IF( i_max_old >= 0 )
     658             :         {
     659      649342 :             invGain_e = sub( invGain_e, 1 ); /* reset inverse gain */
     660      649342 :             if ( LT_16( i_max, i_max_old ) )
     661             :             {
     662      278104 :                 i_max = i_max_old;
     663      278104 :                 move16();
     664             :             }
     665             :         }
     666             : 
     667      672432 :         i = add( i_max, 1 );
     668             : 
     669      672432 :         tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain );            /* multiply */
     670      672432 :         tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
     671      672432 :         IF( GE_32( tmp32, 0x3A000 ) )
     672             :         {
     673             : 
     674             :             /* Debug initialization to catch illegal cases of xq[i] */
     675      385021 :             tmp16 = 0;
     676      385021 :             move16();
     677             : 
     678      385021 :             if ( xq[i] > 0 )
     679             :             {
     680      194891 :                 tmp16 = 2;
     681      194891 :                 move16();
     682             :             }
     683      385021 :             if ( xq[i] < 0 )
     684             :             {
     685      190130 :                 tmp16 = -2;
     686      190130 :                 move16();
     687             :             }
     688             : 
     689      385021 :             assert( tmp16 != 0 );
     690             : 
     691      385021 :             xq[i] = add( xq[i], tmp16 );
     692      385021 :             move16();
     693             :         }
     694             :         ELSE
     695             :         {
     696      287411 :             xq[i] = quantize( x[i], invGain, sub( add( x_e, invGain_e ), 15 ), 0x6000 );
     697      287411 :             move16();
     698             :         }
     699             : 
     700      672432 :         i = add( i, 1 );
     701             : 
     702      672432 :         tmp32 = Mpy_32_16_1( L_abs( x[i] ), invGain );            /* multiply */
     703      672432 :         tmp32 = L_shl( tmp32, sub( add( x_e, invGain_e ), 15 ) ); /* convert to 15Q16 */
     704      672432 :         IF( GE_32( tmp32, 0x3A000 ) )
     705             :         {
     706             : 
     707             :             /* Debug initialization to catch illegal cases of xq[i] */
     708      342159 :             tmp16 = 0;
     709      342159 :             move16();
     710             : 
     711      342159 :             if ( xq[i] > 0 )
     712             :             {
     713      171253 :                 tmp16 = 2;
     714      171253 :                 move16();
     715             :             }
     716      342159 :             if ( xq[i] < 0 )
     717             :             {
     718      170906 :                 tmp16 = -2;
     719      170906 :                 move16();
     720             :             }
     721             : 
     722      342159 :             assert( tmp16 != 0 );
     723             : 
     724      342159 :             xq[i] = add( xq[i], tmp16 );
     725      342159 :             move16();
     726             :         }
     727             :         ELSE
     728             :         {
     729      330273 :             xq[i] = quantize( x[i], invGain, sub( add( x_e, invGain_e ), 15 ), 0x6000 );
     730      330273 :             move16();
     731             :         }
     732             :     }
     733             :     ELSE /*if(!tcx_lpc_shaped_ari)*/
     734             :     {
     735       17495 :         PsychAdaptLowFreqEmph_fx( x, lpcGains, lpcGains_e );
     736             :     } /*if(!tcx_lpc_shaped_ari)*/
     737      689927 : }
     738             : 
     739       21221 : void PsychAdaptLowFreqEmph_fx( Word32 x[],
     740             :                                const Word16 lpcGains[],
     741             :                                const Word16 lpcGains_e[] )
     742             : {
     743             :     Word16 i;
     744             :     Word16 max, max_e, fac, min, min_e, tmp, tmp_e;
     745             :     Word32 L_tmp;
     746             : 
     747             : 
     748       21221 :     assert( lpcGains[0] >= 0x4000 );
     749             : 
     750       21221 :     max = lpcGains[0];
     751       21221 :     move16();
     752       21221 :     max_e = lpcGains_e[0];
     753       21221 :     move16();
     754       21221 :     min = lpcGains[0];
     755       21221 :     move16();
     756       21221 :     min_e = lpcGains_e[0];
     757       21221 :     move16();
     758             : 
     759             :     /* find minimum (min) and maximum (max) of LPC gains in low frequencies */
     760      190989 :     FOR( i = 1; i < 9; i++ )
     761             :     {
     762      169768 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min, min_e ) < 0 )
     763             :         {
     764      127714 :             min = lpcGains[i];
     765      127714 :             move16();
     766      127714 :             min_e = lpcGains_e[i];
     767      127714 :             move16();
     768             :         }
     769             : 
     770      169768 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max, max_e ) > 0 )
     771             :         {
     772       29705 :             max = lpcGains[i];
     773       29705 :             move16();
     774       29705 :             max_e = lpcGains_e[i];
     775       29705 :             move16();
     776             :         }
     777             :     }
     778             : 
     779       21221 :     min_e = add( min_e, 5 ); /* min *= 32.0f; */
     780             : 
     781       21221 :     test();
     782       21221 :     IF( ( compMantExp16Unorm( max, max_e, min, min_e ) < 0 ) && ( max > 0 ) )
     783             :     {
     784             :         /* fac = tmp = (float)pow(min / max, 0.0078125f); */
     785       21221 :         tmp_e = max_e;
     786       21221 :         move16();
     787       21221 :         tmp = Inv16( max, &tmp_e );
     788       21221 :         L_tmp = L_shl( L_mult( tmp, min ), sub( add( tmp_e, min_e ), 6 ) ); /* Q25 */
     789       21221 :         L_tmp = L_add( BASOP_Util_Log2( L_tmp ), 6 << 25 );                 /* Q25 */
     790       21221 :         L_tmp = L_shr( L_tmp, 7 );                                          /* 0.0078125f = 1.f/(1<<7) */
     791       21221 :         L_tmp = BASOP_Util_InvLog2( L_sub( L_tmp, 1 << 25 ) );              /* Q30 */
     792       21221 :         tmp = round_fx( L_tmp );                                            /* Q14 */
     793       21221 :         fac = shr( tmp, 1 );                                                /* Q13 */
     794             : 
     795             :         /* gradual boosting of lowest 32 bins; DC is boosted by (min/max)^1/4 */
     796      700293 :         FOR( i = 31; i >= 0; i-- )
     797             :         {
     798      679072 :             x[i] = L_shl( Mpy_32_16_1( x[i], fac ), 2 );
     799      679072 :             move32();
     800      679072 :             fac = shl( mult_r( fac, tmp ), 1 );
     801             :         }
     802             :     }
     803       21221 : }
     804             : 
     805         662 : Word16 SQ_gain_fx(                  /* output: SQ gain                   */
     806             :                    Word32 x[],      /* input:  vector to quantize        */
     807             :                    Word16 x_e,      /* input:  exponent                  */
     808             :                    Word16 nbitsSQ,  /* input:  number of bits targeted   */
     809             :                    Word16 lg,       /* input:  vector size (2048 max)    */
     810             :                    Word16 *gain_e ) /* output: SQ gain exponent          */
     811             : {
     812             :     Word16 i, iter, lg_4, s, tmp16;
     813             :     Word32 ener, tmp32;
     814             :     Word32 target, fac, offset;
     815             :     Word32 en[N_MAX / 4];
     816             : 
     817             : 
     818         662 :     lg_4 = shr( lg, 2 );
     819             : 
     820             :     /* energy of quadruples with 9dB offset */
     821      108142 :     FOR( i = 0; i < lg_4; i++ )
     822             :     {
     823             :         /* normalization */
     824      107480 :         s = 15;
     825      107480 :         move16();
     826             : 
     827      107480 :         tmp16 = norm_l( x[0] );
     828      107480 :         IF( x[0] != 0 )
     829             :         {
     830       42979 :             s = s_min( s, tmp16 );
     831             :         }
     832             : 
     833      107480 :         tmp16 = norm_l( x[1] );
     834      107480 :         IF( x[1] != 0 )
     835             :         {
     836       42974 :             s = s_min( s, tmp16 );
     837             :         }
     838             : 
     839      107480 :         tmp16 = norm_l( x[2] );
     840      107480 :         IF( x[2] != 0 )
     841             :         {
     842       42977 :             s = s_min( s, tmp16 );
     843             :         }
     844      107480 :         tmp16 = norm_l( x[3] );
     845      107480 :         IF( x[3] != 0 )
     846             :         {
     847       42976 :             s = s_min( s, tmp16 );
     848             :         }
     849             : 
     850      107480 :         s = sub( s, 2 ); /* 2 bits headroom */
     851             : 
     852             :         /* calc quadruple energy */
     853      107480 :         ener = L_deposit_l( 1 );
     854             : 
     855      107480 :         tmp16 = extract_h( L_shl( x[0], s ) );
     856      107480 :         ener = L_mac( ener, tmp16, tmp16 );
     857             : 
     858      107480 :         tmp16 = extract_h( L_shl( x[1], s ) );
     859      107480 :         ener = L_mac( ener, tmp16, tmp16 );
     860             : 
     861      107480 :         tmp16 = extract_h( L_shl( x[2], s ) );
     862      107480 :         ener = L_mac( ener, tmp16, tmp16 );
     863             : 
     864      107480 :         tmp16 = extract_h( L_shl( x[3], s ) );
     865      107480 :         ener = L_mac( ener, tmp16, tmp16 );
     866             : 
     867      107480 :         s = shl( sub( x_e, s ), 1 );
     868             : 
     869             :         /* log */
     870      107480 :         tmp32 = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */
     871      107480 :         en[i] = L_shr( tmp32, 9 );                                               /* 15Q16 */
     872      107480 :         move32();
     873      107480 :         x += 4;
     874             :     }
     875             : 
     876             :     /* SQ scale: 4 bits / 6 dB per quadruple */
     877         662 :     target = L_mult( 0x3FC8, sub( nbitsSQ, shr( lg, 4 ) ) ); /* 0x3FC8 -> 0.15*log2(10) */
     878         662 :     fac = L_add( 0x2A854B, 0 );                              /* -> 12.8f*log2(10); */
     879         662 :     offset = L_add( fac, 0 );
     880             : 
     881             :     /* find offset (0 to 128 dB with step of 0.125dB) */
     882        7282 :     FOR( iter = 0; iter < 10; iter++ )
     883             :     {
     884        6620 :         fac = L_shr( fac, 1 );
     885        6620 :         offset = L_sub( offset, fac );
     886        6620 :         ener = L_deposit_l( 0 );
     887             : 
     888      789694 :         FOR( i = 0; i < lg_4; i++ )
     889             :         {
     890      785624 :             tmp32 = L_sub( en[i], offset );
     891             : 
     892             :             /* avoid SV with 1 bin of amp < 0.5f */
     893      785624 :             IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */
     894             :             {
     895      197222 :                 ener = L_add( ener, tmp32 );
     896             :             }
     897             : 
     898             :             /* if ener is above target -> break and increase offset */
     899      785624 :             IF( GT_32( ener, target ) )
     900             :             {
     901        2550 :                 offset = L_add( offset, fac );
     902        2550 :                 BREAK;
     903             :             }
     904             :         }
     905             :     }
     906             : 
     907         662 :     offset = L_add( L_shr( offset, 1 ), 0x17EB0 ); /* 0x17EB0 -> 0.45*log2(10) */
     908             : 
     909         662 :     *gain_e = add( extract_h( offset ), 1 );
     910         662 :     move16();
     911         662 :     offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 );
     912         662 :     tmp16 = extract_h( BASOP_Util_InvLog2( L_shl( offset, 9 ) ) );
     913             : 
     914             :     /* return gain */
     915             : 
     916         662 :     return tmp16;
     917             : }
     918             : 
     919      220343 : Word16 SQ_gain_ivas_fx(                  /* output: SQ gain                   */
     920             :                         Word32 x[],      /* input:  vector to quantize        */
     921             :                         Word16 x_e,      /* input:  exponent                  */
     922             :                         Word16 nbitsSQ,  /* input:  number of bits targeted   */
     923             :                         Word16 lg,       /* input:  vector size (2048 max)    */
     924             :                         Word16 *gain_e ) /* output: SQ gain exponent          */
     925             : {
     926             :     Word16 i, iter, lg_4, s, tmp16;
     927             :     Word32 ener, tmp32;
     928             :     Word32 target, fac, offset;
     929             :     Word32 en[N_MAX / 4];
     930             : 
     931             : 
     932      220343 :     lg_4 = shr( lg, 2 );
     933             : 
     934             :     /* energy of quadruples with 9dB offset */
     935    47123123 :     FOR( i = 0; i < lg_4; i++ )
     936             :     {
     937             :         /* normalization */
     938    46902780 :         s = 15;
     939    46902780 :         move16();
     940             : 
     941    46902780 :         tmp16 = norm_l( x[0] );
     942    46902780 :         IF( x[0] != 0 )
     943             :         {
     944    22256162 :             s = s_min( s, tmp16 );
     945             :         }
     946             : 
     947    46902780 :         tmp16 = norm_l( x[1] );
     948    46902780 :         IF( x[1] != 0 )
     949             :         {
     950    22256303 :             s = s_min( s, tmp16 );
     951             :         }
     952             : 
     953    46902780 :         tmp16 = norm_l( x[2] );
     954    46902780 :         IF( x[2] != 0 )
     955             :         {
     956    22254789 :             s = s_min( s, tmp16 );
     957             :         }
     958             : 
     959    46902780 :         tmp16 = norm_l( x[3] );
     960    46902780 :         IF( x[3] != 0 )
     961             :         {
     962    22254923 :             s = s_min( s, tmp16 );
     963             :         }
     964             : 
     965    46902780 :         s = sub( s, 2 ); /* 2 bits headroom */
     966             : 
     967             :         /* calc quadruple energy */
     968    46902780 :         ener = L_deposit_l( 1 );
     969             : 
     970    46902780 :         tmp16 = extract_h( L_shl( x[0], s ) );
     971    46902780 :         ener = L_mac( ener, tmp16, tmp16 );
     972             : 
     973    46902780 :         tmp16 = extract_h( L_shl( x[1], s ) );
     974    46902780 :         ener = L_mac( ener, tmp16, tmp16 );
     975             : 
     976    46902780 :         tmp16 = extract_h( L_shl( x[2], s ) );
     977    46902780 :         ener = L_mac( ener, tmp16, tmp16 );
     978             : 
     979    46902780 :         tmp16 = extract_h( L_shl( x[3], s ) );
     980    46902780 :         ener = L_mac( ener, tmp16, tmp16 );
     981             : 
     982    46902780 :         s = shl( sub( x_e, s ), 1 );
     983             : 
     984             :         /* log */
     985    46902780 :         IF( EQ_32( ener, 1 ) )
     986             :         {
     987    24645065 :             en[i] = -131072; /* log10(0.01) in Q16 */
     988    24645065 :             move32();
     989             :         }
     990             :         ELSE
     991             :         {
     992    22257715 :             tmp32 = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */
     993    22257715 :             en[i] = L_shr( tmp32, 9 );                                               /* 15Q16 */
     994    22257715 :             move32();
     995             :         }
     996    46902780 :         x += 4;
     997             :     }
     998             : 
     999             :     /* SQ scale: 4 bits / 6 dB per quadruple */
    1000      220343 :     target = L_mult( 0x3FC8, sub( nbitsSQ, shr( lg, 4 ) ) ); /* 0x3FC8 -> 0.15*log2(10) */
    1001      220343 :     fac = L_add( 0x2A854B, 0 );                              /* -> 12.8f*log2(10); */
    1002      220343 :     offset = L_add( fac, 0 );
    1003             : 
    1004             :     /* find offset (0 to 128 dB with step of 0.125dB) */
    1005     2423773 :     FOR( iter = 0; iter < 10; iter++ )
    1006             :     {
    1007     2203430 :         fac = L_shr( fac, 1 );
    1008     2203430 :         offset = L_sub( offset, fac );
    1009     2203430 :         ener = L_deposit_l( 0 );
    1010             : 
    1011   361256353 :         FOR( i = 0; i < lg_4; i++ )
    1012             :         {
    1013   359873486 :             tmp32 = L_sub( en[i], offset );
    1014             : 
    1015             :             /* avoid SV with 1 bin of amp < 0.5f */
    1016   359873486 :             IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */
    1017             :             {
    1018   135595812 :                 ener = L_add( ener, tmp32 );
    1019             :             }
    1020             : 
    1021             :             /* if ener is above target -> break and increase offset */
    1022   359873486 :             IF( GT_32( ener, target ) )
    1023             :             {
    1024      820563 :                 offset = L_add( offset, fac );
    1025      820563 :                 BREAK;
    1026             :             }
    1027             :         }
    1028             :     }
    1029             : 
    1030      220343 :     offset = L_add( L_shr( offset, 1 ), 0x17EB0 ); /* 0x17EB0 -> 0.45*log2(10) */
    1031             : 
    1032      220343 :     *gain_e = add( extract_h( offset ), 1 );
    1033      220343 :     move16();
    1034      220343 :     offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 );
    1035      220343 :     tmp16 = extract_h( BASOP_Util_InvLog2( L_shl( offset, 9 ) ) );
    1036             : 
    1037             :     /* return gain */
    1038             : 
    1039      220343 :     return tmp16;
    1040             : }
    1041             : 
    1042      623603 : Word16 SQ_gain_estimate_fx(                  /* output: SQ gain                   */
    1043             :                             Word32 x[],      /* input:  vector to quantize        */
    1044             :                             Word16 x_e,      /* input:  exponent                  */
    1045             :                             Word16 nbitsSQ,  /* input:  number of bits targeted   */
    1046             :                             Word16 lg,       /* input:  vector size (2048 max)    */
    1047             :                             Word16 *gain_e ) /* output: SQ gain exponent          */
    1048             : {
    1049             :     Word16 i, iter, max_iter, lg_4, s, tmp16;
    1050             :     Word32 ener, tmp32;
    1051             :     Word32 target, fac, offset;
    1052             :     Word32 en[N_MAX / 4];
    1053      623603 :     Word32 tmp = 0, tmpp = 0;
    1054      623603 :     move32();
    1055      623603 :     move32();
    1056             : 
    1057             :     /* tmp =  0.5f * (float) log10( (float) lg / (float) NORM_MDCT_FACTOR ) + + 0.94f; lowest gain + expected value of the quantization noise energy per quadruple (log10(4/12)) in Q16*/
    1058             :     /* tmpp =  0.5f * (float) log10( (float) lg / (float) NORM_MDCT_FACTOR ) * log2(10) in Q16 */
    1059      623603 :     SWITCH( lg )
    1060             :     {
    1061           0 :         case 80:
    1062           0 :             tmp = 171876;
    1063           0 :             tmpp = -32768;
    1064           0 :             move32();
    1065           0 :             move32();
    1066           0 :             BREAK;
    1067           0 :         case 100:
    1068           0 :             tmp = 182424;
    1069           0 :             tmpp = -22219;
    1070           0 :             move32();
    1071           0 :             move32();
    1072           0 :             BREAK;
    1073        2112 :         case 160:
    1074        2112 :             tmp = 204644;
    1075        2112 :             tmpp = 0;
    1076        2112 :             move32();
    1077        2112 :             move32();
    1078        2112 :             BREAK;
    1079           0 :         case 200:
    1080           0 :             tmp = 215192;
    1081           0 :             tmpp = 10549;
    1082           0 :             move32();
    1083           0 :             move32();
    1084           0 :             BREAK;
    1085           0 :         case 240:
    1086           0 :             tmp = 223812;
    1087           0 :             tmpp = 19168;
    1088           0 :             move32();
    1089           0 :             move32();
    1090           0 :             BREAK;
    1091           0 :         case 300:
    1092           0 :             tmp = 234361;
    1093           0 :             tmpp = 29717;
    1094           0 :             move32();
    1095           0 :             move32();
    1096           0 :             BREAK;
    1097       61010 :         case 320:
    1098       61010 :             tmp = 237412;
    1099       61010 :             tmpp = 32768;
    1100       61010 :             move32();
    1101       61010 :             move32();
    1102       61010 :             BREAK;
    1103          54 :         case 400:
    1104          54 :             tmp = 247960;
    1105          54 :             tmpp = 43317;
    1106          54 :             move32();
    1107          54 :             move32();
    1108          54 :             BREAK;
    1109       18088 :         case 480:
    1110       18088 :             tmp = 256580;
    1111       18088 :             tmpp = 51936;
    1112       18088 :             move32();
    1113       18088 :             move32();
    1114       18088 :             BREAK;
    1115           0 :         case 600:
    1116           0 :             tmp = 267128;
    1117           0 :             tmpp = 62485;
    1118           0 :             move32();
    1119           0 :             move32();
    1120           0 :             BREAK;
    1121      155892 :         case 640:
    1122      155892 :             tmp = 270180;
    1123      155892 :             tmpp = 65536;
    1124      155892 :             move32();
    1125      155892 :             move32();
    1126      155892 :             BREAK;
    1127         288 :         case 800:
    1128         288 :             tmp = 280728;
    1129         288 :             tmpp = 76085;
    1130         288 :             move32();
    1131         288 :             move32();
    1132         288 :             BREAK;
    1133      385143 :         case 960:
    1134      385143 :             tmp = 289348;
    1135      385143 :             tmpp = 84704;
    1136      385143 :             move32();
    1137      385143 :             move32();
    1138      385143 :             BREAK;
    1139        1016 :         case 1200:
    1140        1016 :             tmp = 299896;
    1141        1016 :             tmpp = 95253;
    1142        1016 :             move32();
    1143        1016 :             move32();
    1144        1016 :             BREAK;
    1145           0 :         case 1440:
    1146           0 :             tmp = 308516;
    1147           0 :             tmpp = 103872;
    1148           0 :             move32();
    1149           0 :             move32();
    1150           0 :             BREAK;
    1151           0 :         case 1800:
    1152           0 :             tmp = 319064;
    1153           0 :             tmpp = 114422;
    1154           0 :             move32();
    1155           0 :             move32();
    1156           0 :             BREAK;
    1157           0 :         case 2048:
    1158           0 :             tmp = 325167;
    1159           0 :             tmpp = 120523;
    1160           0 :             move32();
    1161           0 :             move32();
    1162           0 :             BREAK;
    1163           0 :         default:
    1164           0 :             assert( 0 );
    1165             :     }
    1166             : 
    1167      623603 :     lg_4 = shr( lg, 2 );
    1168             : 
    1169             :     /* SNR of quadruples for unit step quantizer and lowest possible gain */
    1170   125504283 :     FOR( i = 0; i < lg_4; i++ )
    1171             :     {
    1172             :         /* normalization */
    1173   124880680 :         s = 15;
    1174   124880680 :         move16();
    1175             : 
    1176   124880680 :         tmp16 = norm_l( x[0] );
    1177   124880680 :         IF( x[0] != 0 )
    1178             :         {
    1179    91021773 :             s = s_min( s, tmp16 );
    1180             :         }
    1181             : 
    1182   124880680 :         tmp16 = norm_l( x[1] );
    1183   124880680 :         IF( x[1] != 0 )
    1184             :         {
    1185    91022285 :             s = s_min( s, tmp16 );
    1186             :         }
    1187             : 
    1188   124880680 :         tmp16 = norm_l( x[2] );
    1189   124880680 :         IF( x[2] != 0 )
    1190             :         {
    1191    91021552 :             s = s_min( s, tmp16 );
    1192             :         }
    1193             : 
    1194   124880680 :         tmp16 = norm_l( x[3] );
    1195   124880680 :         IF( x[3] != 0 )
    1196             :         {
    1197    91021921 :             s = s_min( s, tmp16 );
    1198             :         }
    1199             : 
    1200   124880680 :         s = sub( s, 2 ); /* 2 bits headroom */
    1201             : 
    1202             :         /* calc quadruple energy */
    1203   124880680 :         ener = L_deposit_l( 1 );
    1204             : 
    1205   124880680 :         tmp16 = extract_h( L_shl( x[0], s ) );
    1206   124880680 :         ener = L_mac( ener, tmp16, tmp16 );
    1207             : 
    1208   124880680 :         tmp16 = extract_h( L_shl( x[1], s ) );
    1209   124880680 :         ener = L_mac( ener, tmp16, tmp16 );
    1210             : 
    1211   124880680 :         tmp16 = extract_h( L_shl( x[2], s ) );
    1212   124880680 :         ener = L_mac( ener, tmp16, tmp16 );
    1213             : 
    1214   124880680 :         tmp16 = extract_h( L_shl( x[3], s ) );
    1215   124880680 :         ener = L_mac( ener, tmp16, tmp16 );
    1216             : 
    1217   124880680 :         s = shl( sub( x_e, s ), 1 );
    1218             : 
    1219             :         /* log */
    1220   124880680 :         tmp32 = L_add_sat( BASOP_Util_Log2( ener ), L_shl_sat( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */
    1221   124880680 :         en[i] = L_add_sat( L_shr( tmp32, 9 ), tmp );                                     /* 15Q16 */
    1222   124880680 :         move32();
    1223   124880680 :         x += 4;
    1224             :     }
    1225             : 
    1226             :     /* SQ scale: 4 bits / 6 dB per quadruple */
    1227      623603 :     target = L_mult( 0x3FC8, sub( nbitsSQ, shr( lg, 4 ) ) ); /* 0x3FC8 -> 0.15*log2(10) */
    1228      623603 :     fac = L_add( 4005789, 0 );                               /* -> 18.4f*log2(10); */
    1229      623603 :     offset = 3997967;                                        /*fac - fac / (float) ( 2 << max_iter )*/
    1230      623603 :     move32();
    1231      623603 :     max_iter = 8;
    1232      623603 :     move16();
    1233             :     /* find offset, resolution similar to SQ gain quantizer resolution (92dB range, 0.719db resolution) */
    1234     5612427 :     FOR( iter = 0; iter < max_iter; iter++ )
    1235             :     {
    1236     4988824 :         fac = L_shr( fac, 1 );
    1237     4988824 :         offset = L_sub( offset, fac );
    1238     4988824 :         ener = L_deposit_l( 0 );
    1239             : 
    1240   744940567 :         FOR( i = 0; i < lg_4; i++ )
    1241             :         {
    1242   742004108 :             tmp32 = L_sub( en[i], offset );
    1243             : 
    1244             :             /* avoid SV with 1 bin of amp < 0.5f */
    1245   742004108 :             IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */
    1246             :             {
    1247   273401928 :                 ener = L_add( ener, tmp32 );
    1248             :             }
    1249             : 
    1250             :             /* if SNR is above target -> break and increase offset */
    1251   742004108 :             IF( GT_32( ener, target ) )
    1252             :             {
    1253     2052365 :                 offset = L_add( offset, fac );
    1254     2052365 :                 BREAK;
    1255             :             }
    1256             :         }
    1257             :     }
    1258             : 
    1259      623603 :     offset = L_sub( L_shr( offset, 1 ), tmpp ); /* tmpp -> minGainInv*log2(10) */
    1260      623603 :     *gain_e = add( extract_h( offset ), 1 );
    1261      623603 :     move16();
    1262      623603 :     offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 );
    1263      623603 :     tmp16 = extract_h( BASOP_Util_InvLog2( L_shl( offset, 9 ) ) );
    1264             : 
    1265             :     /* return gain */
    1266             : 
    1267      623603 :     return tmp16;
    1268             : }
    1269             : 
    1270        3972 : void tcx_scalar_quantization_fx(
    1271             :     Word32 *x,                     /* i: input coefficients            */
    1272             :     Word16 x_e,                    /* i: exponent                      */
    1273             :     Word16 *xq,                    /* o: quantized coefficients        */
    1274             :     Word16 L_frame,                /* i: frame length                  */
    1275             :     Word16 gain,                   /* i: quantization gain             */
    1276             :     Word16 gain_e,                 /* i: quantization gain exponent    */
    1277             :     Word16 offset,                 /* i: rounding offset (deadzone)    */
    1278             :     Word8 const *memQuantZeros_fx, /* i: coefficients to be set to 0   */
    1279             :     const Word16 alfe_flag )
    1280             : {
    1281             :     Word16 i, tmp16, s;
    1282             :     Word32 tmp32, offs32;
    1283             : 
    1284             : 
    1285             :     /* common exponent for x and gain for comparison */
    1286        3972 :     tmp16 = sub( gain_e, x_e );
    1287        3972 :     tmp32 = L_shl( L_deposit_h( gain ), s_max( -31, s_min( tmp16, 0 ) ) );
    1288        3972 :     tmp16 = negate( s_max( tmp16, 0 ) );
    1289             : 
    1290        3972 :     i = sub( L_frame, 1 );
    1291             : 
    1292        3972 :     test();
    1293     1326437 :     WHILE( ( memQuantZeros_fx[i] != 0 ) && ( LT_32( L_abs( L_shl( x[i], tmp16 ) ), tmp32 ) ) )
    1294             :     {
    1295     1322465 :         test();
    1296     1322465 :         xq[i] = 0;
    1297     1322465 :         move16();
    1298     1322465 :         i = sub( i, 1 );
    1299             :     }
    1300             : 
    1301             :     /* invert gain */
    1302        3972 :     gain = Inv16( gain, &gain_e );
    1303             : 
    1304        3972 :     s = sub( add( x_e, gain_e ), 15 );
    1305             : 
    1306             :     /*It should almost never happen and if so the quantization will be discarded later on (saturation of gain Quantizer).*/
    1307        3972 :     IF( GT_16( s, 31 ) )
    1308             :     {
    1309             :         /* Limit the inverse gain to maximal possible value=sqrtL_spec/NORM_MDCT_FACTOR)*/
    1310           0 :         gain = 22435; /*sqrt(1200/NORM_MDCT_FACTOR) in 2Q13*/
    1311           0 :         gain_e = 2;
    1312           0 :         move16();
    1313           0 :         move16();
    1314             : 
    1315           0 :         s = sub( add( x_e, gain_e ), 15 );
    1316             :     }
    1317             : 
    1318             :     /* substract 0x8000 to affect the mac_r in the following loop
    1319             :        so it acts like extract_h. the 0x4000 will be multiplied by 2
    1320             :        by the mac_r to get to 0x8000 and disable the round. */
    1321        3972 :     offset = sub( offset, 0x4000 );
    1322             : 
    1323     1261027 :     FOR( ; i >= 0; i-- )
    1324             :     {
    1325     1257055 :         offs32 = Mpy_32_16_1( L_abs( x[i] ), gain ); /* multiply */
    1326     1257055 :         offs32 = L_shl_sat( offs32, s );             /* convert to 15Q16 */
    1327     1257055 :         tmp16 = mac_r_sat( offs32, offset, 1 );      /* add offset and truncate */
    1328     1257055 :         IF( x[i] < 0 )
    1329             :         {
    1330      454857 :             tmp16 = negate( tmp16 ); /* restore sign */
    1331             :         }
    1332             : 
    1333     1257055 :         xq[i] = tmp16;
    1334     1257055 :         move16();
    1335             :     }
    1336             : 
    1337        3972 :     IF( alfe_flag == 0 )
    1338             :     {
    1339        3972 :         AdaptLowFreqEmph_fx( x, x_e, xq, gain, gain_e,
    1340             :                              0, NULL, NULL,
    1341             :                              L_frame );
    1342             :     }
    1343        3972 : }
    1344             : 
    1345     4365316 : void tcx_scalar_quantization_ivas_fx(
    1346             :     Word32 *x,                     /* i: input coefficients            exponent = x_e */
    1347             :     Word16 x_e,                    /* i: exponent                      */
    1348             :     Word16 *xq,                    /* o: quantized coefficients        */
    1349             :     Word16 L_frame,                /* i: frame length                  */
    1350             :     Word16 gain,                   /* i: quantization gain            exponent = gain_e */
    1351             :     Word16 gain_e,                 /* i: quantization gain exponent    */
    1352             :     Word16 offset,                 /* i: rounding offset (deadzone)    */
    1353             :     Word8 const *memQuantZeros_fx, /* i: coefficients to be set to 0   */
    1354             :     const Word16 alfe_flag )
    1355             : {
    1356             :     Word16 i, tmp16, s;
    1357             :     Word32 tmp32, offs32;
    1358             : 
    1359             : 
    1360             :     /* common exponent for x and gain for comparison */
    1361     4365316 :     tmp16 = sub( gain_e, x_e );
    1362     4365316 :     tmp32 = L_shl( L_deposit_h( gain ), s_max( -31, s_min( tmp16, 0 ) ) );
    1363     4365316 :     tmp16 = negate( s_max( tmp16, 0 ) );
    1364             : 
    1365     4365316 :     i = sub( L_frame, 1 );
    1366     4365316 :     IF( memQuantZeros_fx != NULL )
    1367             :     {
    1368     3812208 :         test();
    1369  1081299391 :         WHILE( ( memQuantZeros_fx[i] != 0 ) && ( LT_32( L_abs( L_shl( x[i], tmp16 ) ), tmp32 ) ) )
    1370             :         {
    1371  1077487183 :             test();
    1372  1077487183 :             xq[i] = 0;
    1373  1077487183 :             move16();
    1374  1077487183 :             i = sub( i, 1 );
    1375             :         }
    1376             :     }
    1377             : 
    1378             :     /* invert gain */
    1379     4365316 :     gain = Inv16( gain, &gain_e );
    1380             : 
    1381     4365316 :     s = sub( add( x_e, gain_e ), 15 );
    1382             : 
    1383             :     /*It should almost never happen and if so the quantization will be discarded later on (saturation of gain Quantizer).*/
    1384     4365316 :     IF( GT_16( s, 31 ) )
    1385             :     {
    1386             :         /* Limit the inverse gain to maximal possible value=sqrtL_spec/NORM_MDCT_FACTOR)*/
    1387           0 :         gain = 22435; /*sqrt(1200/NORM_MDCT_FACTOR) in 2Q13*/
    1388           0 :         move16();
    1389           0 :         gain_e = 2;
    1390           0 :         move16();
    1391             : 
    1392           0 :         s = sub( add( x_e, gain_e ), 15 );
    1393             :     }
    1394             : 
    1395             :     /* substract 0x8000 to affect the mac_r in the following loop
    1396             :     so it acts like extract_h. the 0x4000 will be multiplied by 2
    1397             :     by the mac_r to get to 0x8000 and disable the round. */
    1398     4365316 :     offset = sub( offset, 0x4000 );
    1399             : 
    1400  2365291957 :     FOR( ; i >= 0; i-- )
    1401             :     {
    1402  2360926641 :         offs32 = Mpy_32_16_1( L_abs( x[i] ), gain ); /* multiply */
    1403  2360926641 :         offs32 = L_shl_sat( offs32, s );             /* convert to 15Q16 */
    1404  2360926641 :         tmp16 = mac_r_sat( offs32, offset, 1 );      /* add offset and truncate */
    1405  2360926641 :         IF( x[i] < 0 )
    1406             :         {
    1407  1077618772 :             tmp16 = negate( tmp16 ); /* restore sign */
    1408             :         }
    1409             : 
    1410  2360926641 :         xq[i] = tmp16;
    1411  2360926641 :         move16();
    1412             :     }
    1413             : 
    1414     4365316 :     IF( alfe_flag == 0 )
    1415             :     {
    1416      668460 :         AdaptLowFreqEmph_fx( x, x_e, xq, gain, gain_e,
    1417             :                              0, NULL, NULL,
    1418             :                              L_frame );
    1419             :     }
    1420     4365316 : }
    1421             : 
    1422         662 : Word16 tcx_scalar_quantization_rateloop_fx(
    1423             :     Word32 *x,                     /* i  : input coefficients            */
    1424             :     Word16 x_e,                    /* i  : exponent                      */
    1425             :     Word16 *xq,                    /* o  : quantized coefficients        */
    1426             :     Word16 L_frame,                /* i  : frame length                  */
    1427             :     Word16 *gain,                  /* i/o: quantization gain             */
    1428             :     Word16 *gain_e,                /* i/o: gain exponent                 */
    1429             :     Word16 offset,                 /* i  : rounding offset (deadzone)    */
    1430             :     Word8 const *memQuantZeros_fx, /* i  : coefficients to be set to 0   */
    1431             :     Word16 *lastnz_out,            /* i/o: last nonzero coeff index      */
    1432             :     Word16 target,                 /* i  : target number of bits         */
    1433             :     Word16 *nEncoded,              /* o  : number of encoded coeff       */
    1434             :     Word16 *stop,                  /* i/o: stop param                    */
    1435             :     Word16 sqBits_in_noStop,       /* i  : number of sqBits as determined in prev. quant. stage, w/o using stop mechanism (ie might exceed target bits) */
    1436             :     Word16 sqBits_in,              /* i  : number of sqBits as determined in prev. quant. stage, using stop mechanism (ie always <= target bits) */
    1437             :     Word16 tcxRateLoopOpt,         /* i  : turns on/off rateloop optimization */
    1438             :     const Word8 tcxonly,
    1439             :     CONTEXT_HM_CONFIG *hm_cfg /* i  : configuration of the context-based harmonic model */
    1440             : )
    1441             : {
    1442         662 :     const Word16 iter_max = 4;
    1443             :     Word16 sqBits;
    1444             :     Word16 stopFlag;
    1445             :     Word8 ubfound, lbfound;
    1446             :     Word16 ub, ub_e, lb, lb_e;
    1447             :     Word16 shift, shiftInv;
    1448             :     Word16 iter;
    1449             :     Word16 sqGain, sqGain_e;
    1450             :     Word16 w_lb, w_ub;
    1451         662 :     const Word16 kDampen = 10;
    1452             :     Word16 old_stopFlag;
    1453             :     Word16 old_nEncoded;
    1454             :     Word16 old_sqBits;
    1455             :     Word16 mod_adjust0, mod_adjust1;
    1456             :     Word16 inv_target, inv_target_e;
    1457         662 :     const Word16 kMargin = 0x7AE1;    /* 0.96 */
    1458         662 :     const Word16 kMarginInv = 0x42AB; /* 1/0.96 (1Q14) */
    1459             :     Word16 tmp, fac1, fac2;
    1460             :     Word32 tmp32;
    1461             :     Word16 lastnz;
    1462         662 :     move16();
    1463         662 :     move16();
    1464         662 :     move16();
    1465         662 :     move16();
    1466             : 
    1467             : 
    1468             :     /* Init */
    1469         662 :     sqGain = *gain;
    1470         662 :     move16();
    1471         662 :     sqGain_e = *gain_e;
    1472         662 :     move16();
    1473         662 :     stopFlag = *stop;
    1474         662 :     move16();
    1475         662 :     ubfound = 0;
    1476         662 :     move16();
    1477         662 :     lbfound = 0;
    1478         662 :     move16();
    1479         662 :     shift = 0x41DE; /* 10^(1/80), 1Q14 */
    1480         662 :     move16();
    1481         662 :     shiftInv = 0x78D7; /* 10^(-1/40) */
    1482         662 :     move16();
    1483         662 :     lb = lb_e = 0;
    1484         662 :     move16();
    1485         662 :     ub = ub_e = 0;
    1486         662 :     move16();
    1487         662 :     w_lb = 0;
    1488         662 :     move16();
    1489         662 :     w_ub = 0;
    1490         662 :     move16();
    1491         662 :     lastnz = *lastnz_out;
    1492         662 :     move16();
    1493         662 :     old_stopFlag = stopFlag;
    1494         662 :     move16();
    1495         662 :     old_nEncoded = *nEncoded;
    1496         662 :     move16();
    1497         662 :     old_sqBits = sqBits_in_noStop;
    1498         662 :     move16();
    1499             : 
    1500         662 :     sqBits = sqBits_in;
    1501         662 :     move16();
    1502             : 
    1503         662 :     mod_adjust0 = extract_l( L_shr( L_max( 0x10000, L_sub( 0x24CCD, L_mult( 0x0052, target ) ) ), 3 ) ); /* 2Q13 */
    1504         662 :     mod_adjust1 = div_s( 0x2000, mod_adjust0 );                                                          /* 0Q15 */
    1505             : 
    1506         662 :     inv_target_e = 15;
    1507         662 :     move16();
    1508         662 :     inv_target = Inv16( target, &inv_target_e );
    1509             : 
    1510         662 :     fac1 = shl( mult( mult( kMarginInv, mod_adjust0 ), inv_target ), 1 ); /* 2Q13 */
    1511         662 :     fac2 = mult( mult( kMargin, mod_adjust1 ), inv_target );
    1512             : 
    1513             :     /* Loop */
    1514        3310 :     FOR( iter = 0; iter < iter_max; iter++ )
    1515             :     {
    1516        2648 :         IF( EQ_16( tcxRateLoopOpt, 2 ) )
    1517             :         {
    1518             :             /* Ajust sqGain */
    1519           0 :             IF( stopFlag != 0 )
    1520             :             {
    1521           0 :                 lbfound = 1;
    1522           0 :                 move16();
    1523           0 :                 lb = sqGain;
    1524           0 :                 move16();
    1525           0 :                 lb_e = sqGain_e;
    1526           0 :                 move16();
    1527           0 :                 w_lb = add( sub( stopFlag, target ), kDampen );
    1528             : 
    1529           0 :                 IF( ubfound != 0 )
    1530             :                 {
    1531             :                     /* common exponent for addition */
    1532           0 :                     sqGain_e = s_max( lb_e, ub_e );
    1533             : 
    1534             :                     /* multiply and add */
    1535           0 :                     tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
    1536           0 :                     tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
    1537             : 
    1538             :                     /* convert to normalized 16 bit */
    1539           0 :                     tmp = norm_l( tmp32 );
    1540           0 :                     sqGain = round_fx_sat( L_shl( tmp32, tmp ) );
    1541           0 :                     sqGain_e = sub( sqGain_e, tmp );
    1542             : 
    1543             :                     /* divide */
    1544           0 :                     sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
    1545           0 :                     sqGain_e = add( sqGain_e, tmp );
    1546             :                 }
    1547             :                 ELSE
    1548             :                 {
    1549           0 :                     tmp = round_fx( L_shl( L_mult( stopFlag, fac1 ), add( inv_target_e, 15 ) ) );
    1550           0 :                     sqGain = mult( sqGain, sub( tmp, sub( mod_adjust0, 0x2000 ) ) );
    1551           0 :                     sqGain = normalize16( sqGain, &sqGain_e );
    1552           0 :                     sqGain_e = add( sqGain_e, 2 );
    1553             :                 }
    1554             :             }
    1555             :             ELSE
    1556             :             {
    1557           0 :                 ubfound = 1;
    1558           0 :                 move16();
    1559           0 :                 ub = sqGain;
    1560           0 :                 move16();
    1561           0 :                 ub_e = sqGain_e;
    1562           0 :                 move16();
    1563           0 :                 w_ub = add( sub( target, sqBits ), kDampen );
    1564             : 
    1565           0 :                 IF( lbfound != 0 )
    1566             :                 {
    1567             :                     /* common exponent for addition */
    1568           0 :                     sqGain_e = s_max( lb_e, ub_e );
    1569             : 
    1570             :                     /* multiply and add */
    1571           0 :                     tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
    1572           0 :                     tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
    1573             : 
    1574             :                     /* convert to normalized 16 bit */
    1575           0 :                     tmp = norm_l( tmp32 );
    1576           0 :                     sqGain = round_fx_sat( L_shl_sat( tmp32, tmp ) );
    1577           0 :                     sqGain_e = sub( sqGain_e, tmp );
    1578             : 
    1579             :                     /* divide */
    1580           0 :                     sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
    1581           0 :                     sqGain_e = add( sqGain_e, tmp );
    1582             :                 }
    1583             :                 ELSE
    1584             :                 {
    1585           0 :                     tmp = round_fx( L_shl( L_mult( sqBits, fac2 ), add( inv_target_e, 15 ) ) );
    1586           0 :                     sqGain = mult( sqGain, sub( tmp, add( mod_adjust1, (Word16) 0x8000 ) ) );
    1587           0 :                     sqGain = normalize16( sqGain, &sqGain_e );
    1588             :                 }
    1589             :             }
    1590             :         }
    1591             :         ELSE /* tcxRateLoopOpt != 2 */
    1592             :         {
    1593             : 
    1594             :             /* Ajust sqGain */
    1595        2648 :             IF( stopFlag != 0 )
    1596             :             {
    1597        1123 :                 lbfound = 1;
    1598        1123 :                 move16();
    1599        1123 :                 lb = sqGain;
    1600        1123 :                 move16();
    1601        1123 :                 lb_e = sqGain_e;
    1602        1123 :                 move16();
    1603             : 
    1604        1123 :                 IF( ubfound != 0 )
    1605             :                 {
    1606         744 :                     sqGain = mult( lb, ub );
    1607         744 :                     sqGain_e = add( lb_e, ub_e );
    1608         744 :                     sqGain = Sqrt16( sqGain, &sqGain_e );
    1609             :                 }
    1610             :                 ELSE
    1611             :                 {
    1612         379 :                     shift = shl( mult( shift, shift ), 1 );
    1613         379 :                     shiftInv = mult( shiftInv, shiftInv );
    1614             : 
    1615         379 :                     sqGain = mult( sqGain, shift );
    1616         379 :                     sqGain = normalize16( sqGain, &sqGain_e );
    1617         379 :                     sqGain_e = add( sqGain_e, 1 );
    1618             :                 }
    1619             :             }
    1620             :             ELSE
    1621             :             {
    1622        1525 :                 ubfound = 1;
    1623        1525 :                 move16();
    1624        1525 :                 ub = sqGain;
    1625        1525 :                 move16();
    1626        1525 :                 ub_e = sqGain_e;
    1627        1525 :                 move16();
    1628             : 
    1629        1525 :                 IF( lbfound != 0 )
    1630             :                 {
    1631         655 :                     sqGain = mult( lb, ub );
    1632         655 :                     sqGain_e = add( lb_e, ub_e );
    1633         655 :                     sqGain = Sqrt16( sqGain, &sqGain_e );
    1634             :                 }
    1635             :                 ELSE
    1636             :                 {
    1637         870 :                     sqGain = mult( sqGain, shiftInv );
    1638         870 :                     sqGain = normalize16( sqGain, &sqGain_e );
    1639             : 
    1640         870 :                     shift = shl( mult( shift, shift ), 1 );
    1641         870 :                     shiftInv = mult( shiftInv, shiftInv );
    1642             :                 }
    1643             :             }
    1644             :         }
    1645             : 
    1646             :         /* Quantize spectrum */
    1647        2648 :         tcx_scalar_quantization_fx( x, x_e, xq, L_frame, sqGain, sqGain_e, offset, memQuantZeros_fx, tcxonly );
    1648             : 
    1649             :         /* Estimate bitrate */
    1650        2648 :         stopFlag = 1;
    1651        2648 :         move16();
    1652        2648 :         if ( tcxRateLoopOpt > 0 )
    1653             :         {
    1654        2648 :             stopFlag = 0;
    1655        2648 :             move16();
    1656             :         }
    1657             : 
    1658        2648 :         sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( xq, L_frame,
    1659             :                                                                      &lastnz,
    1660             :                                                                      nEncoded, target, &stopFlag,
    1661             :                                                                      hm_cfg );
    1662             : 
    1663        2648 :         IF( tcxRateLoopOpt > 0 )
    1664             :         {
    1665        2648 :             test();
    1666        2648 :             test();
    1667        2648 :             test();
    1668        2648 :             test();
    1669        2648 :             test();
    1670        2648 :             test();
    1671        2648 :             IF( ( ( GE_16( *nEncoded, old_nEncoded ) ) && ( GE_16( stopFlag, old_stopFlag ) ) ) ||
    1672             :                 ( ( GT_16( *nEncoded, old_nEncoded ) ) && ( ( stopFlag == 0 ) && ( old_stopFlag > 0 ) ) ) ||
    1673             :                 ( ( stopFlag == 0 ) && ( old_stopFlag == 0 ) ) )
    1674             :             {
    1675        1451 :                 *gain = sqGain;
    1676        1451 :                 move16();
    1677        1451 :                 *gain_e = sqGain_e;
    1678        1451 :                 move16();
    1679        1451 :                 old_nEncoded = *nEncoded;
    1680        1451 :                 move16();
    1681        1451 :                 old_stopFlag = stopFlag;
    1682        1451 :                 move16();
    1683        1451 :                 old_sqBits = sqBits;
    1684        1451 :                 move16();
    1685        1451 :                 *lastnz_out = lastnz;
    1686        1451 :                 move16();
    1687             :             }
    1688             :         }
    1689             :     } /* for ( iter=0 ; iter<iter_max ; iter++ ) */
    1690             : 
    1691         662 :     IF( tcxRateLoopOpt > 0 )
    1692             :     {
    1693             :         /* Quantize spectrum */
    1694         662 :         tcx_scalar_quantization_fx( x, x_e, xq, L_frame, *gain, *gain_e, offset, memQuantZeros_fx, tcxonly );
    1695             : 
    1696             :         /* Output */
    1697         662 :         *nEncoded = old_nEncoded;
    1698         662 :         move16();
    1699         662 :         sqBits = old_sqBits;
    1700         662 :         move16();
    1701         662 :         *stop = old_stopFlag;
    1702         662 :         move16();
    1703             :     }
    1704             :     ELSE
    1705             :     {
    1706             :         /* Output */
    1707           0 :         *gain = sqGain;
    1708           0 :         move16();
    1709           0 :         *gain_e = sqGain_e;
    1710           0 :         move16();
    1711           0 :         *stop = stopFlag;
    1712           0 :         move16();
    1713           0 :         *lastnz_out = lastnz;
    1714           0 :         move16();
    1715             :     }
    1716             : 
    1717             : 
    1718         662 :     return sqBits;
    1719             : }
    1720             : 
    1721      843946 : Word16 tcx_scalar_quantization_rateloop_ivas_fx(
    1722             :     Word32 *x,                     /* i  : input coefficients            Q = 31 - x_e*/
    1723             :     Word16 x_e,                    /* i  : exponent                      Q0*/
    1724             :     Word16 *xq,                    /* o  : quantized coefficients        Q0*/
    1725             :     Word16 L_frame,                /* i  : frame length                  Q0*/
    1726             :     Word16 *gain,                  /* i/o: quantization gain             Q = gaine_e*/
    1727             :     Word16 *gain_e,                /* i/o: gain exponent                 Q0*/
    1728             :     Word16 offset,                 /* i  : rounding offset (deadzone)    Q0*/
    1729             :     Word8 const *memQuantZeros_fx, /* i  : coefficients to be set to 0   Q0*/
    1730             :     Word16 *lastnz_out,            /* i/o: last nonzero coeff index      Q0*/
    1731             :     Word16 target,                 /* i  : target number of bits         Q0*/
    1732             :     Word16 *nEncoded,              /* o  : number of encoded coeff       Q0*/
    1733             :     Word16 *stop,                  /* i/o: stop param                    Q0*/
    1734             :     Word16 sqBits_in_noStop,       /* i  : number of sqBits as determined in prev. quant. stage, w/o using stop mechanism (ie might exceed target bits) Q0*/
    1735             :     Word16 sqBits_in,              /* i  : number of sqBits as determined in prev. quant. stage, using stop mechanism (ie always <= target bits) Q0*/
    1736             :     Word16 tcxRateLoopOpt,         /* i  : turns on/off rateloop optimization */
    1737             :     const Word16 tcxonly,
    1738             :     CONTEXT_HM_CONFIG *hm_cfg, /* i  : configuration of the context-based harmonic model */
    1739             :     const Word16 iter_max,
    1740             :     const Word16 element_mode )
    1741             : {
    1742             :     Word16 sqBits;
    1743             :     Word16 stopFlag;
    1744             :     Word8 ubfound, lbfound;
    1745             :     Word16 ub, ub_e, lb, lb_e;
    1746             :     Word16 shift, shiftInv;
    1747             :     Word16 iter;
    1748             :     Word16 sqGain, sqGain_e;
    1749             :     Word16 w_lb, w_ub;
    1750      843946 :     const Word16 kDampen = 10;
    1751      843946 :     move16();
    1752             :     Word16 old_stopFlag;
    1753             :     Word16 old_nEncoded;
    1754             :     Word16 old_sqBits;
    1755             :     Word16 mod_adjust0, mod_adjust1;
    1756             :     Word16 inv_target, inv_target_e;
    1757      843946 :     const Word16 kMargin = 0x7AE1; /* 0.96 */
    1758      843946 :     move16();
    1759      843946 :     const Word16 kMarginInv = 0x42AB; /* 1/0.96 (1Q14) */
    1760      843946 :     move16();
    1761             :     Word16 tmp, fac1, fac2;
    1762             :     Word32 tmp32;
    1763      843946 :     Word16 lastnz, saturated, minSqGain = 0;
    1764      843946 :     move16();
    1765             : 
    1766             : 
    1767             :     /* Init */
    1768      843946 :     saturated = 0;
    1769      843946 :     move16();
    1770             :     /* minSqGain = (float) sqrt( (float) NORM_MDCT_FACTOR / (float) L_frame ); in Q14*/
    1771      843946 :     SWITCH( L_frame )
    1772             :     {
    1773           0 :         case 80:
    1774           0 :             minSqGain = 23170;
    1775           0 :             BREAK;
    1776           0 :         case 100:
    1777           0 :             minSqGain = 20724;
    1778           0 :             BREAK;
    1779        2140 :         case 160:
    1780        2140 :             minSqGain = 16384;
    1781        2140 :             BREAK;
    1782           0 :         case 200:
    1783           0 :             minSqGain = 14654;
    1784           0 :             BREAK;
    1785           0 :         case 240:
    1786           0 :             minSqGain = 13377;
    1787           0 :             BREAK;
    1788           0 :         case 300:
    1789           0 :             minSqGain = 11965;
    1790           0 :             BREAK;
    1791       69557 :         case 320:
    1792       69557 :             minSqGain = 11585;
    1793       69557 :             BREAK;
    1794         415 :         case 400:
    1795         415 :             minSqGain = 10362;
    1796         415 :             BREAK;
    1797       21982 :         case 480:
    1798       21982 :             minSqGain = 9459;
    1799       21982 :             BREAK;
    1800           0 :         case 600:
    1801           0 :             minSqGain = 8461;
    1802           0 :             BREAK;
    1803      207815 :         case 640:
    1804      207815 :             minSqGain = 8192;
    1805      207815 :             BREAK;
    1806        3145 :         case 800:
    1807        3145 :             minSqGain = 7327;
    1808        3145 :             BREAK;
    1809      534884 :         case 960:
    1810      534884 :             minSqGain = 6689;
    1811      534884 :             BREAK;
    1812        4008 :         case 1200:
    1813        4008 :             minSqGain = 5983;
    1814        4008 :             BREAK;
    1815           0 :         case 1440:
    1816           0 :             minSqGain = 5461;
    1817           0 :             BREAK;
    1818           0 :         case 1800:
    1819           0 :             minSqGain = 4885;
    1820           0 :             BREAK;
    1821           0 :         case 2048:
    1822           0 :             minSqGain = 4579;
    1823           0 :             BREAK;
    1824           0 :         default:
    1825           0 :             assert( 0 );
    1826             :     }
    1827      843946 :     move16();
    1828      843946 :     sqGain = *gain;
    1829      843946 :     move16();
    1830      843946 :     sqGain_e = *gain_e;
    1831      843946 :     move16();
    1832      843946 :     stopFlag = *stop;
    1833      843946 :     move16();
    1834      843946 :     ubfound = 0;
    1835      843946 :     move16();
    1836      843946 :     lbfound = 0;
    1837      843946 :     move16();
    1838      843946 :     shift = 0x41DE; /* 10^(1/80), 1Q14 */
    1839      843946 :     move16();
    1840      843946 :     shiftInv = 0x78D7; /* 10^(-1/40) */
    1841      843946 :     move16();
    1842      843946 :     lb = lb_e = 0;
    1843      843946 :     move16();
    1844      843946 :     ub = ub_e = 0;
    1845      843946 :     move16();
    1846      843946 :     w_lb = 0;
    1847      843946 :     move16();
    1848      843946 :     w_ub = 0;
    1849      843946 :     move16();
    1850      843946 :     lastnz = *lastnz_out;
    1851      843946 :     move16();
    1852      843946 :     old_stopFlag = stopFlag;
    1853      843946 :     move16();
    1854      843946 :     old_nEncoded = *nEncoded;
    1855      843946 :     move16();
    1856      843946 :     old_sqBits = sqBits_in_noStop;
    1857      843946 :     move16();
    1858             : 
    1859      843946 :     sqBits = sqBits_in;
    1860      843946 :     move16();
    1861             : 
    1862      843946 :     mod_adjust0 = extract_l( L_shr( L_max( 0x10000, L_sub( 0x24CCD, L_mult( 0x0052, target ) ) ), 3 ) ); /* 2Q13 */
    1863      843946 :     mod_adjust1 = div_s( 0x2000, mod_adjust0 );                                                          /* 0Q15 */
    1864             : 
    1865      843946 :     inv_target_e = 15;
    1866      843946 :     move16();
    1867      843946 :     inv_target = Inv16( target, &inv_target_e );
    1868             : 
    1869      843946 :     fac1 = shl( mult( mult( kMarginInv, mod_adjust0 ), inv_target ), 1 ); /* 2Q13 */
    1870      843946 :     fac2 = mult( mult( kMargin, mod_adjust1 ), inv_target );
    1871             : 
    1872             :     /* Loop */
    1873     2963259 :     FOR( iter = 0; iter < iter_max; iter++ )
    1874             :     {
    1875     2128578 :         IF( GE_16( tcxRateLoopOpt, 2 ) )
    1876             :         {
    1877             :             /* Ajust sqGain */
    1878     1682938 :             IF( stopFlag != 0 )
    1879             :             {
    1880      806117 :                 lbfound = 1;
    1881      806117 :                 move16();
    1882      806117 :                 lb = sqGain;
    1883      806117 :                 move16();
    1884      806117 :                 lb_e = sqGain_e;
    1885      806117 :                 move16();
    1886      806117 :                 w_lb = add( sub( stopFlag, target ), kDampen );
    1887      806117 :                 saturated = 0;
    1888      806117 :                 move16();
    1889      806117 :                 IF( ubfound != 0 )
    1890             :                 {
    1891             :                     /* common exponent for addition */
    1892      375746 :                     sqGain_e = s_max( lb_e, ub_e );
    1893             : 
    1894             :                     /* multiply and add */
    1895      375746 :                     tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
    1896      375746 :                     tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
    1897             : 
    1898             :                     /* convert to normalized 16 bit */
    1899      375746 :                     tmp = norm_l( tmp32 );
    1900      375746 :                     sqGain = round_fx_sat( L_shl( tmp32, tmp ) );
    1901      375746 :                     sqGain_e = sub( sqGain_e, tmp );
    1902             : 
    1903             :                     /* divide */
    1904      375746 :                     sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
    1905      375746 :                     sqGain_e = add( sqGain_e, tmp );
    1906             :                 }
    1907             :                 ELSE
    1908             :                 {
    1909      430371 :                     tmp = round_fx_sat( L_shl_sat( L_mult( stopFlag, fac1 ), add( inv_target_e, 15 ) ) );
    1910      430371 :                     sqGain = mult( sqGain, sub( tmp, sub( mod_adjust0, 0x2000 ) ) );
    1911      430371 :                     sqGain = normalize16( sqGain, &sqGain_e );
    1912      430371 :                     sqGain_e = add( sqGain_e, 2 );
    1913             :                 }
    1914             :             }
    1915      876821 :             ELSE IF( saturated == 0 )
    1916             :             {
    1917      867556 :                 ubfound = 1;
    1918      867556 :                 move16();
    1919      867556 :                 ub = sqGain;
    1920      867556 :                 move16();
    1921      867556 :                 ub_e = sqGain_e;
    1922      867556 :                 move16();
    1923      867556 :                 w_ub = add( sub( target, sqBits ), kDampen );
    1924             : 
    1925      867556 :                 IF( lbfound != 0 )
    1926             :                 {
    1927             :                     /* common exponent for addition */
    1928      438882 :                     sqGain_e = s_max( lb_e, ub_e );
    1929             : 
    1930             :                     /* multiply and add */
    1931      438882 :                     tmp32 = L_shr( L_mult( lb, w_ub ), sub( sqGain_e, lb_e ) );
    1932      438882 :                     tmp32 = L_add( tmp32, L_shr( L_mult( ub, w_lb ), sub( sqGain_e, ub_e ) ) );
    1933             : 
    1934             :                     /* convert to normalized 16 bit */
    1935      438882 :                     tmp = norm_l( tmp32 );
    1936      438882 :                     sqGain = round_fx_sat( L_shl_sat( tmp32, tmp ) );
    1937      438882 :                     sqGain_e = sub( sqGain_e, tmp );
    1938             : 
    1939             :                     /* divide */
    1940      438882 :                     sqGain = BASOP_Util_Divide1616_Scale( sqGain, add( w_ub, w_lb ), &tmp );
    1941      438882 :                     sqGain_e = add( sqGain_e, tmp );
    1942             :                 }
    1943             :                 ELSE
    1944             :                 {
    1945      428674 :                     tmp = round_fx( L_shl( L_mult( sqBits, fac2 ), add( inv_target_e, 15 ) ) );
    1946      428674 :                     sqGain = mult( sqGain, sub( tmp, add( mod_adjust1, (Word16) 0x8000 ) ) );
    1947      428674 :                     sqGain = normalize16( sqGain, &sqGain_e );
    1948             :                 }
    1949             : 
    1950      867556 :                 Word16 shift_tmp = s_max( sqGain_e, 1 );
    1951      867556 :                 move16();
    1952      867556 :                 test();
    1953      867556 :                 IF( LT_16( shl( sqGain, sub( sqGain_e, shift_tmp ) ), shl( minSqGain, sub( 1, shift_tmp ) ) ) && EQ_16( tcxRateLoopOpt, 3 ) )
    1954             :                 {
    1955        9771 :                     sqGain = minSqGain;
    1956        9771 :                     move16();
    1957        9771 :                     sqGain_e = 1;
    1958        9771 :                     move16();
    1959        9771 :                     saturated = 1;
    1960        9771 :                     move16();
    1961             :                 }
    1962             :             }
    1963             :             ELSE
    1964             :             {
    1965        9265 :                 break; /* we cannot go any lower anyway*/
    1966             :             }
    1967             :         }
    1968             :         ELSE /* tcxRateLoopOpt != 2 */
    1969             :         {
    1970             : 
    1971             :             /* Ajust sqGain */
    1972      445640 :             IF( stopFlag != 0 )
    1973             :             {
    1974      181638 :                 lbfound = 1;
    1975      181638 :                 move16();
    1976      181638 :                 lb = sqGain;
    1977      181638 :                 move16();
    1978      181638 :                 lb_e = sqGain_e;
    1979      181638 :                 move16();
    1980             : 
    1981      181638 :                 IF( ubfound != 0 )
    1982             :                 {
    1983      131330 :                     sqGain = mult( lb, ub );
    1984      131330 :                     sqGain_e = add( lb_e, ub_e );
    1985      131330 :                     sqGain = Sqrt16( sqGain, &sqGain_e );
    1986             :                 }
    1987             :                 ELSE
    1988             :                 {
    1989       50308 :                     shift = shl( mult( shift, shift ), 1 );
    1990       50308 :                     shiftInv = mult( shiftInv, shiftInv );
    1991             : 
    1992       50308 :                     sqGain = mult( sqGain, shift );
    1993       50308 :                     sqGain = normalize16( sqGain, &sqGain_e );
    1994       50308 :                     sqGain_e = add( sqGain_e, 1 );
    1995             :                 }
    1996             :             }
    1997             :             ELSE
    1998             :             {
    1999      264002 :                 ubfound = 1;
    2000      264002 :                 move16();
    2001      264002 :                 ub = sqGain;
    2002      264002 :                 move16();
    2003      264002 :                 ub_e = sqGain_e;
    2004      264002 :                 move16();
    2005             : 
    2006      264002 :                 IF( lbfound != 0 )
    2007             :                 {
    2008       96975 :                     sqGain = mult( lb, ub );
    2009       96975 :                     sqGain_e = add( lb_e, ub_e );
    2010       96975 :                     sqGain = Sqrt16( sqGain, &sqGain_e );
    2011             :                 }
    2012             :                 ELSE
    2013             :                 {
    2014      167027 :                     sqGain = mult( sqGain, shiftInv );
    2015      167027 :                     sqGain = normalize16( sqGain, &sqGain_e );
    2016             : 
    2017      167027 :                     shift = shl( mult( shift, shift ), 1 );
    2018      167027 :                     shiftInv = mult( shiftInv, shiftInv );
    2019             :                 }
    2020             :             }
    2021             :         }
    2022             : 
    2023             :         /* Quantize spectrum */
    2024     2119313 :         tcx_scalar_quantization_ivas_fx( x, x_e, xq, L_frame, sqGain, sqGain_e, offset, memQuantZeros_fx, tcxonly );
    2025             : 
    2026             :         /* Estimate bitrate */
    2027     2119313 :         stopFlag = 1;
    2028     2119313 :         move16();
    2029     2119313 :         if ( tcxRateLoopOpt > 0 )
    2030             :         {
    2031     2119313 :             stopFlag = 0;
    2032     2119313 :             move16();
    2033             :         }
    2034             : 
    2035     2119313 :         IF( GT_16( element_mode, EVS_MONO ) )
    2036             :         {
    2037     2119313 :             sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( xq, L_frame, &lastnz, nEncoded, target, &stopFlag, 0, hm_cfg );
    2038             :         }
    2039             :         ELSE
    2040             :         {
    2041           0 :             sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( xq, L_frame,
    2042             :                                                                          &lastnz,
    2043             :                                                                          nEncoded, target, &stopFlag,
    2044             :                                                                          hm_cfg );
    2045             :         }
    2046             : 
    2047     2119313 :         IF( GE_16( tcxRateLoopOpt, 1 ) )
    2048             :         {
    2049     2119313 :             test();
    2050     2119313 :             test();
    2051     2119313 :             test();
    2052     2119313 :             test();
    2053     2119313 :             test();
    2054     2119313 :             test();
    2055     2119313 :             IF( ( ( GE_16( *nEncoded, old_nEncoded ) ) && ( GE_16( stopFlag, old_stopFlag ) ) ) ||
    2056             :                 ( ( GT_16( *nEncoded, old_nEncoded ) ) && ( ( stopFlag == 0 ) && ( old_stopFlag > 0 ) ) ) ||
    2057             :                 ( ( stopFlag == 0 ) && ( old_stopFlag == 0 ) ) )
    2058             :             {
    2059     1150845 :                 *gain = sqGain;
    2060     1150845 :                 move16();
    2061     1150845 :                 *gain_e = sqGain_e;
    2062     1150845 :                 move16();
    2063     1150845 :                 old_nEncoded = *nEncoded;
    2064     1150845 :                 move16();
    2065     1150845 :                 old_stopFlag = stopFlag;
    2066     1150845 :                 move16();
    2067     1150845 :                 old_sqBits = sqBits;
    2068     1150845 :                 move16();
    2069     1150845 :                 *lastnz_out = lastnz;
    2070     1150845 :                 move16();
    2071             :             }
    2072             :         }
    2073             :     } /* for ( iter=0 ; iter<iter_max ; iter++ ) */
    2074             : 
    2075      843946 :     IF( GE_16( tcxRateLoopOpt, 1 ) )
    2076             :     {
    2077             :         /* Quantize spectrum */
    2078      843946 :         tcx_scalar_quantization_ivas_fx( x, x_e, xq, L_frame, *gain, *gain_e, offset, memQuantZeros_fx, tcxonly );
    2079             : 
    2080             :         /* Output */
    2081      843946 :         *nEncoded = old_nEncoded;
    2082      843946 :         move16();
    2083      843946 :         sqBits = old_sqBits;
    2084      843946 :         move16();
    2085      843946 :         *stop = old_stopFlag;
    2086      843946 :         move16();
    2087             :     }
    2088             :     ELSE
    2089             :     {
    2090             :         /* Output */
    2091           0 :         *gain = sqGain;
    2092           0 :         move16();
    2093           0 :         *gain_e = sqGain_e;
    2094           0 :         move16();
    2095           0 :         *stop = stopFlag;
    2096           0 :         move16();
    2097           0 :         *lastnz_out = lastnz;
    2098           0 :         move16();
    2099             :     }
    2100             : 
    2101             : 
    2102      843946 :     return sqBits;
    2103             : }
    2104             : 
    2105      862103 : void QuantizeGain( Word16 n, Word16 *pGain, Word16 *pGain_e, Word16 *pQuantizedGain )
    2106             : {
    2107             :     Word16 ener, ener_e, enerInv, enerInv_e, gain, gain_e;
    2108             :     Word16 quantizedGain;
    2109             :     Word32 tmp32;
    2110             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2111      862103 :     Flag Overflow = 0;
    2112      862103 :     move32();
    2113             : #endif
    2114             : 
    2115      862103 :     ener = mult_r( shl_o( n, 5, &Overflow ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    2116      862103 :     ener_e = 15 - 5 - 7;
    2117      862103 :     move16();
    2118      862103 :     IF( GE_16( n, 1024 ) )
    2119             :     {
    2120             :         /*reduce precision for avoiding overflow*/
    2121        4008 :         ener = mult_r( shl( n, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
    2122        4008 :         ener_e = 15 - 4 - 7;
    2123        4008 :         move16();
    2124             :     }
    2125      862103 :     BASOP_Util_Sqrt_InvSqrt_MantExp( ener, ener_e, &ener, &ener_e, &enerInv, &enerInv_e );
    2126             : 
    2127      862103 :     gain = mult( *pGain, ener );
    2128      862103 :     gain_e = add( *pGain_e, ener_e );
    2129             : 
    2130      862103 :     assert( gain > 0 );
    2131             : 
    2132             :     /* quantize gain with step of 0.714 dB */
    2133      862103 :     quantizedGain = add( round_fx( BASOP_Util_Log2( L_deposit_h( gain ) ) ), shl( gain_e, 9 ) ); /* 6Q9 */
    2134      862103 :     quantizedGain = mult( quantizedGain, 0x436E );                                               /* 10Q5;  0x436E -> 28/log2(10) (4Q11) */
    2135      862103 :     quantizedGain = shr( add( quantizedGain, 0x10 ), 5 );                                        /* round */
    2136             : 
    2137      862103 :     if ( quantizedGain < 0 )
    2138             :     {
    2139        1124 :         quantizedGain = 0;
    2140        1124 :         move16();
    2141             :     }
    2142             : 
    2143      862103 :     if ( GT_16( quantizedGain, 127 ) )
    2144             :     {
    2145          30 :         quantizedGain = 127;
    2146          30 :         move16();
    2147             :     }
    2148             : 
    2149      862103 :     *pQuantizedGain = quantizedGain;
    2150      862103 :     move16();
    2151             : 
    2152      862103 :     tmp32 = L_shl( L_mult0( quantizedGain, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
    2153      862103 :     gain_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 );   /* get exponent */
    2154      862103 :     gain = round_fx( BASOP_Util_InvLog2( L_or( tmp32, 0xFE000000 ) ) );
    2155             : 
    2156      862103 :     *pGain = mult( gain, enerInv );
    2157      862103 :     move16();
    2158      862103 :     *pGain_e = add( gain_e, enerInv_e );
    2159      862103 :     move16();
    2160      862103 : }
    2161             : 
    2162         662 : void tcx_noise_factor_fx(
    2163             :     Word32 *x_orig,          /* i: unquantized mdct coefficients             */
    2164             :     Word16 x_orig_e,         /* i: exponent                                  */
    2165             :     Word32 *sqQ,             /* i: quantized mdct coefficients               */
    2166             :     Word16 iFirstLine,       /* i: first coefficient to be considered        */
    2167             :     Word16 lowpassLine,      /* i: last nonzero coefficients after low-pass  */
    2168             :     Word16 nTransWidth,      /* i: minimum size of hole to be checked        */
    2169             :     Word16 L_frame,          /* i: frame length                              */
    2170             :     Word16 gain_tcx,         /* i: tcx gain                                  */
    2171             :     Word16 gain_tcx_e,       /* i: gain exponent                             */
    2172             :     Word16 tiltCompFactor,   /* i: LPC tilt compensation factor              */
    2173             :     Word16 *fac_ns,          /* o: noise factor                              */
    2174             :     Word16 *quantized_fac_ns /* o: quantized noise factor                    */
    2175             : )
    2176             : {
    2177             :     Word16 i, k, maxK, segmentOffset;
    2178             :     Word32 sqErrorNrg, n;
    2179             :     Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1;
    2180             :     Word32 accu1, accu2, tmp32;
    2181             :     Word16 tmp1, tmp2, s;
    2182             :     Word16 c1, c2;
    2183             :     Word16 att; /* noise level attenuation factor for transient windows */
    2184             :     Word32 xMax;
    2185             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2186         662 :     Flag Overflow = 0;
    2187         662 :     move32();
    2188             : #endif
    2189             : 
    2190             : 
    2191         662 :     assert( nTransWidth <= 16 );
    2192             : 
    2193         662 :     c1 = sub( shl( nTransWidth, 1 ), 4 );
    2194         662 :     c2 = mult( 9216 /*0.28125f Q15*/, inv_int[nTransWidth] );
    2195         662 :     nTransWidth_1 = sub( nTransWidth, 1 );
    2196             : 
    2197             :     /*Adjust noise filling level*/
    2198         662 :     sqErrorNrg = L_deposit_l( 0 );
    2199         662 :     n = L_deposit_l( 0 );
    2200             : 
    2201             :     /* get inverse frame length */
    2202         662 :     tmp1 = getInvFrameLen( L_frame );
    2203             : 
    2204             :     /* tilt_factor = 1.0f /(float)pow(max(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    2205         662 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    2206         662 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, negate( tmp1 ) ), 6 );
    2207         662 :     tilt_factor = round_fx( BASOP_Util_InvLog2( L_sub( tmp32, 0x2000000 ) ) ); /* 1Q14 */
    2208             : 
    2209             :     /* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */
    2210         662 :     tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */
    2211         662 :     tmp1 = norm_l( tmp32 );
    2212         662 :     inv_gain2 = round_fx( L_shl( tmp32, tmp1 ) );
    2213         662 :     inv_gain2_e = add( sub( 15, tmp1 ), gain_tcx_e );
    2214         662 :     inv_gain2 = Inv16( inv_gain2, &inv_gain2_e );
    2215         662 :     inv_gain2 = shr( inv_gain2, 2 ); /* 2 bits headroom */
    2216         662 :     inv_gain2_e = add( inv_gain2_e, 2 );
    2217             : 
    2218             :     /* find last nonzero line below iFirstLine, use it as start offset */
    2219         662 :     tmp1 = shr( iFirstLine, 1 );
    2220        2871 :     FOR( i = iFirstLine; i > tmp1; i-- )
    2221             :     {
    2222        2867 :         IF( sqQ[i] != 0 )
    2223             :         {
    2224         658 :             BREAK;
    2225             :         }
    2226             :     }
    2227             :     /* inv_gain2 *= (float)pow(tilt_factor, (float)i); */
    2228       31160 :     FOR( k = 0; k < i; k++ )
    2229             :     {
    2230       30498 :         inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
    2231             :     }
    2232             : 
    2233             :     /* initialize left (k) and right (maxK) non-zero neighbor pointers */
    2234         662 :     k = 0;
    2235         662 :     move16();
    2236        3407 :     FOR( maxK = 1; maxK < nTransWidth; maxK++ )
    2237             :     {
    2238        3124 :         IF( sqQ[i + maxK] != 0 )
    2239             :         {
    2240         379 :             BREAK;
    2241             :         }
    2242             :     }
    2243         662 :     i = add( i, 1 );
    2244         662 :     segmentOffset = i;
    2245         662 :     move16();
    2246             : 
    2247         662 :     IF( LE_16( nTransWidth, 3 ) )
    2248             :     {
    2249           0 :         accu1 = L_deposit_l( 0 );
    2250           0 :         accu2 = L_deposit_l( 0 );
    2251           0 :         xMax = L_deposit_l( 0 );
    2252             : 
    2253           0 :         FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k++ )
    2254             :         {
    2255           0 :             xMax = L_max( xMax, L_abs( x_orig[k] ) );
    2256             :         }
    2257           0 :         s = sub( norm_l( xMax ), 4 );
    2258             : 
    2259           0 :         FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k += 2 )
    2260             :         {
    2261             :             /* even-index bins, left sub-win */
    2262           0 :             tmp1 = round_fx( L_shl( x_orig[k], s ) );
    2263           0 :             accu1 = L_mac0( accu1, tmp1, tmp1 );
    2264             : 
    2265             :             /* odd-index bins, right sub-win */
    2266           0 :             tmp1 = round_fx( L_shl( x_orig[k + 1], s ) );
    2267           0 :             accu2 = L_mac0( accu2, tmp1, tmp1 );
    2268             :         }
    2269           0 :         k = 0;
    2270           0 :         move16();
    2271             : 
    2272           0 :         IF( accu1 == 0 )
    2273             :         {
    2274           0 :             accu1 = L_deposit_l( 1 );
    2275             :         }
    2276           0 :         IF( accu2 == 0 )
    2277             :         {
    2278           0 :             accu2 = L_deposit_l( 1 );
    2279             :         }
    2280             : 
    2281           0 :         att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s );
    2282           0 :         att = Sqrt16( att, &s );
    2283             :         BASOP_SATURATE_WARNING_OFF_EVS; /* att is always <= 1.0 */
    2284           0 :         att = shl_o( att, s, &Overflow );
    2285             :         BASOP_SATURATE_WARNING_ON_EVS;
    2286             :     }
    2287             :     ELSE
    2288             :     {
    2289         662 :         att = 0x7FFF;
    2290         662 :         move16();
    2291             :     }
    2292             : 
    2293         662 :     accu1 = L_deposit_l( 0 );
    2294             : 
    2295         662 :     tmp1 = sub( lowpassLine, nTransWidth );
    2296      124307 :     FOR( ; i <= tmp1; i++ )
    2297             :     {
    2298      123645 :         inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
    2299             : 
    2300      123645 :         IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */
    2301             :         {
    2302       19021 :             k = sub( i, segmentOffset );
    2303             : 
    2304       19021 :             IF( k > 0 ) /* add segment sum to sum of segment magnitudes */
    2305             :             {
    2306       12329 :                 IF( LE_16( nTransWidth, 3 ) )
    2307             :                 {
    2308           0 :                     tmp2 = sub( k, c1 );
    2309           0 :                     IF( tmp2 > 0 )
    2310             :                     {
    2311           0 :                         n = L_msu( n, k, (Word16) 0x8000 );
    2312             :                     }
    2313           0 :                     IF( tmp2 > 0 )
    2314             :                     {
    2315           0 :                         n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
    2316             :                     }
    2317           0 :                     IF( tmp2 <= 0 )
    2318             :                     {
    2319           0 :                         n = L_mac( n, int_sqr[k], c2 );
    2320             :                     }
    2321             :                 }
    2322             :                 ELSE
    2323             :                 {
    2324       12329 :                     tmp2 = sub( k, 12 );
    2325       12329 :                     IF( tmp2 > 0 )
    2326             :                     {
    2327        1736 :                         n = L_msu( n, k, (Word16) 0x8000 );
    2328             :                     }
    2329       12329 :                     IF( tmp2 > 0 )
    2330             :                     {
    2331        1736 :                         n = L_sub( n, 0x70000 );
    2332             :                     }
    2333       12329 :                     IF( tmp2 <= 0 )
    2334             :                     {
    2335       10593 :                         n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
    2336             :                     }
    2337             :                 }
    2338       12329 :                 sqErrorNrg = L_add( sqErrorNrg, accu1 );
    2339       12329 :                 accu1 = L_deposit_l( 0 ); /* segment ended here, so reset segment sum */
    2340       12329 :                 k = 0;
    2341       12329 :                 move16();
    2342             :             }
    2343             : 
    2344       69113 :             FOR( ; maxK < nTransWidth; maxK++ )
    2345             :             {
    2346       64976 :                 IF( sqQ[i + maxK] != 0 )
    2347             :                 {
    2348       14884 :                     BREAK;
    2349             :                 }
    2350             :             }
    2351       19021 :             segmentOffset = add( i, 1 ); /* new segment might start at next line */
    2352             :         }
    2353             :         ELSE /* current line is zero, so update pointers & segment sum */
    2354             :         {
    2355      104624 :             IF( LT_16( k, nTransWidth ) )
    2356             :             {
    2357       55852 :                 k = add( k, 1 );
    2358             :             }
    2359             : 
    2360      104624 :             tmp2 = sub( maxK, nTransWidth );
    2361      104624 :             IF( tmp2 < 0 )
    2362             :             {
    2363       45117 :                 maxK = sub( maxK, 1 );
    2364             :             }
    2365             : 
    2366      104624 :             test();
    2367      104624 :             IF( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) )
    2368             :             {
    2369        3952 :                 maxK = sub( nTransWidth, 1 );
    2370             :             }
    2371             : 
    2372             :             /* update segment sum: magnitudes scaled by smoothing function */
    2373             :             /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/
    2374      104624 :             tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) );
    2375      104624 :             accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) );
    2376             :         }
    2377             :     }
    2378             : 
    2379        5296 :     FOR( ; i < lowpassLine; i++ )
    2380             :     {
    2381        4634 :         inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
    2382             : 
    2383        4634 :         IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */
    2384             :         {
    2385         866 :             k = sub( i, segmentOffset );
    2386             : 
    2387         866 :             IF( k > 0 ) /* add segment sum to sum of segment magnitudes */
    2388             :             {
    2389         181 :                 IF( LE_16( nTransWidth, 3 ) )
    2390             :                 {
    2391           0 :                     tmp2 = sub( k, c1 );
    2392           0 :                     IF( tmp2 > 0 )
    2393             :                     {
    2394           0 :                         n = L_msu( n, k, (Word16) 0x8000 );
    2395             :                     }
    2396           0 :                     IF( tmp2 > 0 )
    2397             :                     {
    2398           0 :                         n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
    2399             :                     }
    2400           0 :                     IF( tmp2 <= 0 )
    2401             :                     {
    2402           0 :                         n = L_mac( n, int_sqr[k], c2 );
    2403             :                     }
    2404             :                 }
    2405             :                 ELSE
    2406             :                 {
    2407         181 :                     tmp2 = sub( k, 12 );
    2408         181 :                     IF( tmp2 > 0 )
    2409             :                     {
    2410          60 :                         n = L_msu( n, k, (Word16) 0x8000 );
    2411             :                     }
    2412         181 :                     IF( tmp2 > 0 )
    2413             :                     {
    2414          60 :                         n = L_sub( n, 0x70000 );
    2415             :                     }
    2416         181 :                     IF( tmp2 <= 0 )
    2417             :                     {
    2418         121 :                         n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
    2419             :                     }
    2420             :                 }
    2421         181 :                 sqErrorNrg = L_add( sqErrorNrg, accu1 );
    2422             :             }
    2423         866 :             segmentOffset = add( i, 1 ); /* no new segments since maxK remains 1 */
    2424             :         }
    2425             :         ELSE /* current line is zero, so update pointers & energy sum */
    2426             :         {
    2427        3768 :             IF( LT_16( k, nTransWidth ) )
    2428             :             {
    2429         801 :                 k = add( k, 1 );
    2430             :             }
    2431        3768 :             IF( LT_16( maxK, nTransWidth ) )
    2432             :             {
    2433         492 :                 maxK = sub( maxK, 1 );
    2434             :             }
    2435             : 
    2436             :             /* update segment sum: magnitudes scaled by smoothing function */
    2437             :             /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/
    2438        3768 :             tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) );
    2439        3768 :             accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) );
    2440             :         }
    2441             :     }
    2442             : 
    2443         662 :     k = sub( i, segmentOffset );
    2444         662 :     IF( k > 0 ) /* add last segment sum to sum of segment magnitudes */
    2445             :     {
    2446         468 :         IF( LE_16( nTransWidth, 3 ) )
    2447             :         {
    2448           0 :             tmp2 = sub( k, c1 );
    2449           0 :             IF( tmp2 > 0 )
    2450             :             {
    2451           0 :                 n = L_msu( n, k, (Word16) 0x8000 );
    2452             :             }
    2453           0 :             IF( tmp2 > 0 )
    2454             :             {
    2455           0 :                 n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
    2456             :             }
    2457           0 :             IF( tmp2 <= 0 )
    2458             :             {
    2459           0 :                 n = L_mac( n, int_sqr[k], c2 );
    2460             :             }
    2461             :         }
    2462             :         ELSE
    2463             :         {
    2464         468 :             tmp2 = sub( k, 12 );
    2465         468 :             IF( tmp2 > 0 )
    2466             :             {
    2467         374 :                 n = L_msu( n, k, (Word16) 0x8000 );
    2468             :             }
    2469         468 :             IF( tmp2 > 0 )
    2470             :             {
    2471         374 :                 n = L_sub( n, 0x70000 );
    2472             :             }
    2473         468 :             IF( tmp2 <= 0 )
    2474             :             {
    2475          94 :                 n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
    2476             :             }
    2477             :         }
    2478         468 :         sqErrorNrg = L_add( sqErrorNrg, accu1 );
    2479             :     }
    2480             : 
    2481             :     /* noise level factor: average of segment magnitudes of noise bins */
    2482         662 :     IF( n > 0 )
    2483             :     {
    2484         662 :         tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s );
    2485         662 :         s = add( add( add( s, x_orig_e ), inv_gain2_e ), 7 - 15 );
    2486             :         BASOP_SATURATE_WARNING_OFF_EVS;
    2487         662 :         tmp1 = shl_o( tmp1, s, &Overflow );
    2488             :         BASOP_SATURATE_WARNING_ON_EVS;
    2489             :     }
    2490             :     ELSE
    2491             :     {
    2492           0 :         tmp1 = 0;
    2493           0 :         move16();
    2494             :     }
    2495             : 
    2496             :     /* quantize, dequantize noise level factor (range 0.09375 - 0.65625) */
    2497         662 :     tmp2 = round_fx( L_shr( L_mult( tmp1, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) );
    2498             : 
    2499         662 :     if ( GT_16( tmp2, ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1 ) )
    2500             :     {
    2501           0 :         tmp2 = ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1;
    2502           0 :         move16();
    2503             :     }
    2504             : 
    2505         662 :     *quantized_fac_ns = tmp2;
    2506         662 :     move16();
    2507             : 
    2508         662 :     *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) );
    2509         662 : }
    2510             : 
    2511             : 
    2512      823390 : void tcx_noise_factor_ivas_fx(
    2513             :     Word32 *x_orig,           /* i: unquantized mdct coefficients                    */
    2514             :     Word16 x_orig_e,          /* i: exponent                                         */
    2515             :     Word32 *sqQ,              /* i: quantized mdct coefficients, exponent = x_orig_e */
    2516             :     Word16 iFirstLine,        /* i: first coefficient to be considered               */
    2517             :     Word16 lowpassLine,       /* i: last nonzero coefficients after low-pass         */
    2518             :     Word16 nTransWidth,       /* i: minimum size of hole to be checked               */
    2519             :     Word16 L_frame,           /* i: frame length                                     */
    2520             :     Word16 gain_tcx,          /* i: tcx gain                                         */
    2521             :     Word16 gain_tcx_e,        /* i: gain exponent                                    */
    2522             :     Word16 tiltCompFactor,    /* i: LPC tilt compensation factor                     */
    2523             :     Word16 *fac_ns,           /* o: noise factor, Q15                                */
    2524             :     Word16 *quantized_fac_ns, /* o: quantized noise factor, Q0                       */
    2525             :     Word16 element_mode       /* i: element mode                                     */
    2526             : )
    2527             : {
    2528             :     Word16 i, k, win, segmentOffset, j;
    2529      823390 :     Word32 sqErrorNrg = 0, n;
    2530      823390 :     move32();
    2531      823390 :     Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1, exp_sqErrorNrg = 0;
    2532      823390 :     move16();
    2533             :     Word32 accu1, accu2, tmp32;
    2534             :     Word16 tmp1, tmp2, s;
    2535             :     Word16 c1, c2;
    2536             :     Word16 att; /* noise level attenuation factor for transient windows */
    2537             :     Word32 xMax;
    2538             :     Word16 exp_spQ[N_MAX];
    2539             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2540      823390 :     Flag Overflow = 0;
    2541      823390 :     move32();
    2542             : #endif
    2543             : 
    2544      823390 :     assert( nTransWidth <= 16 );
    2545             : 
    2546      823390 :     set16_fx( exp_spQ, x_orig_e, N_MAX );
    2547      823390 :     c1 = sub( shl( nTransWidth, 1 ), 4 );
    2548      823390 :     c2 = mult( 9216 /*0.28125f Q15*/, inv_int[nTransWidth] );
    2549      823390 :     nTransWidth_1 = sub( nTransWidth, 1 );
    2550             : 
    2551             :     /*Adjust noise filling level*/
    2552      823390 :     n = 0;
    2553      823390 :     move32();
    2554             : 
    2555             :     /* get inverse frame length */
    2556      823390 :     tmp1 = getInvFrameLen( L_frame );
    2557             : 
    2558             :     /* tilt_factor = 1.0f /(float)pow(max(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
    2559      823390 :     tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
    2560      823390 :     tmp32 = L_shr( Mpy_32_16_1( tmp32, negate( tmp1 ) ), 6 );
    2561      823390 :     tilt_factor = round_fx( BASOP_Util_InvLog2( L_sub( tmp32, 0x2000000 ) ) ); /* 1Q14 */
    2562             : 
    2563             :     /* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */
    2564      823390 :     tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */
    2565      823390 :     inv_gain2 = BASOP_Util_Divide3232_Scale( MAX_32, tmp32, &inv_gain2_e );
    2566      823390 :     inv_gain2_e = add( inv_gain2_e, sub( 0, add( 15, gain_tcx_e ) ) );
    2567      823390 :     inv_gain2 = shr( inv_gain2, 2 ); /* 2 bits headroom */
    2568      823390 :     inv_gain2_e = add( inv_gain2_e, 2 );
    2569             : 
    2570             :     /* find last nonzero line below iFirstLine, use it as start offset */
    2571      823390 :     i = iFirstLine;
    2572      823390 :     move16();
    2573             : 
    2574      823390 :     IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
    2575             :     {
    2576      603685 :         segmentOffset = i;
    2577      603685 :         move16();
    2578             :     }
    2579             :     ELSE
    2580             :     {
    2581             :         /* find last nonzero line below iFirstLine, use it as start offset */
    2582      219705 :         tmp1 = shr( iFirstLine, 1 );
    2583      657767 :         FOR( ; i > tmp1; i-- )
    2584             :         {
    2585      656229 :             IF( sqQ[i] != 0 )
    2586             :             {
    2587      218167 :                 BREAK;
    2588             :             }
    2589             :         }
    2590             :         /* inv_gain2 *= (float)pow(tilt_factor, (float)i); */
    2591    15041475 :         FOR( k = 0; k < i; k++ )
    2592             :         {
    2593    14821770 :             inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
    2594             :         }
    2595             : 
    2596      219705 :         i = add( i, 1 );
    2597      219705 :         segmentOffset = i;
    2598      219705 :         move16();
    2599             :     }
    2600             : 
    2601      823390 :     IF( LE_16( nTransWidth, 3 ) )
    2602             :     {
    2603       29930 :         accu1 = 0;
    2604       29930 :         move32();
    2605       29930 :         accu2 = 0;
    2606       29930 :         move32();
    2607       29930 :         xMax = 0;
    2608       29930 :         move32();
    2609             : 
    2610     6290800 :         FOR( k = i & 0xFFFE; k < lowpassLine; k++ )
    2611             :         {
    2612     6260870 :             xMax = L_max( xMax, L_abs( x_orig[k] ) );
    2613             :         }
    2614       29930 :         s = sub( norm_l( xMax ), 4 );
    2615             : 
    2616     3160365 :         FOR( k = i & 0xFFFE; k < lowpassLine; k += 2 )
    2617             :         {
    2618             :             /* even-index bins, left sub-win */
    2619     3130435 :             tmp1 = round_fx( L_shl( x_orig[k], s ) );
    2620     3130435 :             accu1 = L_mac0( accu1, tmp1, tmp1 );
    2621             : 
    2622             :             /* odd-index bins, right sub-win */
    2623     3130435 :             tmp1 = round_fx( L_shl( x_orig[k + 1], s ) );
    2624     3130435 :             accu2 = L_mac0( accu2, tmp1, tmp1 );
    2625             :         }
    2626       29930 :         k = 0;
    2627       29930 :         move16();
    2628             : 
    2629       29930 :         if ( accu1 == 0 )
    2630             :         {
    2631          16 :             accu1 = 1;
    2632          16 :             move32();
    2633             :         }
    2634       29930 :         if ( accu2 == 0 )
    2635             :         {
    2636           1 :             accu2 = 1;
    2637           1 :             move32();
    2638             :         }
    2639             : 
    2640       29930 :         att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s );
    2641       29930 :         att = Sqrt16( att, &s );
    2642             :         BASOP_SATURATE_WARNING_OFF_EVS; /* att is always <= 1.0 */
    2643       29930 :         att = shl_o( att, s, &Overflow );
    2644             :         BASOP_SATURATE_WARNING_ON_EVS;
    2645             :     }
    2646             :     ELSE
    2647             :     {
    2648      793460 :         att = 0x7FFF;
    2649      793460 :         move16();
    2650             :     }
    2651             : 
    2652      823390 :     win = 0;
    2653      823390 :     move16();
    2654             : 
    2655   321890425 :     FOR( ; i < lowpassLine; i++ )
    2656             :     {
    2657   321067035 :         inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
    2658             : 
    2659   321067035 :         IF( sqQ[i] != 0 ) /* current line is not zero, so reset pointers */
    2660             :         {
    2661    80163762 :             IF( win > 0 )
    2662             :             {
    2663    37057351 :                 k = sub( i, segmentOffset );
    2664             : 
    2665    37057351 :                 IF( LE_16( nTransWidth, 3 ) )
    2666             :                 {
    2667      812438 :                     tmp2 = sub( k, c1 );
    2668      812438 :                     IF( tmp2 > 0 )
    2669             :                     {
    2670      319427 :                         n = L_msu( n, k, (Word16) 0x8000 );
    2671             :                     }
    2672      812438 :                     IF( tmp2 > 0 )
    2673             :                     {
    2674      319427 :                         n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
    2675             :                     }
    2676      812438 :                     IF( tmp2 <= 0 )
    2677             :                     {
    2678      493011 :                         n = L_mac( n, int_sqr[k], c2 );
    2679             :                     }
    2680             :                 }
    2681             :                 ELSE
    2682             :                 {
    2683    36244913 :                     tmp2 = sub( k, 12 );
    2684    36244913 :                     IF( tmp2 > 0 )
    2685             :                     {
    2686     2479565 :                         n = L_msu( n, k, (Word16) 0x8000 );
    2687             :                     }
    2688    36244913 :                     IF( tmp2 > 0 )
    2689             :                     {
    2690     2479565 :                         n = L_sub( n, 0x70000 );
    2691             :                     }
    2692    36244913 :                     IF( tmp2 <= 0 )
    2693             :                     {
    2694    33765348 :                         n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
    2695             :                     }
    2696             :                 }
    2697    92725318 :                 FOR( k = segmentOffset; k < i - win; k++ )
    2698             :                 {
    2699    55667967 :                     tmp1 = norm_l( sqQ[k] );
    2700    55667967 :                     sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
    2701    55667967 :                     sqQ[k] = 0;
    2702    55667967 :                     move32();
    2703    55667967 :                     exp_spQ[k] = 0;
    2704    55667967 :                     move16();
    2705             :                 }
    2706   145517922 :                 FOR( ; win > 0; win-- )
    2707             :                 {
    2708   108460571 :                     tmp1 = norm_l( sqQ[k] );
    2709   108460571 :                     sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
    2710   108460571 :                     exp_spQ[k] = 0;
    2711   108460571 :                     move16();
    2712   108460571 :                     sqQ[k++] = 0;
    2713   108460571 :                     move32();
    2714             :                 }
    2715             :             }
    2716    80163762 :             segmentOffset = add( i, 1 ); /* new segment might start at next line */
    2717             :         }
    2718             :         ELSE /* current line is zero, so update pointers & segment sum */
    2719             :         {
    2720   240903273 :             IF( LT_16( win, nTransWidth ) )
    2721             :             {
    2722   113449525 :                 win = add( win, 1 );
    2723             :             }
    2724             :             /* update segment sum: magnitudes scaled by smoothing function */
    2725   240903273 :             sqQ[i] = Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 );
    2726   240903273 :             move32();
    2727   240903273 :             exp_spQ[i] = add( x_orig_e, inv_gain2_e );
    2728   240903273 :             move16();
    2729             :         }
    2730             :     }
    2731      823390 :     IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */
    2732             :     {
    2733      756928 :         k = sub( i, segmentOffset );
    2734      756928 :         IF( LE_16( nTransWidth, 3 ) )
    2735             :         {
    2736       26952 :             tmp2 = sub( k, c1 );
    2737       26952 :             IF( tmp2 > 0 )
    2738             :             {
    2739       24117 :                 n = L_msu( n, k, (Word16) 0x8000 );
    2740             :             }
    2741       26952 :             IF( tmp2 > 0 )
    2742             :             {
    2743       24117 :                 n = L_mac( n, nTransWidth_1, (Word16) 0x8000 );
    2744             :             }
    2745       26952 :             IF( tmp2 <= 0 )
    2746             :             {
    2747        2835 :                 n = L_mac( n, int_sqr[k], c2 );
    2748             :             }
    2749             :         }
    2750             :         ELSE
    2751             :         {
    2752      729976 :             tmp2 = sub( k, 12 );
    2753      729976 :             IF( tmp2 > 0 )
    2754             :             {
    2755      544919 :                 n = L_msu( n, k, (Word16) 0x8000 );
    2756             :             }
    2757      729976 :             IF( tmp2 > 0 )
    2758             :             {
    2759      544919 :                 n = L_sub( n, 0x70000 );
    2760             :             }
    2761      729976 :             IF( tmp2 <= 0 )
    2762             :             {
    2763      185057 :                 n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ );
    2764             :             }
    2765             :         }
    2766    72542709 :         FOR( k = segmentOffset; k < i - win; k++ )
    2767             :         {
    2768    71785781 :             tmp1 = norm_l( sqQ[k] );
    2769    71785781 :             sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
    2770    71785781 :             exp_spQ[k] = 0;
    2771    71785781 :             move16();
    2772    71785781 :             sqQ[k] = 0;
    2773    71785781 :             move32();
    2774             :         }
    2775     5745882 :         FOR( ; win > 0; win-- )
    2776             :         {
    2777     4988954 :             tmp1 = norm_l( sqQ[k] );
    2778     4988954 :             sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg );
    2779     4988954 :             exp_spQ[k] = 0;
    2780     4988954 :             move16();
    2781     4988954 :             sqQ[k++] = 0;
    2782     4988954 :             move32();
    2783             :         }
    2784             :     }
    2785             :     Word32 tmp4;
    2786             :     /* noise level factor: average of segment magnitudes of noise bins */
    2787      823390 :     IF( n > 0 )
    2788             :     {
    2789      823390 :         tmp4 = BASOP_Util_Divide3232_Scale_newton( Mpy_32_16_1( sqErrorNrg, att ), n, &s );
    2790      823390 :         s = add( add( exp_sqErrorNrg, -15 ), s );
    2791             :         BASOP_SATURATE_WARNING_OFF_EVS;
    2792      823390 :         tmp4 = L_shl_o( tmp4, s, &Overflow );
    2793             :         BASOP_SATURATE_WARNING_ON_EVS;
    2794             :     }
    2795             :     ELSE
    2796             :     {
    2797           0 :         tmp4 = 0;
    2798           0 :         move16();
    2799             :     }
    2800   988891390 :     FOR( j = 0; j < N_MAX; j++ )
    2801             :     {
    2802   988068000 :         sqQ[j] = L_shl( sqQ[j], sub( x_orig_e, exp_spQ[j] ) );
    2803   988068000 :         move32();
    2804             :     }
    2805             :     /* quantize, dequantize noise level factor (range 0.09375 - 0.65625) */
    2806      823390 :     tmp2 = round_fx( L_shr( Mpy_32_16_1( tmp4, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) );
    2807      823390 :     if ( GT_16( tmp2, ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1 ) )
    2808             :     {
    2809       35799 :         tmp2 = ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1;
    2810       35799 :         move16();
    2811             :     }
    2812             : 
    2813      823390 :     *quantized_fac_ns = tmp2;
    2814      823390 :     move16();
    2815             : 
    2816      823390 :     *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) );
    2817      823390 :     move16();
    2818      823390 : }
    2819             : 
    2820             : 
    2821         662 : void tcx_encoder_memory_update_fx(
    2822             :     Word16 *wsig,        /* i : target weighted signal */
    2823             :     Word16 *xn_buf,      /* i/o: mdct output buffer/time domain weigthed synthesis        */
    2824             :     Word16 L_frame_glob, /* i: global frame length                         */
    2825             :     const Word16 *Ai,    /* i: Unquantized (interpolated) LPC coefficients */
    2826             :     const Word16 *A,     /* i: Quantized LPC coefficients                  */
    2827             :     Word16 preemph,      /* i: preemphasis factor                          */
    2828             :     LPD_state *LPDmem,   /* i/o: coder memory state                        */
    2829             :     Encoder_State *st,
    2830             :     Word16 *synthout,
    2831             :     Word16 Q_new,
    2832             :     Word16 shift )
    2833             : {
    2834             :     Word16 tmp;
    2835             :     Word16 buf[1 + M + LFAC + L_FRAME_PLUS];
    2836             :     Word16 *synth;
    2837             : 
    2838             : 
    2839             :     /* Output synth */
    2840         662 :     Copy( xn_buf, synthout, L_frame_glob );
    2841             : 
    2842             : 
    2843             :     /* Update synth */
    2844         662 :     synth = buf + M + 1;
    2845         662 :     Copy( LPDmem->syn, buf, M + 1 );
    2846             : 
    2847         662 :     Copy( xn_buf, synth, L_frame_glob );
    2848         662 :     Copy( synth + sub( L_frame_glob, M + 1 ), LPDmem->syn, M + 1 );
    2849             : 
    2850         662 :     IF( st->tcxonly == 0 )
    2851             :     {
    2852             :         /* Update weighted synthesis */
    2853         662 :         Residu3_fx( Ai + ( st->nb_subfr - 1 ) * ( M + 1 ), synth + sub( L_frame_glob, 1 ), &tmp, 1, Q_new + shift - 1 );
    2854         662 :         LPDmem->mem_w0 = sub( wsig[sub( L_frame_glob, 1 )], tmp );
    2855         662 :         move16();
    2856         662 :         LPDmem->mem_w0 = shr_sat( LPDmem->mem_w0, shift ); /*Qnew-1*/
    2857         662 :         move16();
    2858             :     }
    2859             : 
    2860             : 
    2861             :     /* Emphasis of synth -> synth_pe */
    2862         662 :     tmp = synth[-( M + 1 )];
    2863         662 :     move16();
    2864         662 :     E_UTIL_f_preemph2( Q_new - 1, synth - M, preemph, add( M, L_frame_glob ), &tmp );
    2865             : 
    2866         662 :     Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M );
    2867         662 :     Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M );
    2868         662 :     Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM );
    2869             : 
    2870         662 :     test();
    2871         662 :     IF( st->tcxonly == 0 || LE_16( L_frame_glob, L_FRAME16k ) )
    2872             :     {
    2873             :         /* Update excitation */
    2874         662 :         IF( LT_16( L_frame_glob, L_EXC_MEM ) )
    2875             :         {
    2876         260 :             Copy( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ) );
    2877         260 :             Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 1 );
    2878             :         }
    2879             :         ELSE
    2880             :         {
    2881         402 :             Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 1 );
    2882             :         }
    2883             :     }
    2884         662 : }
    2885             : 
    2886      235779 : void tcx_encoder_memory_update_ivas_fx(
    2887             :     Word16 *wsig,        /* i : target weighted signal, Q_new */
    2888             :     Word16 *xn_buf,      /* i/o: mdct output buffer/time domain weigthed synthesis, Q_new        */
    2889             :     Word16 L_frame_glob, /* i: global frame length                         */
    2890             :     const Word16 *Ai,    /* i: Unquantized (interpolated) LPC coefficients, Q12 */
    2891             :     const Word16 *A,     /* i: Quantized LPC coefficients, Q = 14 - norm_s(A[0]) */
    2892             :     Word16 preemph,      /* i: preemphasis factor, Q15                          */
    2893             :     LPD_state *LPDmem,   /* i/o: coder memory state                        */
    2894             :     Encoder_State *st,
    2895             :     Word16 *synthout, /* Q_new */
    2896             :     Word16 Q_new )
    2897             : {
    2898             :     Word16 tmp;
    2899             :     Word16 buf[1 + M + LFAC + L_FRAME_PLUS];
    2900             :     Word16 *synth;
    2901             : 
    2902             : 
    2903             :     /* Output synth */
    2904      235779 :     Copy( xn_buf, synthout, L_frame_glob );
    2905             : 
    2906             : 
    2907             :     /* Update synth */
    2908      235779 :     synth = buf + M + 1;
    2909      235779 :     Copy( LPDmem->syn, buf, M + 1 );
    2910             : 
    2911      235779 :     Copy( xn_buf, synth, L_frame_glob );
    2912      235779 :     Copy( synth + sub( L_frame_glob, M + 1 ), LPDmem->syn, M + 1 );
    2913      235779 :     LPDmem->q_lpd_syn = Q_new;
    2914      235779 :     move16();
    2915             : 
    2916      235779 :     IF( st->tcxonly == 0 )
    2917             :     {
    2918             :         /* Update weighted synthesis */
    2919      128905 :         Residu3_fx( Ai + imult1616( sub( st->nb_subfr, 1 ), ( M + 1 ) ), synth + sub( L_frame_glob, 1 ), &tmp, 1, 0 );
    2920      128905 :         LPDmem->mem_w0 = sub_sat( wsig[L_frame_glob - 1], tmp );
    2921      128905 :         move16();
    2922             :     }
    2923             : 
    2924             : 
    2925             :     /* Emphasis of synth -> synth_pe */
    2926      235779 :     tmp = synth[-( M + 1 )];
    2927      235779 :     move16();
    2928      235779 :     E_UTIL_f_preemph2( 0, synth - M, preemph, add( M, L_frame_glob ), &tmp ); // Q_new
    2929             : 
    2930      235779 :     Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M );
    2931      235779 :     Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M );
    2932      235779 :     Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM );
    2933             : 
    2934             :     /* Aligning the Q-factor of the remaining synthesis memory buffers */
    2935      235779 :     Scale_sig( LPDmem->mem_syn1_fx, M, sub( Q_new, LPDmem->q_mem_syn ) );
    2936      235779 :     Scale_sig( LPDmem->mem_syn3, M, sub( Q_new, LPDmem->q_mem_syn ) );
    2937             : 
    2938      235779 :     LPDmem->q_mem_syn = Q_new; // resultant q of synth after E_UTIL_f_preemph2
    2939      235779 :     move16();
    2940             : 
    2941      235779 :     test();
    2942      235779 :     IF( st->tcxonly == 0 || LE_16( L_frame_glob, L_FRAME16k ) )
    2943             :     {
    2944             :         /* Update excitation */
    2945      129405 :         IF( LT_16( L_frame_glob, L_EXC_MEM ) )
    2946             :         {
    2947       54598 :             Word16 shift = norm_arr( LPDmem->old_exc + L_frame_glob, sub( L_EXC_MEM, L_frame_glob ) );
    2948       54598 :             IF( LT_16( shift, sub( Q_new, LPDmem->q_lpd_old_exc ) ) )
    2949             :             {
    2950           0 :                 Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), shift );
    2951           0 :                 LPDmem->q_lpd_old_exc = add( LPDmem->q_lpd_old_exc, shift );
    2952           0 :                 move16();
    2953           0 :                 Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, sub( LPDmem->q_lpd_old_exc, Q_new ) ); // LPDmem->q_lpd_old_exc
    2954             :             }
    2955             :             ELSE
    2956             :             {
    2957       54598 :                 Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), sub( Q_new, LPDmem->q_lpd_old_exc ) );
    2958       54598 :                 Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 0 ); // Q_new
    2959       54598 :                 LPDmem->q_lpd_old_exc = Q_new;
    2960       54598 :                 move16();
    2961             :             }
    2962             :         }
    2963             :         ELSE
    2964             :         {
    2965       74807 :             Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 0 ); // Q_new
    2966       74807 :             LPDmem->q_lpd_old_exc = Q_new;
    2967       74807 :             move16();
    2968             :         }
    2969             :     }
    2970      235779 : }
    2971             : 
    2972             : 
    2973             : /*---------------------------------------------------------------
    2974             :  * Residual Quantization
    2975             :  *--------------------------------------------------------------*/
    2976             : 
    2977             : /* Returns: number of bits used (including "bits")  Q0 */
    2978           0 : Word16 tcx_ari_res_Q_spec_fx(
    2979             :     const Word32 x_orig[], /* i: original spectrum                   Q31-e */
    2980             :     Word16 x_orig_e,       /* i: original spectrum exponent          Q0 */
    2981             :     const Word16 signs[],  /* i: signs (x_orig[.]<0)                 Q0 */
    2982             :     Word32 x_Q[],          /* i/o: quantized spectrum                Q31-e */
    2983             :     Word16 x_Q_e,          /* i: quantized spectrum exponent         Q0 */
    2984             :     Word16 L_frame,        /* i: number of lines                     Q0 */
    2985             :     Word16 gain,           /* i: TCX gain                            Q15-e */
    2986             :     Word16 gain_e,         /* i: TCX gain exponent                   Q0 */
    2987             :     Word16 prm[],          /* o: bit-stream                          Q0 */
    2988             :     Word16 target_bits,    /* i: number of bits available            Q0 */
    2989             :     Word16 bits,           /* i: number of bits used so far          Q0 */
    2990             :     Word16 deadzone,       /* i: quantizer deadzone                  Q15 */
    2991             :     const Word16 x_fac[]   /* i: spectrum post-quantization factors  Q14 */
    2992             : )
    2993             : {
    2994             :     Word16 i, j, num_zeros;
    2995             :     Word16 zeros[L_FRAME_PLUS];
    2996             :     Word16 fac_p, sign;
    2997             :     Word32 thres, x_Q_m, x_Q_p;
    2998             :     Word32 L_tmp, L_tmp2;
    2999             :     Word16 s, s2;
    3000             : 
    3001             : 
    3002             :     /* Limit the number of residual bits */
    3003           0 :     target_bits = s_min( target_bits, NPRM_RESQ );
    3004             : 
    3005             : 
    3006             :     /* Requantize the spectrum line-by-line */
    3007             :     /* fac_m = deadzone * 0.5f;
    3008             :        fac_p = 0.5f - fac_m; */
    3009           0 :     num_zeros = 0;
    3010           0 :     move16();
    3011             : 
    3012           0 :     s = sub( add( gain_e, x_Q_e ), x_orig_e );
    3013           0 :     FOR( i = 0; i < L_frame; i++ )
    3014             :     {
    3015           0 :         IF( GE_16( bits, target_bits ) ) /* no bits left */
    3016             :         {
    3017           0 :             BREAK;
    3018             :         }
    3019             : 
    3020           0 :         IF( x_Q[i] != 0 )
    3021             :         {
    3022           0 :             sign = x_fac[i];
    3023           0 :             move16();
    3024           0 :             IF( signs[i] != 0 )
    3025             :             {
    3026           0 :                 sign = negate( sign );
    3027             :             }
    3028             : 
    3029             :             /* x_Q_m = x_Q[i] - sign*fac_m;
    3030             :                x_Q_p = x_Q[i] + sign*fac_p; */
    3031             : 
    3032           0 :             L_tmp = L_mult( sign, deadzone ); /* sign*deadzone/2 in Q31 */
    3033           0 :             x_Q_m = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
    3034             : 
    3035           0 :             L_tmp = L_mac( L_tmp, sign, (Word16) 0x8000 ); /* sign*(deadzone-1)/2 in Q31 */
    3036           0 :             x_Q_p = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
    3037             : 
    3038             :             /* if (fabs(x_orig[i] - gain * x_Q_m) < fabs(x_orig[i] - gain * x_Q_p)) */
    3039           0 :             L_tmp = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_m, gain ), s ) ) );
    3040           0 :             L_tmp2 = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_p, gain ), s ) ) );
    3041             : 
    3042           0 :             IF( LT_32( L_tmp, L_tmp2 ) ) /* Decrease magnitude */
    3043             :             {
    3044           0 :                 x_Q[i] = x_Q_m;
    3045           0 :                 move32();
    3046           0 :                 prm[bits] = 0;
    3047           0 :                 move16();
    3048             :             }
    3049             :             ELSE /* Increase magnitude */
    3050             :             {
    3051           0 :                 x_Q[i] = x_Q_p;
    3052           0 :                 move32();
    3053           0 :                 prm[bits] = 1;
    3054           0 :                 move16();
    3055             :             }
    3056           0 :             bits = add( bits, 1 );
    3057             :         }
    3058             :         ELSE
    3059             :         {
    3060           0 :             zeros[num_zeros] = i;
    3061           0 :             move16();
    3062           0 :             num_zeros = add( num_zeros, 1 );
    3063             :         }
    3064             :     }
    3065             : 
    3066             :     /* Requantize zeroed-lines of the spectrum */
    3067           0 :     fac_p = msu_r( 1417339264l /*2*0.33f Q31*/, deadzone, 21627 /*2*0.33f Q15*/ ); /* Q16 */
    3068           0 :     target_bits = sub( target_bits, 1 );                                           /* reserve 1 bit for the check below */
    3069             : 
    3070           0 :     s = sub( gain_e, x_orig_e );
    3071           0 :     s2 = sub( x_Q_e, 1 );
    3072           0 :     FOR( j = 0; j < num_zeros; j++ )
    3073             :     {
    3074           0 :         IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
    3075             :         {
    3076           0 :             BREAK;
    3077             :         }
    3078             : 
    3079           0 :         i = zeros[j];
    3080           0 :         move16();
    3081             : 
    3082           0 :         thres = L_mult( fac_p, x_fac[i] ); /* Q31 */
    3083             : 
    3084           0 :         IF( GT_32( L_abs( x_orig[i] ), L_shl( Mpy_32_16_1( thres, gain ), s ) ) )
    3085             :         {
    3086           0 :             prm[bits] = 1;
    3087           0 :             move16();
    3088           0 :             bits = add( bits, 1 );
    3089             : 
    3090           0 :             prm[bits] = sub( 1, signs[i] );
    3091           0 :             move16();
    3092           0 :             bits = add( bits, 1 );
    3093             : 
    3094           0 :             L_tmp = L_shr( thres, s2 );
    3095           0 :             IF( signs[i] )
    3096             :             {
    3097           0 :                 L_tmp = L_negate( L_tmp );
    3098             :             }
    3099           0 :             x_Q[i] = L_tmp;
    3100           0 :             move32();
    3101             :         }
    3102             :         ELSE
    3103             :         {
    3104           0 :             prm[bits] = 0;
    3105           0 :             move16();
    3106           0 :             bits = add( bits, 1 );
    3107             :         }
    3108             :     }
    3109             : 
    3110             : 
    3111           0 :     return bits;
    3112             : }
    3113             : 
    3114       17495 : Word16 tcx_ari_res_Q_spec_ivas_fx(
    3115             :     const Word32 x_orig[], /* i: original spectrum                   Q31-e */
    3116             :     Word16 x_orig_e,       /* i: original spectrum exponent          Q0 */
    3117             :     const Word16 signs[],  /* i: signs (x_orig[.]<0)                 Q0 */
    3118             :     Word32 x_Q[],          /* i/o: quantized spectrum                Q31-e */
    3119             :     Word16 x_Q_e,          /* i: quantized spectrum exponent         Q0 */
    3120             :     Word16 L_frame,        /* i: number of lines                     Q0 */
    3121             :     Word16 gain,           /* i: TCX gain                            Q15-e */
    3122             :     Word16 gain_e,         /* i: TCX gain exponent                   Q0 */
    3123             :     Word16 prm[],          /* o: bit-stream                          Q0 */
    3124             :     Word16 target_bits,    /* i: number of bits available            Q0 */
    3125             :     Word16 bits,           /* i: number of bits used so far          Q0 */
    3126             :     Word16 deadzone,       /* i: quantizer deadzone                  Q15 */
    3127             :     const Word16 x_fac[]   /* i: spectrum post-quantization factors  Q14 */
    3128             : )
    3129             : {
    3130             :     Word16 i, j, num_zeros;
    3131             :     Word16 zeros[L_FRAME_PLUS];
    3132             :     Word16 fac_p, sign;
    3133             :     Word32 thres, x_Q_m, x_Q_p;
    3134             :     Word32 L_tmp, L_tmp2;
    3135             :     Word16 s, s2;
    3136             : 
    3137             : 
    3138             :     /* Limit the number of residual bits */
    3139       17495 :     target_bits = s_min( target_bits, NPRM_RESQ );
    3140             : 
    3141             : 
    3142             :     /* Requantize the spectrum line-by-line */
    3143             :     /* fac_m = deadzone * 0.5f;
    3144             :        fac_p = 0.5f - fac_m; */
    3145       17495 :     num_zeros = 0;
    3146       17495 :     move16();
    3147       17495 :     s = sub( add( gain_e, x_Q_e ), x_orig_e );
    3148       17495 :     IF( x_fac == NULL )
    3149             :     {
    3150           0 :         FOR( i = 0; i < L_frame; ++i )
    3151             :         {
    3152           0 :             IF( GE_16( bits, target_bits ) ) /* no bits left */
    3153             :             {
    3154           0 :                 BREAK;
    3155             :             }
    3156             : 
    3157           0 :             IF( x_Q[i] != 0 )
    3158             :             {
    3159           0 :                 sign = shl( sub( 1, shl( signs[i], 1 ) ), Q14 );
    3160           0 :                 move16();
    3161             : 
    3162             :                 /* x_Q_m = x_Q[i] - sign*fac_m;
    3163             :                    x_Q_p = x_Q[i] + sign*fac_p; */
    3164             : 
    3165           0 :                 L_tmp = L_mult( sign, deadzone ); /* sign*deadzone/2 in Q31 */
    3166           0 :                 x_Q_m = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
    3167             : 
    3168           0 :                 L_tmp = L_mac( L_tmp, sign, (Word16) 0x8000 ); /* sign*(deadzone-1)/2 in Q31 */
    3169           0 :                 x_Q_p = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
    3170             : 
    3171             :                 /* if (fabs(x_orig[i] - gain * x_Q_m) < fabs(x_orig[i] - gain * x_Q_p)) */
    3172           0 :                 L_tmp = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_m, gain ), s ) ) );
    3173           0 :                 L_tmp2 = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_p, gain ), s ) ) );
    3174             : 
    3175           0 :                 IF( LT_32( L_tmp, L_tmp2 ) ) /* Decrease magnitude */
    3176             :                 {
    3177           0 :                     x_Q[i] = x_Q_m;
    3178           0 :                     move32();
    3179           0 :                     prm[bits] = 0;
    3180           0 :                     move16();
    3181             :                 }
    3182             :                 ELSE /* Increase magnitude */
    3183             :                 {
    3184           0 :                     x_Q[i] = x_Q_p;
    3185           0 :                     move32();
    3186           0 :                     prm[bits] = 1;
    3187           0 :                     move16();
    3188             :                 }
    3189           0 :                 bits = add( bits, 1 );
    3190             :             }
    3191             :             ELSE
    3192             :             {
    3193           0 :                 zeros[num_zeros] = i;
    3194           0 :                 move16();
    3195           0 :                 num_zeros = add( num_zeros, 1 );
    3196             :             }
    3197             :         }
    3198             : 
    3199             :         /* Requantize zeroed-lines of the spectrum */
    3200           0 :         fac_p = msu_r( 1417339264l /*2*0.33f Q31*/, deadzone, 21627 /*2*0.33f Q15*/ ); /* Q16 */
    3201           0 :         target_bits = sub( target_bits, 1 );                                           /* reserve 1 bit for the check below */
    3202             : 
    3203           0 :         s = sub( gain_e, x_orig_e );
    3204           0 :         s2 = sub( x_Q_e, 1 );
    3205           0 :         FOR( j = 0; j < num_zeros; j++ )
    3206             :         {
    3207           0 :             IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
    3208             :             {
    3209           0 :                 BREAK;
    3210             :             }
    3211             : 
    3212           0 :             i = zeros[j];
    3213           0 :             move16();
    3214             : 
    3215           0 :             thres = L_shl( fac_p, Q15 ); /* Q31 */
    3216             : 
    3217           0 :             IF( GT_32( L_abs( x_orig[i] ), L_shl( Mpy_32_16_1( thres, gain ), s ) ) )
    3218             :             {
    3219           0 :                 prm[bits] = 1;
    3220           0 :                 move16();
    3221           0 :                 bits = add( bits, 1 );
    3222             : 
    3223           0 :                 prm[bits] = sub( 1, signs[i] );
    3224           0 :                 move16();
    3225           0 :                 bits = add( bits, 1 );
    3226             : 
    3227           0 :                 L_tmp = L_shr( thres, s2 );
    3228           0 :                 IF( signs[i] )
    3229             :                 {
    3230           0 :                     L_tmp = L_negate( L_tmp );
    3231             :                 }
    3232           0 :                 x_Q[i] = L_tmp;
    3233           0 :                 move32();
    3234             :             }
    3235             :             ELSE
    3236             :             {
    3237           0 :                 prm[bits] = 0;
    3238           0 :                 move16();
    3239           0 :                 bits = add( bits, 1 );
    3240             :             }
    3241             :         }
    3242             : 
    3243           0 :         return bits;
    3244             :     }
    3245             : 
    3246       17495 :     s = sub( add( gain_e, x_Q_e ), x_orig_e );
    3247      763741 :     FOR( i = 0; i < L_frame; i++ )
    3248             :     {
    3249      762577 :         IF( GE_16( bits, target_bits ) ) /* no bits left */
    3250             :         {
    3251       16331 :             BREAK;
    3252             :         }
    3253             : 
    3254      746246 :         IF( x_Q[i] != 0 )
    3255             :         {
    3256       15627 :             sign = x_fac[i];
    3257       15627 :             move16();
    3258       15627 :             IF( signs[i] != 0 )
    3259             :             {
    3260        7794 :                 sign = negate( sign );
    3261             :             }
    3262             : 
    3263             :             /* x_Q_m = x_Q[i] - sign*fac_m;
    3264             :                x_Q_p = x_Q[i] + sign*fac_p; */
    3265             : 
    3266       15627 :             L_tmp = L_mult( sign, deadzone ); /* sign*deadzone/2 in Q31 */
    3267       15627 :             x_Q_m = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
    3268             : 
    3269       15627 :             L_tmp = L_mac( L_tmp, sign, (Word16) 0x8000 ); /* sign*(deadzone-1)/2 in Q31 */
    3270       15627 :             x_Q_p = L_sub( x_Q[i], L_shr( L_tmp, x_Q_e ) );
    3271             : 
    3272             :             /* if (fabs(x_orig[i] - gain * x_Q_m) < fabs(x_orig[i] - gain * x_Q_p)) */
    3273       15627 :             L_tmp = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_m, gain ), s ) ) );
    3274       15627 :             L_tmp2 = L_abs( L_sub( x_orig[i], L_shl( Mpy_32_16_1( x_Q_p, gain ), s ) ) );
    3275             : 
    3276       15627 :             IF( LT_32( L_tmp, L_tmp2 ) ) /* Decrease magnitude */
    3277             :             {
    3278        9730 :                 x_Q[i] = x_Q_m;
    3279        9730 :                 move32();
    3280        9730 :                 prm[bits] = 0;
    3281        9730 :                 move16();
    3282             :             }
    3283             :             ELSE /* Increase magnitude */
    3284             :             {
    3285        5897 :                 x_Q[i] = x_Q_p;
    3286        5897 :                 move32();
    3287        5897 :                 prm[bits] = 1;
    3288        5897 :                 move16();
    3289             :             }
    3290       15627 :             bits = add( bits, 1 );
    3291             :         }
    3292             :         ELSE
    3293             :         {
    3294      730619 :             zeros[num_zeros] = i;
    3295      730619 :             move16();
    3296      730619 :             num_zeros = add( num_zeros, 1 );
    3297             :         }
    3298             :     }
    3299             : 
    3300             :     /* Requantize zeroed-lines of the spectrum */
    3301       17495 :     fac_p = msu_r( 1417339264l /*2*0.33f Q31*/, deadzone, 21627 /*2*0.33f Q15*/ ); /* Q16 */
    3302       17495 :     target_bits = sub( target_bits, 1 );                                           /* reserve 1 bit for the check below */
    3303             : 
    3304       17495 :     s = sub( gain_e, x_orig_e );
    3305       17495 :     s2 = sub( x_Q_e, 1 );
    3306       56296 :     FOR( j = 0; j < num_zeros; j++ )
    3307             :     {
    3308       40456 :         IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
    3309             :         {
    3310        1655 :             BREAK;
    3311             :         }
    3312             : 
    3313       38801 :         i = zeros[j];
    3314       38801 :         move16();
    3315             : 
    3316       38801 :         thres = L_mult( fac_p, x_fac[i] ); /* Q31 */
    3317             : 
    3318       38801 :         IF( GT_32( L_abs( x_orig[i] ), L_shl( Mpy_32_16_1( thres, gain ), s ) ) )
    3319             :         {
    3320        8819 :             prm[bits] = 1;
    3321        8819 :             move16();
    3322        8819 :             bits = add( bits, 1 );
    3323             : 
    3324        8819 :             prm[bits] = sub( 1, signs[i] );
    3325        8819 :             move16();
    3326        8819 :             bits = add( bits, 1 );
    3327             : 
    3328        8819 :             L_tmp = L_shr( thres, s2 );
    3329        8819 :             IF( signs[i] )
    3330             :             {
    3331        4550 :                 L_tmp = L_negate( L_tmp );
    3332             :             }
    3333        8819 :             x_Q[i] = L_tmp;
    3334        8819 :             move32();
    3335             :         }
    3336             :         ELSE
    3337             :         {
    3338       29982 :             prm[bits] = 0;
    3339       29982 :             move16();
    3340       29982 :             bits = add( bits, 1 );
    3341             :         }
    3342             :     }
    3343             : 
    3344             : 
    3345       17495 :     return bits;
    3346             : }
    3347             : 
    3348             : #define kMaxEstimatorOvershoot  5
    3349             : #define kMaxEstimatorUndershoot 0
    3350             : 
    3351      373523 : Word16 tcx_res_Q_gain_fx(
    3352             :     Word16 sqGain,
    3353             :     Word16 sqGain_e,
    3354             :     Word16 *gain_tcx,
    3355             :     Word16 *gain_tcx_e,
    3356             :     Word16 *prm,
    3357             :     Word16 sqTargetBits )
    3358             : {
    3359             :     Word16 bits;
    3360             :     Word16 gain_reQ, gain_reQ_e;
    3361             : 
    3362             :     /*Refine the gain quantization : Normal greedy gain coding */
    3363             : 
    3364      373523 :     gain_reQ = *gain_tcx;
    3365      373523 :     move16();
    3366      373523 :     gain_reQ_e = *gain_tcx_e;
    3367      373523 :     move16();
    3368             : 
    3369             :     /* make sure we have a bit of headroom */
    3370      373523 :     IF( GT_16( gain_reQ, 0x7000 ) )
    3371             :     {
    3372       18467 :         gain_reQ = shr( gain_reQ, 1 );
    3373       18467 :         gain_reQ_e = add( gain_reQ_e, 1 );
    3374             :     }
    3375             : 
    3376             :     /* bring sqGain to same exponent */
    3377      373523 :     sqGain = shr_sat( sqGain, sub( gain_reQ_e, sqGain_e ) );
    3378     1494092 :     FOR( bits = 0; bits < TCX_RES_Q_BITS_GAIN; bits++ )
    3379             :     {
    3380     1120569 :         IF( LT_16( sqGain, gain_reQ ) )
    3381             :         {
    3382      572018 :             prm[bits] = 0;
    3383      572018 :             move16();
    3384      572018 :             gain_reQ = mult_r( gain_reQ, gain_corr_inv_fac[bits] );
    3385             :         }
    3386             :         ELSE
    3387             :         {
    3388      548551 :             prm[bits] = 1;
    3389      548551 :             move16();
    3390      548551 :             gain_reQ = shl( mult_r( gain_reQ, gain_corr_fac[bits] ), 1 );
    3391             :         }
    3392             : 
    3393     1120569 :         IF( LT_16( bits, sqTargetBits ) )
    3394             :         {
    3395      874530 :             *gain_tcx = gain_reQ;
    3396      874530 :             move16();
    3397      874530 :             *gain_tcx_e = gain_reQ_e;
    3398      874530 :             move16();
    3399             :         }
    3400             :     }
    3401             : 
    3402             : 
    3403      373523 :     return bits;
    3404             : }
    3405             : 
    3406         662 : Word16 tcx_res_Q_spec_fx(
    3407             :     Word32 *x_orig,
    3408             :     Word16 x_orig_e,
    3409             :     Word32 *x_Q,
    3410             :     Word16 x_Q_e,
    3411             :     Word16 L_frame,
    3412             :     Word16 sqGain,
    3413             :     Word16 sqGain_e,
    3414             :     Word16 *prm,
    3415             :     Word16 sqTargetBits,
    3416             :     Word16 bits,
    3417             :     Word16 sq_round,
    3418             :     const Word16 lf_deemph_factors[] /* 1Q14 */
    3419             : )
    3420             : {
    3421             :     Word16 i;
    3422             :     Word16 fac_m, fac_p;
    3423             :     Word32 tmp1, tmp2;
    3424             :     Word16 s, s2, lf_deemph_factor;
    3425             :     Word16 c;
    3426             :     Word32 thres;
    3427             : 
    3428             : 
    3429             :     /* Limit the number of residual bits */
    3430         662 :     sqTargetBits = s_min( sqTargetBits, NPRM_RESQ );
    3431             : 
    3432             :     /* Requantize the spectrum line-by-line */
    3433         662 :     fac_m = shr( sq_round, 1 );
    3434         662 :     fac_p = sub( 0x4000, fac_m );
    3435             : 
    3436             :     /* exponent difference of x_orig and x_Q * sqGain */
    3437         662 :     s = sub( x_orig_e, add( x_Q_e, sqGain_e ) );
    3438             : 
    3439         662 :     lf_deemph_factor = 0x4000;
    3440         662 :     move16();
    3441         662 :     s2 = sub( x_Q_e, 1 );
    3442             : 
    3443       50467 :     FOR( i = 0; i < L_frame; i++ )
    3444             :     {
    3445       50410 :         IF( GE_16( bits, sub( sqTargetBits, kMaxEstimatorUndershoot ) ) )
    3446             :         {
    3447       16061 :             fac_m = 0;
    3448       16061 :             move16();
    3449       16061 :             fac_p = 0;
    3450       16061 :             move16();
    3451             : 
    3452       16061 :             IF( GE_16( bits, s_min( NPRM_RESQ, add( sqTargetBits, kMaxEstimatorOvershoot ) ) ) )
    3453             :             {
    3454         605 :                 BREAK;
    3455             :             }
    3456             :         }
    3457             : 
    3458       49805 :         test();
    3459       49805 :         test();
    3460       49805 :         IF( ( x_Q[i] != 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
    3461             :         {
    3462        5989 :             tmp1 = L_add( x_orig[i], 0 );
    3463        5989 :             tmp2 = Mpy_32_16_1( x_Q[i], sqGain );
    3464        5989 :             IF( s > 0 )
    3465             :             {
    3466        2284 :                 tmp2 = L_shr( tmp2, s );
    3467             :             }
    3468        5989 :             IF( s < 0 )
    3469             :             {
    3470        3395 :                 tmp1 = L_shl( tmp1, s );
    3471             :             }
    3472             : 
    3473        5989 :             if ( lf_deemph_factors != NULL )
    3474             :             {
    3475        5989 :                 lf_deemph_factor = lf_deemph_factors[i];
    3476        5989 :                 move16();
    3477             :             }
    3478             : 
    3479        5989 :             IF( LT_32( tmp1, tmp2 ) )
    3480             :             {
    3481        2991 :                 prm[bits] = 0;
    3482        2991 :                 move16();
    3483        2991 :                 bits = add( bits, 1 );
    3484             : 
    3485        2991 :                 IF( x_Q[i] > 0 )
    3486             :                 {
    3487        1536 :                     tmp1 = L_mult( fac_m, lf_deemph_factor );
    3488             :                 }
    3489        2991 :                 IF( x_Q[i] < 0 )
    3490             :                 {
    3491        1455 :                     tmp1 = L_mult( fac_p, lf_deemph_factor );
    3492             :                 }
    3493        2991 :                 x_Q[i] = L_sub( x_Q[i], L_shr( tmp1, s2 ) );
    3494        2991 :                 move32();
    3495             :             }
    3496             :             ELSE
    3497             :             {
    3498        2998 :                 prm[bits] = 1;
    3499        2998 :                 move16();
    3500        2998 :                 bits = add( bits, 1 );
    3501             : 
    3502        2998 :                 IF( x_Q[i] > 0 )
    3503             :                 {
    3504        1421 :                     tmp1 = L_mult( fac_p, lf_deemph_factor );
    3505             :                 }
    3506        2998 :                 IF( x_Q[i] < 0 )
    3507             :                 {
    3508        1577 :                     tmp1 = L_mult( fac_m, lf_deemph_factor );
    3509             :                 }
    3510        2998 :                 x_Q[i] = L_add( x_Q[i], L_shr( tmp1, s2 ) );
    3511        2998 :                 move32();
    3512             :             }
    3513             :         }
    3514             :     }
    3515             : 
    3516             :     /*Quantize zeroed-line of the spectrum*/
    3517         662 :     c = sub( 21627 /*0.66f Q15*/, mult_r( sq_round, 21627 /*0.66f Q15*/ ) );
    3518             : 
    3519        2471 :     FOR( i = 0; i < L_frame; i++ )
    3520             :     {
    3521        2471 :         IF( GE_16( bits, sub( sqTargetBits, 2 ) ) )
    3522             :         {
    3523         662 :             BREAK;
    3524             :         }
    3525             : 
    3526        1809 :         test();
    3527        1809 :         test();
    3528        1809 :         IF( ( x_Q[i] == 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
    3529             :         {
    3530         882 :             if ( lf_deemph_factors != NULL )
    3531             :             {
    3532         882 :                 lf_deemph_factor = lf_deemph_factors[i];
    3533         882 :                 move16();
    3534             :             }
    3535             : 
    3536         882 :             thres = L_mult( c, lf_deemph_factor );
    3537         882 :             tmp1 = L_shl( Mpy_32_16_1( thres, sqGain ), sub( sqGain_e, x_orig_e ) );
    3538             : 
    3539         882 :             IF( GT_32( x_orig[i], tmp1 ) )
    3540             :             {
    3541         258 :                 prm[bits] = 1;
    3542         258 :                 move16();
    3543         258 :                 bits = add( bits, 1 );
    3544             : 
    3545         258 :                 prm[bits] = 1;
    3546         258 :                 move16();
    3547         258 :                 bits = add( bits, 1 );
    3548             : 
    3549         258 :                 x_Q[i] = L_shl( thres, sub( 1, x_Q_e ) );
    3550         258 :                 move32();
    3551             :             }
    3552         624 :             ELSE IF( L_add( x_orig[i], tmp1 ) < 0 )
    3553             :             {
    3554         252 :                 prm[bits] = 1;
    3555         252 :                 move16();
    3556         252 :                 bits = add( bits, 1 );
    3557             : 
    3558         252 :                 prm[bits] = 0;
    3559         252 :                 move16();
    3560         252 :                 bits = add( bits, 1 );
    3561             : 
    3562         252 :                 x_Q[i] = L_shl( L_negate( thres ), sub( 1, x_Q_e ) );
    3563         252 :                 move32();
    3564             :             }
    3565             :             ELSE
    3566             :             {
    3567         372 :                 prm[bits] = 0;
    3568         372 :                 move16();
    3569         372 :                 bits = add( bits, 1 );
    3570             :             }
    3571             :         }
    3572             :     }
    3573             : 
    3574             :     /*Be sure that every possible bits are initialized*/
    3575       57495 :     FOR( i = bits; i < NPRM_RESQ; i++ )
    3576             :     {
    3577       56833 :         prm[i] = 0;
    3578       56833 :         move16();
    3579             :     }
    3580             : 
    3581             : 
    3582         662 :     return bits;
    3583             : }
    3584             : 
    3585      372861 : Word16 tcx_res_Q_spec_ivas_fx(
    3586             :     Word32 *x_orig,
    3587             :     Word16 x_orig_e,
    3588             :     Word32 *x_Q,
    3589             :     Word16 x_Q_e,
    3590             :     Word16 L_frame,
    3591             :     Word16 sqGain,
    3592             :     Word16 sqGain_e,
    3593             :     Word16 *prm,
    3594             :     Word16 sqTargetBits,
    3595             :     Word16 bits,
    3596             :     Word16 sq_round,
    3597             :     const Word16 lf_deemph_factors[] /* 1Q14 */
    3598             : )
    3599             : {
    3600             :     Word16 i;
    3601             :     Word16 fac_m, fac_p;
    3602             :     Word32 tmp1, tmp2;
    3603             :     Word16 s, s2, lf_deemph_factor;
    3604             :     Word16 c;
    3605             :     Word32 thres;
    3606             : 
    3607             : 
    3608             :     /* Limit the number of residual bits */
    3609      372861 :     sqTargetBits = s_min( sqTargetBits, NPRM_RESQ );
    3610             : 
    3611             :     /* Requantize the spectrum line-by-line */
    3612      372861 :     fac_m = shr( sq_round, 1 );
    3613      372861 :     fac_p = sub( 0x4000, fac_m );
    3614             : 
    3615             :     /* exponent difference of x_orig and x_Q * sqGain */
    3616      372861 :     s = sub( x_orig_e, add( x_Q_e, sqGain_e ) );
    3617             : 
    3618      372861 :     lf_deemph_factor = 0x4000;
    3619      372861 :     move16();
    3620      372861 :     s2 = sub( x_Q_e, 1 );
    3621             : 
    3622    17666145 :     FOR( i = 0; i < L_frame; i++ )
    3623             :     {
    3624    17651681 :         IF( GE_16( bits, sub( sqTargetBits, kMaxEstimatorUndershoot ) ) )
    3625             :         {
    3626     5366632 :             fac_m = 0;
    3627     5366632 :             move16();
    3628     5366632 :             fac_p = 0;
    3629     5366632 :             move16();
    3630             : 
    3631     5366632 :             IF( GE_16( bits, s_min( NPRM_RESQ, add( sqTargetBits, kMaxEstimatorOvershoot ) ) ) )
    3632             :             {
    3633      358397 :                 BREAK;
    3634             :             }
    3635             :         }
    3636             : 
    3637    17293284 :         test();
    3638    17293284 :         test();
    3639    17293284 :         IF( ( x_Q[i] != 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
    3640             :         {
    3641     3665965 :             tmp1 = L_add( x_orig[i], 0 );
    3642     3665965 :             tmp2 = Mpy_32_16_1( x_Q[i], sqGain );
    3643     3665965 :             IF( s > 0 )
    3644             :             {
    3645         632 :                 tmp2 = L_shr( tmp2, s );
    3646             :             }
    3647     3665965 :             IF( s < 0 )
    3648             :             {
    3649     3664845 :                 tmp1 = L_shl( tmp1, s );
    3650             :             }
    3651             : 
    3652     3665965 :             if ( lf_deemph_factors != NULL )
    3653             :             {
    3654      901443 :                 lf_deemph_factor = lf_deemph_factors[i];
    3655      901443 :                 move16();
    3656             :             }
    3657             : 
    3658     3665965 :             IF( LT_32( tmp1, tmp2 ) )
    3659             :             {
    3660     1831660 :                 prm[bits] = 0;
    3661     1831660 :                 move16();
    3662     1831660 :                 bits = add( bits, 1 );
    3663             : 
    3664     1831660 :                 IF( x_Q[i] > 0 )
    3665             :                 {
    3666      903669 :                     tmp1 = L_mult( fac_m, lf_deemph_factor );
    3667             :                 }
    3668     1831660 :                 IF( x_Q[i] < 0 )
    3669             :                 {
    3670      927991 :                     tmp1 = L_mult( fac_p, lf_deemph_factor );
    3671             :                 }
    3672     1831660 :                 x_Q[i] = L_sub( x_Q[i], L_shr( tmp1, s2 ) );
    3673     1831660 :                 move32();
    3674             :             }
    3675             :             ELSE
    3676             :             {
    3677     1834305 :                 prm[bits] = 1;
    3678     1834305 :                 move16();
    3679     1834305 :                 bits = add( bits, 1 );
    3680             : 
    3681     1834305 :                 IF( x_Q[i] > 0 )
    3682             :                 {
    3683      937480 :                     tmp1 = L_mult( fac_p, lf_deemph_factor );
    3684             :                 }
    3685     1834305 :                 IF( x_Q[i] < 0 )
    3686             :                 {
    3687      896825 :                     tmp1 = L_mult( fac_m, lf_deemph_factor );
    3688             :                 }
    3689     1834305 :                 x_Q[i] = L_add( x_Q[i], L_shr( tmp1, s2 ) );
    3690     1834305 :                 move32();
    3691             :             }
    3692             :         }
    3693             :     }
    3694             : 
    3695             :     /*Quantize zeroed-line of the spectrum*/
    3696      372861 :     c = sub( 21627 /*0.66f Q15*/, mult_r( sq_round, 21627 /*0.66f Q15*/ ) );
    3697             : 
    3698      885339 :     FOR( i = 0; i < L_frame; i++ )
    3699             :     {
    3700      885339 :         IF( GE_16( bits, sub( sqTargetBits, 2 ) ) )
    3701             :         {
    3702      372861 :             BREAK;
    3703             :         }
    3704             : 
    3705      512478 :         test();
    3706      512478 :         test();
    3707      512478 :         IF( ( x_Q[i] == 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 ) ) ) )
    3708             :         {
    3709      384200 :             if ( lf_deemph_factors != NULL )
    3710             :             {
    3711      304960 :                 lf_deemph_factor = lf_deemph_factors[i];
    3712      304960 :                 move16();
    3713             :             }
    3714             : 
    3715      384200 :             thres = L_mult( c, lf_deemph_factor ); // Q31
    3716      384200 :             Word16 shift_tmp = s_max( sqGain_e, x_orig_e );
    3717             : 
    3718      384200 :             tmp1 = Mpy_32_16_1( thres, sqGain );
    3719             : 
    3720      384200 :             IF( GT_32( L_shl( x_orig[i], sub( x_orig_e, shift_tmp ) ), L_shl( tmp1, sub( sqGain_e, shift_tmp ) ) ) )
    3721             :             {
    3722       70003 :                 prm[bits] = 1;
    3723       70003 :                 move16();
    3724       70003 :                 bits = add( bits, 1 );
    3725             : 
    3726       70003 :                 prm[bits] = 1;
    3727       70003 :                 move16();
    3728       70003 :                 bits = add( bits, 1 );
    3729             : 
    3730       70003 :                 x_Q[i] = L_shl( thres, sub( 1, x_Q_e ) );
    3731       70003 :                 move32();
    3732             :             }
    3733      314197 :             ELSE IF( L_add( L_shl( x_orig[i], sub( x_orig_e, shift_tmp ) ), L_shl( tmp1, sub( sqGain_e, shift_tmp ) ) ) < 0 )
    3734             :             {
    3735       69527 :                 prm[bits] = 1;
    3736       69527 :                 move16();
    3737       69527 :                 bits = add( bits, 1 );
    3738             : 
    3739       69527 :                 prm[bits] = 0;
    3740       69527 :                 move16();
    3741       69527 :                 bits = add( bits, 1 );
    3742             : 
    3743       69527 :                 x_Q[i] = L_shl( L_negate( thres ), sub( 1, x_Q_e ) );
    3744       69527 :                 move32();
    3745             :             }
    3746             :             ELSE
    3747             :             {
    3748      244670 :                 prm[bits] = 0;
    3749      244670 :                 move16();
    3750      244670 :                 bits = add( bits, 1 );
    3751             :             }
    3752             :         }
    3753             :     }
    3754             : 
    3755             :     /*Be sure that every possible bits are initialized*/
    3756    32350683 :     FOR( i = bits; i < NPRM_RESQ; i++ )
    3757             :     {
    3758    31977822 :         prm[i] = 0;
    3759    31977822 :         move16();
    3760             :     }
    3761             : 
    3762      372861 :     return bits;
    3763             : }
    3764             : 
    3765         662 : void ProcessIGF_fx(
    3766             :     IGF_ENC_INSTANCE_HANDLE const hInstance, /**< in: instance handle of IGF Encoder */
    3767             :     Encoder_State *st,                       /**< in: Encoder state */
    3768             :     Word32 pMDCTSpectrum[],                  /**< in: MDCT spectrum */
    3769             :     Word16 *pMDCTSpectrum_e,
    3770             :     Word32 pPowerSpectrum[], /**< in: MDCT^2 + MDST^2 spectrum, or estimate */
    3771             :     Word16 *pPowerSpectrum_e,
    3772             :     Word16 isTCX20,      /**< in: flag indicating if the input is TCX20 or TCX10/2xTCX5 */
    3773             :     Word16 isTNSActive,  /**< in: flag indicating if the TNS is active */
    3774             :     Word16 isTransition, /**< in: flag indicating if the input is the transition from from ACELP to TCX20/TCX10 */
    3775             :     Word16 frameno       /**< in: flag indicating index of current subframe */
    3776             : )
    3777             : {
    3778             :     Word16 igfGridIdx;
    3779             :     Word16 isIndepFlag;
    3780             :     Word16 bsBits;
    3781             : #ifndef HARM_PUSH_BIT
    3782             :     Word16 bsStart, pBsStart;
    3783             : #else
    3784             :     Word16 pBsStart;
    3785             : #endif
    3786         662 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
    3787         662 :     IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc;
    3788             : 
    3789             : 
    3790         662 :     isIndepFlag = 1;
    3791         662 :     move16();
    3792         662 :     test();
    3793         662 :     IF( isTransition && isTCX20 )
    3794             :     {
    3795          39 :         igfGridIdx = IGF_GRID_LB_TRAN;
    3796          39 :         move16();
    3797             :     }
    3798             :     ELSE
    3799             :     {
    3800         623 :         IF( isTCX20 )
    3801             :         {
    3802         623 :             igfGridIdx = IGF_GRID_LB_NORM;
    3803         623 :             move16();
    3804             :         }
    3805             :         ELSE
    3806             :         {
    3807             :             /* It is short block */
    3808           0 :             igfGridIdx = IGF_GRID_LB_SHORT;
    3809           0 :             move16();
    3810           0 :             if ( EQ_16( frameno, 1 ) )
    3811             :             {
    3812           0 :                 isIndepFlag = 0;
    3813           0 :                 move16();
    3814             :             }
    3815             :         }
    3816             :     }
    3817             : 
    3818             : 
    3819         662 :     IGFEncApplyMono_fx( hInstance,     /**< in: instance handle of IGF Encoder */
    3820             :                         igfGridIdx,    /**< in: IGF grid index */
    3821             :                         st,            /**< in: Encoder state */
    3822             :                         pMDCTSpectrum, /**< in: MDCT spectrum */
    3823         662 :                         *pMDCTSpectrum_e,
    3824             :                         pPowerSpectrum, /**< in: MDCT^2 + MDST^2 spectrum, or estimate */
    3825         662 :                         *pPowerSpectrum_e,
    3826             :                         isTCX20,     /**< in: flag indicating if the input is TCX20 or TCX10/2xTCX5 */
    3827             :                         isTNSActive, /**< in: flag indicating if the TNS is active */
    3828         662 :                         ( st->last_core == ACELP_CORE ) );
    3829             :     {
    3830         662 :         const Word32 tns_predictionGain = st->hIGFEnc->tns_predictionGain;
    3831         662 :         const Word16 startLine = st->hIGFEnc->infoStartLine;
    3832         662 :         const Word16 endLine = st->hIGFEnc->infoStopLine;
    3833         662 :         const Word16 maxOrder = 8;
    3834         662 :         const Word32 *spec_before = st->hIGFEnc->spec_be_igf;
    3835         662 :         Word16 curr_order = 0;
    3836             :         Word16 A[ITF_MAX_FILTER_ORDER + 1];
    3837             :         Word16 Q_A;
    3838         662 :         Word16 predictionGain = 0;
    3839         662 :         Word16 *flatteningTrigger = &( st->hIGFEnc->flatteningTrigger );
    3840             : 
    3841             : 
    3842         662 :         move32();
    3843         662 :         move16();
    3844         662 :         move16();
    3845         662 :         move16();
    3846         662 :         move32();
    3847         662 :         move16();
    3848         662 :         move16();
    3849             : 
    3850         662 :         ITF_Detect_fx( spec_before, startLine, endLine, maxOrder, A, &Q_A, &predictionGain, &curr_order, shl( st->hIGFEnc->spec_be_igf_e, 1 ) );
    3851         662 :         *flatteningTrigger = 0;
    3852         662 :         move16();
    3853         662 :         test();
    3854         662 :         IF( LT_32( tns_predictionGain, 9646899l /*1.15 Q23*/ ) &&
    3855             :             LT_16( predictionGain, 147 /*1.15 Q7*/ ) )
    3856             :         {
    3857         588 :             *flatteningTrigger = 1;
    3858         588 :             move16();
    3859             :         }
    3860             :     }
    3861             : 
    3862             : #ifndef HARM_PUSH_BIT
    3863             :     bsStart = hBstr->next_ind_fx;
    3864             : #endif
    3865         662 :     move16();
    3866         662 :     hInstance->infoTotalBitsPerFrameWritten = 0;
    3867         662 :     move16();
    3868         662 :     IF( isTCX20 )
    3869             :     {
    3870         662 :         IGFEncWriteBitstream_fx( hInstance, NULL, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
    3871             :     }
    3872             : #ifndef HARM_PUSH_BIT
    3873             :     ELSE
    3874             :     {
    3875             :         IGFEncWriteBitstream_fx( hInstance, st->hBstr, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
    3876             :     }
    3877             : 
    3878             :     bsBits = sub( hBstr->next_ind_fx, bsStart );
    3879             :     IF( !isTCX20 )
    3880             :     {
    3881             :         IGFEncConcatenateBitstream_fx( hInstance, bsBits, &hBstr->next_ind_fx, &hBstr->nb_bits_tot, hBstr->ind_list );
    3882             :     }
    3883             : #else
    3884             :     ELSE
    3885             :     {
    3886           0 :         pBsStart = hBstr->nb_ind_tot;
    3887           0 :         move16();
    3888             : 
    3889           0 :         IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
    3890             : 
    3891           0 :         bsBits = sub( hBstr->nb_ind_tot, pBsStart );
    3892           0 :         IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr );
    3893             :     }
    3894             : #endif
    3895         662 : }
    3896             : 
    3897           0 : void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum )
    3898             : {
    3899             :     Word16 i, length, att;
    3900             : 
    3901           0 :     length = idiv1616U( L_frame, 20 );
    3902             : 
    3903           0 :     att = 21627 /*0.66f Q15*/;
    3904           0 :     move16();
    3905           0 :     if ( EQ_16( length, 8 ) )
    3906             :     {
    3907           0 :         att = 19661 /*0.6f Q15*/;
    3908           0 :         move16();
    3909             :     }
    3910             : 
    3911           0 :     spectrum += sub( L_frame, length );
    3912           0 :     FOR( i = 0; i < length; i++ )
    3913             :     {
    3914           0 :         spectrum[i] = Mpy_32_16_1( spectrum[i], att );
    3915           0 :         move32();
    3916           0 :         att = mult_r( att, att );
    3917             :     }
    3918           0 : }
    3919             : 
    3920             : /*---------------------------------------------------------------------*
    3921             :  * ProcessIGF_ivas_fx()
    3922             :  *
    3923             :  *
    3924             :  *---------------------------------------------------------------------*/
    3925      491554 : void ProcessIGF_ivas_fx(
    3926             :     Encoder_State *st,              /* i  : Encoder state                                           */
    3927             :     Word16 powerSpec_len,           /* i  : length of pPowerSpectrum buffer */
    3928             :     Word32 *pMDCTSpectrum,          /* i  : MDCT spectrum (*q_spectrum)                                          */
    3929             :     Word16 *q_spectrum,             /* i/o: Q of spectrum */
    3930             :     const Word32 *pITFMDCTSpectrum, /* i  : MDCT spectrum fir ITF                                */
    3931             :     const Word16 q_ITFMDCTSpectrum, /* i  : Q of MDCT spectrum fir ITF */
    3932             :     Word32 *pPowerSpectrum,         /* i  : MDCT^2 + MDST^2 spectrum, or estimate (*q_powerSpec)                  */
    3933             :     Word16 *exp_powerSpec,          /* i/o: Q of power spectrum */
    3934             :     const Word16 isTCX20,           /* i  : flag indicating if the input is TCX20 or TCX10/2xTCX5   */
    3935             :     const Word16 frameno,           /* i  : flag indicating index of current subframe               */
    3936             :     const Word16 sp_aud_decision0,  /* i  : first stage switching decision                         */
    3937             :     const Word16 vad_hover_flag     /* i  : VAD hangover flag                                      */
    3938             : )
    3939             : {
    3940             :     Word16 igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order;
    3941             :     Word16 predictionGain;
    3942             :     Word16 A[ITF_MAX_FILTER_ORDER + 1];
    3943             :     Word16 q_A;
    3944             : 
    3945      491554 :     IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc;
    3946      491554 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
    3947             : 
    3948      491554 :     isIndepFlag = 1;
    3949      491554 :     move16();
    3950      491554 :     test();
    3951      491554 :     IF( st->last_core == ACELP_CORE && isTCX20 )
    3952             :     {
    3953        8512 :         igfGridIdx = IGF_GRID_LB_TRAN;
    3954        8512 :         move16();
    3955             :     }
    3956      483042 :     ELSE IF( isTCX20 )
    3957             :     {
    3958      465176 :         igfGridIdx = IGF_GRID_LB_NORM;
    3959      465176 :         move16();
    3960             :     }
    3961             :     ELSE
    3962             :     {
    3963             :         /* It is short block */
    3964       17866 :         igfGridIdx = IGF_GRID_LB_SHORT;
    3965       17866 :         move16();
    3966       17866 :         if ( EQ_16( frameno, 1 ) )
    3967             :         {
    3968        8992 :             isIndepFlag = 0;
    3969        8992 :             move16();
    3970             :         }
    3971             :     }
    3972             : 
    3973      491554 :     IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, q_ITFMDCTSpectrum ) );
    3974             : 
    3975      491554 :     IGFEncApplyMono_ivas_fx( st, powerSpec_len, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag );
    3976             : 
    3977      491554 :     curr_order = 0;
    3978      491554 :     move16();
    3979      491554 :     predictionGain = 0;
    3980      491554 :     move16();
    3981      491554 :     q_A = 0;
    3982      491554 :     move16();
    3983             : 
    3984      491554 :     ITF_Detect_ivas_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) );
    3985             : 
    3986      491554 :     test();
    3987      491554 :     IF( LT_16( hIGFEnc->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 ) )
    3988             :     {
    3989      472928 :         hIGFEnc->flatteningTrigger = 1;
    3990      472928 :         move16();
    3991             :     }
    3992             :     ELSE
    3993             :     {
    3994       18626 :         hIGFEnc->flatteningTrigger = 0;
    3995       18626 :         move16();
    3996             :     }
    3997             : 
    3998      491554 :     hIGFEnc->infoTotalBitsPerFrameWritten = 0;
    3999      491554 :     move16();
    4000             : 
    4001      491554 :     IF( isTCX20 )
    4002             :     {
    4003      473688 :         IGFEncWriteBitstream_ivas_fx( hIGFEnc, NULL, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
    4004             :     }
    4005             :     ELSE
    4006             :     {
    4007       17866 :         pBsStart = hBstr->nb_ind_tot;
    4008       17866 :         move16();
    4009             : 
    4010       17866 :         IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
    4011             : 
    4012       17866 :         bsBits = sub( hBstr->nb_ind_tot, pBsStart );
    4013       17866 :         IGFEncConcatenateBitstream_ivas_fx( hIGFEnc, bsBits, hBstr );
    4014             :     }
    4015             : 
    4016      491554 :     return;
    4017             : }
    4018             : 
    4019             : /*---------------------------------------------------------------------*
    4020             :  * ProcessStereoIGF()
    4021             :  *
    4022             :  *
    4023             :  *---------------------------------------------------------------------*/
    4024             : 
    4025       50217 : void ProcessStereoIGF_fx(
    4026             :     STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct,
    4027             :     Encoder_State *sts[CPE_CHANNELS],                  /* i  : Encoder state                           */
    4028             :     Word16 ms_mask[2][MAX_SFB],                        /* i  : bandwise MS mask                        */
    4029             :     Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i  : MDCT spectrum fir ITF                   */
    4030             :     Word16 q_pITFMDCTSpectrum_1,
    4031             :     Word16 q_pITFMDCTSpectrum_2,
    4032             :     Word32 *pPowerSpectrum_fx[CPE_CHANNELS],              /* i/o: MDCT^2 + MDST^2 spectrum, or estimate   */
    4033             :     Word16 exp_pPowerSpectrum_fx[CPE_CHANNELS],           /* i/o: exp of pPowerSpectrum_fx                */
    4034             :     Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i  : inverse power spectrum                  */
    4035             :     Word16 exp_pPowerSpectrumMsInv_fx[CPE_CHANNELS],      /* i/o: exp of pPowerSpectrumMsInv_fx           */
    4036             :     Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV],        /* i  : inverse spectrum                        */
    4037             :     Word16 exp_inv_spectrum_fx[CPE_CHANNELS],             /* i/o: exp of inv_spectrum_fx                  */
    4038             :     const Word16 frameno,                                 /* i  : flag indicating index of current subfr. */
    4039             :     const Word16 sp_aud_decision0,                        /* i  : sp_aud_decision0                        */
    4040             :     const Word32 element_brate,                           /* i  : element bitrate                         */
    4041             :     const Word16 mct_on )
    4042             : {
    4043             :     Word16 ch, igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order;
    4044             :     Word16 predictionGain;
    4045             :     Word16 A[ITF_MAX_FILTER_ORDER + 1];
    4046             :     Word16 Q_A;
    4047             :     IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS];
    4048             :     BSTR_ENC_HANDLE hBstr;
    4049       50217 :     hIGFEnc[0] = sts[0]->hIGFEnc;
    4050       50217 :     hIGFEnc[1] = sts[1]->hIGFEnc;
    4051             : 
    4052       50217 :     isIndepFlag = 1;
    4053       50217 :     move16();
    4054             : 
    4055       50217 :     test();
    4056       50217 :     IF( sts[0]->last_core == ACELP_CORE && EQ_16( sts[0]->core, TCX_20_CORE ) )
    4057             :     {
    4058           0 :         igfGridIdx = IGF_GRID_LB_TRAN;
    4059             :     }
    4060       50217 :     ELSE IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
    4061             :     {
    4062       48108 :         igfGridIdx = IGF_GRID_LB_NORM;
    4063             :     }
    4064             :     ELSE
    4065             :     {
    4066             :         /* It is short block */
    4067        2109 :         igfGridIdx = IGF_GRID_LB_SHORT;
    4068        2109 :         if ( EQ_16( frameno, 1 ) )
    4069             :         {
    4070        1025 :             isIndepFlag = 0;
    4071        1025 :             move16();
    4072             :         }
    4073             :     }
    4074       50217 :     move16();
    4075             : 
    4076       50217 :     IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[0], igfGridIdx, pITFMDCTSpectrum_fx[0][frameno], sub( Q31, q_pITFMDCTSpectrum_1 ) );
    4077             : 
    4078       50217 :     IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum_fx[1][frameno], sub( Q31, q_pITFMDCTSpectrum_2 ) );
    4079             : 
    4080             : 
    4081       50217 :     IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, exp_pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, exp_pPowerSpectrumMsInv_fx,
    4082             :                           inv_spectrum_fx, exp_inv_spectrum_fx, frameno, sp_aud_decision0, element_brate, mct_on );
    4083             : 
    4084      150651 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    4085             :     {
    4086      100434 :         curr_order = 0;
    4087      100434 :         move16();
    4088             : 
    4089      100434 :         Q_A = 0;
    4090      100434 :         move16();
    4091             : 
    4092      100434 :         predictionGain = 0;
    4093      100434 :         move16();
    4094             : 
    4095      100434 :         ITF_Detect_ivas_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) );
    4096             : 
    4097      100434 :         test();
    4098      100434 :         hIGFEnc[ch]->flatteningTrigger = LT_16( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 );
    4099      100434 :         move16();
    4100             : 
    4101      100434 :         hIGFEnc[ch]->infoTotalBitsPerFrameWritten = 0;
    4102      100434 :         move16();
    4103             : 
    4104      100434 :         IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
    4105             :         {
    4106       96216 :             IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], NULL, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
    4107             :         }
    4108             :         ELSE
    4109             :         {
    4110        4218 :             hBstr = sts[ch]->hBstr;
    4111        4218 :             pBsStart = hBstr->nb_ind_tot;
    4112        4218 :             move16();
    4113             : 
    4114        4218 :             if ( ch > 0 )
    4115             :             {
    4116        2109 :                 hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
    4117             :             }
    4118        4218 :             IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], hBstr, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag );
    4119             : 
    4120        4218 :             bsBits = sub( hBstr->nb_ind_tot, pBsStart );
    4121        4218 :             IGFEncConcatenateBitstream_ivas_fx( hIGFEnc[ch], bsBits, hBstr );
    4122             :         }
    4123             :     }
    4124       50217 :     return;
    4125             : }

Generated by: LCOV version 1.14