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

Generated by: LCOV version 1.14