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

Generated by: LCOV version 1.14