LCOV - code coverage report
Current view: top level - lib_enc - gain_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 999 1474 67.8 %
Date: 2025-05-03 01:55:50 Functions: 9 12 75.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h"    /* Compilation switches                   */
       6             : #include "cnst.h"       /* Common constants                       */
       7             : #include "rom_com_fx.h" /* Static table prototypes                */
       8             : #include "rom_com.h"    /* Static table prototypes                */
       9             : //#include "prot_fx.h"       /* Function prototypes                    */
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "prot_fx_enc.h" /* Function prototypes                    */
      12             : 
      13             : /*-------------------------------------------------------------------*
      14             :  * Local constants
      15             :  *-------------------------------------------------------------------*/
      16             : 
      17             : #define RANGE         64
      18             : #define NB_QUA_GAIN7B 128 /* Number of quantization levels */
      19             : 
      20             : /*-------------------------------------------------------------------*
      21             :  * Local function prototype
      22             :  *-------------------------------------------------------------------*/
      23             : 
      24             : static Word16 Find_Opt_gainQ_fx( Word16 *coeff, Word16 *exp_coeff, Word16 *gain_pit, Word32 *gain_code, Word16 gcode0, Word16 exp_gcode0, const Word16 *cdbk, const Word16 size );
      25             : 
      26             : /*==========================================================================*/
      27             : /* FUNCTION      :  Es_pred_enc_fx()                                        */
      28             : /*--------------------------------------------------------------------------*/
      29             : /* PURPOSE : Calculation and quantization of average predicted innovation energy to be*/
      30             : /*--------------------------------------------------------------------------*/
      31             : /* INPUT ARGUMENTS  :                                                       */
      32             : /*   _ Word16 L_frame,     i  : length of the frame       Q0                */
      33             : /*   _ Word16 *res,        i  : residual signal           Q_new           */
      34             : /*   _ Word16 *voicing,    i  : normalized correlation in three 1/2frames Q15*/
      35             : /*   _ Word16 coder_type,  i  : coder_type                Q0                            */
      36             : /*   _ Word16 bwidth,      i  : input signal bandwidth    Q0                            */
      37             : /*   _ Word32  core_brate, i  : core bitrate              Q0                            */
      38             : /*   _ Word16 Q_new        i  : Scaling in speech         Q0                            */
      39             : /*--------------------------------------------------------------------------*/
      40             : /* OUTPUT ARGUMENTS :                                                       */
      41             : /*   _ Word16 *Es_pred,    o  : predicited scaled innovation energy    Q8   */
      42             : /*--------------------------------------------------------------------------*/
      43             : /* INPUT/OUTPUT ARGUMENTS :                                                 */
      44             : /*   _ None.                                                                */
      45             : /*--------------------------------------------------------------------------*/
      46             : /* RETURN ARGUMENTS : _ None.                                               */
      47             : /*--------------------------------------------------------------------------*/
      48             : /* CALLED FROM : TX                                                      */
      49             : /*==========================================================================*/
      50             : 
      51      132562 : void Es_pred_enc_fx(
      52             :     Word16 *Es_pred,       /* o  : predicited scaled innovation energy                  Q8*/
      53             :     Word16 *indice,        /* o  : indice of quantization                                               Q0*/
      54             :     const Word16 L_frame,  /* i  : length of the frame                                                  Q0*/
      55             :     const Word16 *res,     /* i  : residual signal                                                              Q_new*/
      56             :     const Word16 *voicing, /* i  : normalized correlation in three 1/2frames    Q15*/
      57             :     const Word16 nb_bits,  /* i  : allocated number of bits                                             Q0*/
      58             :     const Word16 no_ltp,   /* i  : no_ltp flag                                                                  Q0*/
      59             :     Word16 Q_new           /* i  : Scaling in speech                                                    Q0*/
      60             : )
      61             : {
      62             :     Word16 i, i_subfr, size, tmp16, tmp16_2, Q_res;
      63             :     Word16 weight;
      64             :     Word16 s0, s1, ener_dB, mean_ener_code16;
      65             :     const Word16 *qua_table;
      66             :     Word32 ener_fx, Lmean_ener_code, Ltmp;
      67             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      68      132562 :     Flag Overflow = 0;
      69      132562 :     move32();
      70             : #endif
      71             : 
      72      132562 :     Lmean_ener_code = L_deposit_l( 0 );
      73      132562 :     Q_res = sub( shl( Q_new, 1 ), 3 );
      74             : 
      75      132562 :     IF( EQ_16( L_frame, L_FRAME ) )
      76             :     {
      77       60740 :         weight = 8192;
      78       60740 :         move16(); /*0.25f in Q15*/
      79             :     }
      80             :     ELSE /* L_frame == L_FRAME16k */
      81             :     {
      82       71822 :         weight = 6554;
      83       71822 :         move16(); /*0.2f in Q15*/
      84             :     }
      85             : 
      86             :     /*----------------------------------------------------------*
      87             :      * calculate the average residual signal energy in four sframes
      88             :      *----------------------------------------------------------*/
      89             : 
      90      734632 :     FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
      91             :     {
      92             :         /* calculate the energy of residual signal */
      93      602070 :         tmp16 = mult_r( res[i_subfr + 0], 8192 /* 1 in Q13 */ ); /* remove 2bits        Q_new - 2*/
      94      602070 :         ener_fx = L_mult( tmp16, tmp16 );
      95    38532480 :         FOR( i = 1; i < L_SUBFR; i++ )
      96             :         {
      97    37930410 :             tmp16 = mult_r( res[i_subfr + i], 8192 /* 1 in Q13 */ ); /* remove 2bits    Q_new - 2*/
      98    37930410 :             ener_fx = L_mac_o( ener_fx, tmp16, tmp16, &Overflow );
      99             :         }
     100             : 
     101             :         /* ener = 10 * (float)log10(ener / (float)L_SUBFR) */
     102      602070 :         s1 = 0;
     103      602070 :         move16();
     104      602070 :         s0 = norm_l( ener_fx );
     105             : 
     106      602070 :         IF( ener_fx != 0 ) /* Log2_norm_lc doesn't Support Input <= 0; deal with it here */
     107             :         {
     108      596379 :             s1 = Log2_norm_lc( L_shl( ener_fx, s0 ) );
     109      596379 :             s0 = sub( 30, s0 );
     110             :         }
     111      602070 :         s0 = sub( s0, add( Q_res, 6 ) );
     112      602070 :         Ltmp = Mpy_32_16( s0, s1, LG10 );
     113      602070 :         ener_dB = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 Energy in log10 */
     114      602070 :         test();
     115      602070 :         if ( ( ener_dB < 0 ) && ( no_ltp == 0 ) )
     116             :         {
     117       12405 :             ener_dB = 0;
     118       12405 :             move16();
     119             :         }
     120             : 
     121             :         /* update the average energy of residual signal */
     122      602070 :         Lmean_ener_code = L_mac( Lmean_ener_code, ener_dB, weight ); /* Q24 */
     123             :     }
     124             : 
     125      132562 :     IF( no_ltp == 0 )
     126             :     {
     127             :         /*----------------------------------------------------------*
     128             :          * subtract an estimate of adaptive codebook contribution
     129             :          *----------------------------------------------------------*/
     130             :         /*mean_ener_code -= 10.0f * (0.5f * voicing[0] + 0.5f * voicing[1]);*/
     131      130561 :         Lmean_ener_code = L_msu( Lmean_ener_code, voicing[0], 1280 ); /*Q24*/
     132      130561 :         Lmean_ener_code = L_msu( Lmean_ener_code, voicing[1], 1280 ); /*Q24*/
     133      130561 :         mean_ener_code16 = extract_h( Lmean_ener_code );              /*Q8*/
     134             : 
     135             :         /*----------------------------------------------------------*n
     136             :          * quantize the average predicted innovation energy
     137             :          *----------------------------------------------------------*/
     138      130561 :         SWITCH( nb_bits )
     139             :         {
     140      112602 :             case 5:
     141             :             {
     142      112602 :                 qua_table = Es_pred_qua_5b_fx; // Q8
     143      112602 :                 BREAK;
     144             :             }
     145       17355 :             case 4:
     146             :             {
     147       17355 :                 qua_table = Es_pred_qua_4b_fx; // Q8
     148       17355 :                 BREAK;
     149             :             }
     150         604 :             case 3:
     151             :             {
     152         604 :                 qua_table = Es_pred_qua_3b_fx; // Q8
     153         604 :                 BREAK;
     154             :             }
     155           0 :             default:
     156             :             {
     157           0 :                 qua_table = Es_pred_qua_5b_fx; // Q8
     158           0 :                 BREAK;
     159             :             }
     160             :         }
     161             :     }
     162             :     ELSE
     163             :     {
     164        2001 :         mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
     165             : 
     166        2001 :         qua_table = Es_pred_qua_4b_no_ltp_fx; // Q8
     167             :     }
     168             :     /*size = extract_l(pow2_fx[nb_bits]); */ /*maximum number of bit is 6 */
     169      132562 :     size = shl( 1, nb_bits );                /*maximum number of bit is 6 */
     170             : 
     171             :     /* find the nearest neighbour (codevector) */
     172      132562 :     *Es_pred = qua_table[0]; // Q8
     173      132562 :     move16();
     174      132562 :     tmp16 = abs_s( sub( mean_ener_code16, qua_table[0] ) );
     175      132562 :     *indice = 0;
     176      132562 :     move16();
     177             : 
     178     3917792 :     FOR( i = 1; i < size; i++ )
     179             :     {
     180     3785230 :         tmp16_2 = abs_s( sub_o( mean_ener_code16, qua_table[i], &Overflow ) );
     181     3785230 :         IF( LT_16( tmp16_2, tmp16 ) )
     182             :         {
     183     1949791 :             tmp16 = tmp16_2;
     184     1949791 :             move16();
     185     1949791 :             *indice = i;
     186     1949791 :             move16();
     187     1949791 :             *Es_pred = qua_table[i]; // Q8
     188     1949791 :             move16();
     189             :         }
     190             :     }
     191             : 
     192             : 
     193      132562 :     return;
     194             : }
     195             : /*---------------------------------------------------------------------*
     196             :  * gain_enc_mless()
     197             :  *
     198             :  * Quantization of pitch and codebook gains without prediction (memory-less)
     199             :  * - an initial predicted gain, gcode0, is first determined based on
     200             :  *   the predicted average innovation energy
     201             :  * - a correction factor gamma = g_code / gcode0 is then vector quantized along with gain_pit
     202             :  * - the mean-squared weighted error criterion is used for codebook search
     203             :  *---------------------------------------------------------------------*/
     204        2916 : void gain_enc_mless_fx(
     205             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                 */
     206             :     const Word16 gains_mode[], /* i  : gain bits                                                                                                                Q0*/
     207             :     const Word16 element_mode, /* i  : element mode                                                                                                             Q0*/
     208             :     const Word16 L_frame,      /* i  : length of the frame                                                                                              Q0*/
     209             :     const Word16 i_subfr,      /* i  : subframe index                                                                                                   Q0*/
     210             :     const Word16 tc_subfr,     /* i  : TC subframe index                                                                                                Q0*/
     211             :     const Word16 *xn,          /* i  : target vector                                                                                                    Q_xn*/
     212             :     const Word16 *y1,          /* i  : zero-memory filtered adaptive excitation                                                 Q_xn*/
     213             :     const Word16 Q_xn,         /* i  : xn and y1 scaling                                                                                                */
     214             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation                               Q9*/
     215             :     const Word16 *code,        /* i  : algebraic excitation                                                                                             Q9*/
     216             :     const Word16 Es_pred,      /* i  : predicted scaled innovation energy                                                               Q8*/
     217             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                                                                             Q14*/
     218             :     Word32 *gain_code,         /* o  : quantized codebook gain                                                                                  Q16*/
     219             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                                  Q12*/
     220             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                                                    Q16*/
     221             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>    Qx*/
     222             :     const Word16 clip_gain     /* i  : gain pitch clipping flag (1 = clipping)                                                  Q0*/
     223             : )
     224             : {
     225             : 
     226             :     Word16 index, size, nBits, nBits2;
     227             :     Word16 gcode0, Ei, gain_code16;
     228             :     const Word16 *qua_table;
     229             :     Word16 coeff[5], exp_coeff[5];
     230             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
     231             :     Word32 L_tmp, L_tmp1, L_tmp2;
     232             :     Word16 tmp1, expg;
     233             :     Word16 exp1, exp2;
     234             :     Word16 exp_num, exp_den, exp_div, frac_den;
     235             :     Word32 L_frac_num, L_frac_den, L_div;
     236             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     237        2916 :     Flag Overflow = 0;
     238        2916 :     move32();
     239             : #endif
     240             : 
     241             :     /*-----------------------------------------------------------------*
     242             :      * calculate the rest of the correlation coefficients
     243             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
     244             :      *-----------------------------------------------------------------*/
     245             : 
     246        2916 :     coeff[0] = g_corr[0];
     247        2916 :     move16();
     248        2916 :     exp_coeff[0] = g_corr[1];
     249        2916 :     move16();
     250        2916 :     coeff[1] = negate( g_corr[2] );
     251        2916 :     move16(); /* coeff[1] = -2 xn yy1 */
     252        2916 :     exp_coeff[1] = add( g_corr[3], 1 );
     253        2916 :     move16();
     254             : 
     255             :     /* Compute scalar product <y2[],y2[]> */
     256        2916 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
     257        2916 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
     258        2916 :     move16(); /* -18 (y2 Q9) */
     259             : 
     260             :     /* Compute scalar product -2*<xn[],y2[]> */
     261        2916 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
     262        2916 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
     263        2916 :     move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
     264             : 
     265             :     /* Compute scalar product 2*<y1[],y2[]> */
     266        2916 :     coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
     267        2916 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
     268        2916 :     move16(); /* -9 (y2 Q9), +1 (2 y1 y2) */
     269             : 
     270             :     /*-----------------------------------------------------------------*
     271             :      * calculate the unscaled innovation energy
     272             :      * calculate the predicted gain code
     273             :      *-----------------------------------------------------------------*/
     274             : 
     275             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     276        2916 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
     277        2916 :     exp_inov = sub( exp_code, 18 + 6 );
     278        2916 :     exp_code = sub( exp_code, 30 );
     279             : 
     280             :     /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     281             : 
     282             :     /*----------------------------------------------------------------*
     283             :      * calculate the predicted gain code
     284             :      *----------------------------------------------------------------*/
     285        2916 :     tmp = norm_l( L_tmp );
     286        2916 :     frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
     287        2916 :     tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
     288        2916 :     L_tmp1 = Mpy_32_16( tmp, frac, 12330 );             /* Q13 */
     289        2916 :     Ei = round_fx( L_shl( L_tmp1, 11 ) );               /* Q8 */
     290             : 
     291             :     /* predicted codebook gain */
     292        2916 :     gcode0 = sub( Es_pred, Ei ); /* Q8 */
     293             : 
     294             :     /*---------------------------------------------------------------*
     295             :      * Decode codebook gain and the adaptive excitation low-pass
     296             :      * filtering factor (Finalize computation )
     297             :      *---------------------------------------------------------------*/
     298             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     299        2916 :     L_tmp = Isqrt_lc( L_tmp, &exp_inov );
     300        2916 :     *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
     301        2916 :     move16();
     302             : 
     303             :     /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
     304             :     /*----------------------------------------------------------------*
     305             :      * gcode0 = pow(10.0, gcode0/20)
     306             :      *        = pow(2, 3.321928*gcode0/20)
     307             :      *        = pow(2, 0.166096*gcode0)
     308             :      *----------------------------------------------------------------*/
     309             : 
     310        2916 :     L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26    */
     311        2916 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16            */
     312        2916 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
     313             : 
     314        2916 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
     315             :     /* output of Pow2() will be: */
     316             :     /* 16384 < Pow2() <= 32767   */
     317        2916 :     exp_gcode0 = sub( exp_gcode0, 14 );
     318             : 
     319             :     /*-----------------------------------------------------------------*
     320             :      * select the codebook, size and number of bits
     321             :      * set the gains searching range
     322             :      *-----------------------------------------------------------------*/
     323        2916 :     nBits = gains_mode[i_subfr >> 6];
     324        2916 :     move16();
     325             : 
     326        2916 :     test();
     327        2916 :     test();
     328        2916 :     test();
     329        2916 :     test();
     330        2916 :     test();
     331        2916 :     IF( ( EQ_16( tc_subfr, 3 * L_SUBFR ) && EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( L_frame, L_FRAME ) ) ||
     332             :         ( EQ_16( tc_subfr, 4 * L_SUBFR ) && EQ_16( i_subfr, 4 * L_SUBFR ) && EQ_16( L_frame, L_FRAME16k ) ) )
     333             :     {
     334             :         /*    *gain_pit =  (g_corr[2]*tmp2) - (0.5f*g_corr[4]*tmp3);
     335             :                         =  ((-0.5f*g_corr[1]*g_corr[2]) - (-0.25*g_corr[3]*g_corr[4]))/tmp1;
     336             :                         =  ((0.25*g_corr[3]*g_corr[4]) - (0.5*g_corr[1]*g_corr[2]))/tmp1; */
     337             : 
     338             :         /*     *gain_code = (g_corr[0]*tmp3) - (0.5f*g_corr[4]*tmp2);
     339             :                           = ((-0.5*g_corr[3]*g_corr[0]) - (-0.25*g_corr[1]*g_corr[4]))/tmp1;
     340             :                           = ((0.25*g_corr[1]*g_corr[4]) - (0.5*g_corr[0]*g_corr[3]))/tmp1; */
     341             : 
     342          23 :         L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
     343          23 :         exp1 = add( exp_coeff[0], exp_coeff[2] );
     344             : 
     345          23 :         L_tmp2 = L_shr( L_mult( coeff[4], coeff[4] ), 2 ); /*Q31*/
     346          23 :         exp2 = add( exp_coeff[4], exp_coeff[4] );
     347             : 
     348          23 :         IF( GT_16( exp1, exp2 ) )
     349             :         {
     350          23 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     351          23 :             exp_den = exp1;
     352          23 :             move16();
     353             :         }
     354             :         ELSE
     355             :         {
     356           0 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     357           0 :             exp_den = exp2;
     358           0 :             move16();
     359             :         }
     360          23 :         L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     361             : 
     362          23 :         frac_den = extract_h( L_frac_den );  /* Q15 */
     363          23 :         frac_den = s_max( frac_den, 1 );     /* Q15 */
     364          23 :         L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
     365          23 :         exp = norm_l( L_frac_den );
     366          23 :         tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
     367             : 
     368          23 :         L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
     369          23 :         exp1 = add( exp_coeff[3], exp_coeff[4] );
     370             : 
     371          23 :         L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
     372          23 :         exp2 = add( exp_coeff[1], exp_coeff[2] );
     373             : 
     374          23 :         IF( GT_16( exp1, exp2 ) )
     375             :         {
     376           1 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     377           1 :             exp_num = exp1;
     378           1 :             move16();
     379             :         }
     380             :         ELSE
     381             :         {
     382          22 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     383          22 :             exp_num = exp2;
     384          22 :             move16();
     385             :         }
     386          23 :         L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     387             : 
     388          23 :         L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     389          23 :         exp_div = sub( exp_num, exp_den );
     390             : 
     391          23 :         *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
     392             : 
     393          23 :         L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
     394          23 :         exp1 = add( exp_coeff[1], exp_coeff[4] );
     395             : 
     396          23 :         L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
     397          23 :         exp2 = add( exp_coeff[0], exp_coeff[3] );
     398             : 
     399          23 :         IF( GT_16( exp1, exp2 ) )
     400             :         {
     401           1 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     402           1 :             exp_num = exp1;
     403           1 :             move16();
     404             :         }
     405             :         ELSE
     406             :         {
     407          22 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     408          22 :             exp_num = exp2;
     409          22 :             move16();
     410             :         }
     411          23 :         L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     412             : 
     413          23 :         L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     414          23 :         exp_div = sub( exp_num, exp_den );
     415             : 
     416          23 :         *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
     417          23 :         move32(); /*Q16*/
     418             : 
     419          23 :         *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) );
     420          23 :         move16();
     421             : 
     422             :         /* set number of bits for two SQs */
     423          23 :         nBits2 = shr( add( nBits, 1 ), 1 );
     424          23 :         nBits = shr( nBits, 1 );
     425             : 
     426             :         /* gain_pit Q */
     427             : 
     428          23 :         tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
     429          23 :         index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
     430          23 :         move16();
     431          23 :         push_indice( hBstr, IND_GAIN_PIT, index, nBits );
     432             : 
     433             :         /* gain_code Q */
     434             :         /**gain_code /= gcode0;*/
     435          23 :         IF( gcode0 != 0 )
     436             :         {
     437          23 :             tmp = div_s( 16384, gcode0 );                       /*Q15*/
     438          23 :             L_tmp = Mult_32_16( *gain_code, tmp );              /*Q16*/
     439          23 :             *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
     440          23 :             move32();
     441             :         }
     442             : 
     443          23 :         index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
     444          23 :         push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
     445          23 :         L_tmp = L_mult( gain_code16, gcode0 );                                        /*Q0*Q0 -> Q1*/
     446          23 :         *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/
     447             :     }
     448             :     ELSE
     449             :     {
     450        2893 :         size = shl( 1, nBits );
     451             : 
     452        2893 :         SWITCH( nBits )
     453             :         {
     454           0 :             case 7:
     455             :             {
     456           0 :                 qua_table = gain_qua_mless_7b_fx;
     457           0 :                 move16();
     458           0 :                 if ( EQ_16( clip_gain, 1 ) )
     459             :                 {
     460           0 :                     size = sub( size, 30 );
     461             :                 }
     462           0 :                 BREAK;
     463             :             }
     464        2893 :             case 6:
     465             :             {
     466        2893 :                 qua_table = gain_qua_mless_6b_fx;
     467             :                 if ( element_mode > EVS_MONO )
     468             :                 {
     469             :                 }
     470        2893 :                 move16();
     471        2893 :                 if ( EQ_16( clip_gain, 1 ) )
     472             :                 {
     473          23 :                     size = sub( size, 14 );
     474             :                 }
     475        2893 :                 BREAK;
     476             :             }
     477           0 :             case 5:
     478             :             {
     479           0 :                 qua_table = gain_qua_mless_5b_fx; // Q14
     480           0 :                 move16();
     481           0 :                 if ( EQ_16( clip_gain, 1 ) )
     482             :                 {
     483           0 :                     size = sub( size, 6 );
     484             :                 }
     485           0 :                 BREAK;
     486             :             }
     487           0 :             default:
     488             :             {
     489           0 :                 qua_table = gain_qua_mless_6b_fx; // Q14
     490           0 :                 move16();
     491           0 :                 if ( EQ_16( clip_gain, 1 ) )
     492             :                 {
     493           0 :                     size = sub( size, 14 );
     494             :                 }
     495           0 :                 BREAK;
     496             :             }
     497             :         }
     498             : 
     499             :         /* in case of AVQ inactive, limit the gain_pit to 0.65 */
     500        2893 :         test();
     501        2893 :         IF( EQ_16( clip_gain, 2 ) && EQ_16( nBits, 6 ) )
     502             :         {
     503           0 :             size = sub( size, 36 );
     504           0 :             nBits = sub( nBits, 1 );
     505             :         }
     506             : 
     507             :         /*-----------------------------------------------------------------*
     508             :          * search for the best quantizer
     509             :          *-----------------------------------------------------------------*/
     510        2893 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0
     511        2893 :         push_indice( hBstr, IND_GAIN, index, nBits );
     512             :     }
     513             : 
     514             :     /* *norm_gain_code = *gain_code / *gain_inov; */
     515        2916 :     exp = sub( norm_s( *gain_inov ), 1 );
     516        2916 :     exp = s_max( exp, 0 );
     517             : 
     518        2916 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
     519        2916 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) );
     520        2916 :     move32();
     521             : 
     522        2916 :     return;
     523             : }
     524             : 
     525      521364 : void gain_enc_mless_ivas_fx(
     526             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                 */
     527             :     const Word16 gains_mode[], /* i  : gain bits                                                                                                                Q0*/
     528             :     const Word16 element_mode, /* i  : element mode                                                                                                             Q0*/
     529             :     const Word16 L_frame,      /* i  : length of the frame                                                                                              Q0*/
     530             :     const Word16 i_subfr,      /* i  : subframe index                                                                                                   Q0*/
     531             :     const Word16 tc_subfr,     /* i  : TC subframe index                                                                                                Q0*/
     532             :     const Word16 *xn,          /* i  : target vector                                                                                                    Q_xn*/
     533             :     const Word16 *y1,          /* i  : zero-memory filtered adaptive excitation                                                 Q_xn*/
     534             :     const Word16 Q_xn,         /* i  : xn and y1 scaling                                                                                                */
     535             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation                               Q9*/
     536             :     const Word16 *code,        /* i  : algebraic excitation                                                                                             Q9*/
     537             :     const Word16 Es_pred,      /* i  : predicted scaled innovation energy                                                               Q8*/
     538             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                                                                             Q14*/
     539             :     Word32 *gain_code,         /* o  : quantized codebook gain                                                                                  Q16*/
     540             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                                  Q12*/
     541             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                                                    Q16*/
     542             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>    Qx*/
     543             :     const Word16 clip_gain     /* i  : gain pitch clipping flag (1 = clipping)                                                  Q0*/
     544             : )
     545             : {
     546             : 
     547             :     Word16 index, size, nBits, nBits2;
     548             :     Word16 gcode0, Ei, gain_code16;
     549             :     const Word16 *qua_table;
     550             :     Word16 coeff[5], exp_coeff[5];
     551             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
     552             :     Word32 L_tmp, L_tmp1, L_tmp2;
     553             :     Word16 tmp1, expg;
     554             :     Word16 exp1, exp2;
     555             :     Word16 exp_num, exp_den, exp_div, frac_den;
     556             :     Word32 L_frac_num, L_frac_den, L_div;
     557             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     558      521364 :     Flag Overflow = 0;
     559      521364 :     move32();
     560             : #endif
     561             : 
     562             :     /*-----------------------------------------------------------------*
     563             :      * calculate the rest of the correlation coefficients
     564             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
     565             :      *-----------------------------------------------------------------*/
     566             : 
     567      521364 :     coeff[0] = g_corr[0];
     568      521364 :     move16();
     569      521364 :     exp_coeff[0] = g_corr[1];
     570      521364 :     move16();
     571      521364 :     coeff[1] = negate( g_corr[2] );
     572      521364 :     move16(); /* coeff[1] = -2 xn yy1 */
     573      521364 :     exp_coeff[1] = add( g_corr[3], 1 );
     574      521364 :     move16();
     575             : 
     576             :     /* Compute scalar product <y2[],y2[]> */
     577      521364 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
     578      521364 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
     579      521364 :     move16(); /* -18 (y2 Q9) */
     580             : 
     581             :     /* Compute scalar product -2*<xn[],y2[]> */
     582      521364 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
     583      521364 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
     584      521364 :     move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
     585             : 
     586             :     /* Compute scalar product 2*<y1[],y2[]> */
     587      521364 :     coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
     588      521364 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
     589      521364 :     move16(); /* -9 (y2 Q9), +1 (2 y1 y2) */
     590             : 
     591             :     /*-----------------------------------------------------------------*
     592             :      * calculate the unscaled innovation energy
     593             :      * calculate the predicted gain code
     594             :      *-----------------------------------------------------------------*/
     595             : 
     596             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     597      521364 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
     598      521364 :     exp_inov = sub( exp_code, 18 + 6 );
     599             : 
     600             :     // To avoid crash in case code value is 0,
     601      521364 :     IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, exp_inov, 21474836, 0 ), -1 ) )
     602             :     {
     603             :         // setting values to avoid extra computation
     604           0 :         *gain_inov = 32767; /*8(max value gain_inov can hold) in Q12*/
     605           0 :         Ei = -9743;         /* -38 in Q8*/
     606           0 :         move16();
     607           0 :         move16();
     608             :     }
     609             :     ELSE
     610             :     {
     611      521364 :         exp_code = sub( exp_code, 30 );
     612             : 
     613             :         /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     614             : 
     615             :         /*----------------------------------------------------------------*
     616             :          * calculate the predicted gain code
     617             :          *----------------------------------------------------------------*/
     618      521364 :         tmp = norm_l( L_tmp );
     619      521364 :         frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
     620      521364 :         tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
     621      521364 :         L_tmp1 = Mpy_32_16( tmp, frac, 12330 );             /* Q13 */
     622      521364 :         Ei = round_fx( L_shl( L_tmp1, 11 ) );               /* Q8 */
     623             : 
     624             :         /*---------------------------------------------------------------*
     625             :          * Decode codebook gain and the adaptive excitation low-pass
     626             :          * filtering factor (Finalize computation )
     627             :          *---------------------------------------------------------------*/
     628             :         /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     629      521364 :         L_tmp = Isqrt_lc( L_tmp, &exp_inov );
     630      521364 :         *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
     631      521364 :         move16();
     632             :     }
     633             : 
     634             :     /* predicted codebook gain */
     635      521364 :     gcode0 = sub( Es_pred, Ei ); /* Q8 */
     636             : 
     637             :     /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
     638             :     /*----------------------------------------------------------------*
     639             :      * gcode0 = pow(10.0, gcode0/20)
     640             :      *        = pow(2, 3.321928*gcode0/20)
     641             :      *        = pow(2, 0.166096*gcode0)
     642             :      *----------------------------------------------------------------*/
     643             : 
     644      521364 :     L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26    */
     645      521364 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16            */
     646      521364 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
     647             : 
     648      521364 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
     649             :     /* output of Pow2() will be: */
     650             :     /* 16384 < Pow2() <= 32767   */
     651      521364 :     exp_gcode0 = sub( exp_gcode0, 14 );
     652             : 
     653             :     /*-----------------------------------------------------------------*
     654             :      * select the codebook, size and number of bits
     655             :      * set the gains searching range
     656             :      *-----------------------------------------------------------------*/
     657      521364 :     nBits = gains_mode[i_subfr >> 6];
     658      521364 :     move16();
     659             : 
     660      521364 :     test();
     661      521364 :     test();
     662      521364 :     test();
     663      521364 :     test();
     664      521364 :     test();
     665      521364 :     IF( ( EQ_16( tc_subfr, 3 * L_SUBFR ) && EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( L_frame, L_FRAME ) ) ||
     666             :         ( EQ_16( tc_subfr, 4 * L_SUBFR ) && EQ_16( i_subfr, 4 * L_SUBFR ) && EQ_16( L_frame, L_FRAME16k ) ) )
     667             :     {
     668             :         /*    *gain_pit =  (g_corr[2]*tmp2) - (0.5f*g_corr[4]*tmp3);
     669             :                         =  ((-0.5f*g_corr[1]*g_corr[2]) - (-0.25*g_corr[3]*g_corr[4]))/tmp1;
     670             :                         =  ((0.25*g_corr[3]*g_corr[4]) - (0.5*g_corr[1]*g_corr[2]))/tmp1; */
     671             : 
     672             :         /*     *gain_code = (g_corr[0]*tmp3) - (0.5f*g_corr[4]*tmp2);
     673             :                           = ((-0.5*g_corr[3]*g_corr[0]) - (-0.25*g_corr[1]*g_corr[4]))/tmp1;
     674             :                           = ((0.25*g_corr[1]*g_corr[4]) - (0.5*g_corr[0]*g_corr[3]))/tmp1; */
     675             : 
     676        3610 :         L_tmp1 = L_mult_sat( coeff[0], coeff[2] ); /*Q31 added saturation for -32768*-32768*/
     677        3610 :         exp1 = add( exp_coeff[0], exp_coeff[2] );
     678             : 
     679        3610 :         L_tmp2 = L_shr( L_mult_sat( coeff[4], coeff[4] ), 2 ); /*Q31 added saturation for -32768*-32768*/
     680        3610 :         exp2 = add( exp_coeff[4], exp_coeff[4] );
     681             : 
     682        3610 :         IF( GT_16( exp1, exp2 ) )
     683             :         {
     684        3506 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     685        3506 :             exp_den = exp1;
     686        3506 :             move16();
     687             :         }
     688             :         ELSE
     689             :         {
     690         104 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     691         104 :             exp_den = exp2;
     692         104 :             move16();
     693             :         }
     694        3610 :         L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     695             : 
     696        3610 :         frac_den = extract_h( L_frac_den );  /* Q15 */
     697        3610 :         frac_den = s_max( frac_den, 1 );     /* Q15 */
     698        3610 :         L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
     699        3610 :         exp = norm_l( L_frac_den );
     700        3610 :         tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
     701             : 
     702        3610 :         L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
     703        3610 :         exp1 = add( exp_coeff[3], exp_coeff[4] );
     704             : 
     705        3610 :         L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
     706        3610 :         exp2 = add( exp_coeff[1], exp_coeff[2] );
     707             : 
     708        3610 :         IF( GT_16( exp1, exp2 ) )
     709             :         {
     710         124 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     711         124 :             exp_num = exp1;
     712         124 :             move16();
     713             :         }
     714             :         ELSE
     715             :         {
     716        3486 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     717        3486 :             exp_num = exp2;
     718        3486 :             move16();
     719             :         }
     720        3610 :         L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     721             : 
     722        3610 :         L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     723        3610 :         exp_div = sub( exp_num, exp_den );
     724             : 
     725        3610 :         *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
     726             : 
     727        3610 :         L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
     728        3610 :         exp1 = add( exp_coeff[1], exp_coeff[4] );
     729             : 
     730        3610 :         L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
     731        3610 :         exp2 = add( exp_coeff[0], exp_coeff[3] );
     732             : 
     733        3610 :         IF( GT_16( exp1, exp2 ) )
     734             :         {
     735          55 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     736          55 :             exp_num = exp1;
     737          55 :             move16();
     738             :         }
     739             :         ELSE
     740             :         {
     741        3555 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     742        3555 :             exp_num = exp2;
     743        3555 :             move16();
     744             :         }
     745        3610 :         L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     746             : 
     747        3610 :         L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     748        3610 :         exp_div = sub( exp_num, exp_den );
     749             : 
     750        3610 :         *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
     751        3610 :         move32(); /*Q16*/
     752             : 
     753        3610 :         *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) );
     754             : 
     755             :         /* set number of bits for two SQs */
     756        3610 :         nBits2 = shr( add( nBits, 1 ), 1 );
     757        3610 :         nBits = shr( nBits, 1 );
     758             : 
     759             :         /* gain_pit Q */
     760             : 
     761        3610 :         tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
     762        3610 :         index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
     763        3610 :         move16();
     764        3610 :         push_indice( hBstr, IND_GAIN_PIT, index, nBits );
     765             : 
     766             :         /* gain_code Q */
     767             :         /**gain_code /= gcode0;*/
     768        3610 :         IF( gcode0 != 0 )
     769             :         {
     770        3610 :             tmp = div_s( 16384, gcode0 );                       /*Q15*/
     771        3610 :             L_tmp = Mult_32_16( *gain_code, tmp );              /*Q16*/
     772        3610 :             *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
     773        3610 :             move32();
     774             :         }
     775             : 
     776        3610 :         index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
     777        3610 :         push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
     778        3610 :         L_tmp = L_mult( gain_code16, gcode0 );                                        /*Q0*Q0 -> Q1*/
     779        3610 :         *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/
     780             :     }
     781             :     ELSE
     782             :     {
     783      517754 :         size = shl( 1, nBits );
     784             : 
     785      517754 :         SWITCH( nBits )
     786             :         {
     787         751 :             case 7:
     788             :             {
     789         751 :                 qua_table = gain_qua_mless_7b_fx; // Q14
     790         751 :                 if ( EQ_16( clip_gain, 1 ) )
     791             :                 {
     792           0 :                     size = sub( size, 30 );
     793             :                 }
     794         751 :                 BREAK;
     795             :             }
     796      516497 :             case 6:
     797             :             {
     798      516497 :                 qua_table = gain_qua_mless_6b_fx; // Q14
     799      516497 :                 if ( element_mode > EVS_MONO )
     800             :                 {
     801      516497 :                     qua_table = gain_qua_mless_6b_stereo_fx;
     802             :                 }
     803      516497 :                 if ( EQ_16( clip_gain, 1 ) )
     804             :                 {
     805        5940 :                     size = sub( size, 14 );
     806             :                 }
     807      516497 :                 BREAK;
     808             :             }
     809         506 :             case 5:
     810             :             {
     811         506 :                 qua_table = gain_qua_mless_5b_fx; // Q14
     812         506 :                 if ( EQ_16( clip_gain, 1 ) )
     813             :                 {
     814           0 :                     size = sub( size, 6 );
     815             :                 }
     816         506 :                 BREAK;
     817             :             }
     818           0 :             default:
     819             :             {
     820           0 :                 qua_table = gain_qua_mless_6b_fx; // Q14
     821           0 :                 if ( EQ_16( clip_gain, 1 ) )
     822             :                 {
     823           0 :                     size = sub( size, 14 );
     824             :                 }
     825           0 :                 BREAK;
     826             :             }
     827             :         }
     828             : 
     829             :         /* in case of AVQ inactive, limit the gain_pit to 0.65 */
     830      517754 :         test();
     831      517754 :         IF( EQ_16( clip_gain, 2 ) && EQ_16( nBits, 6 ) )
     832             :         {
     833        5325 :             size = sub( size, 36 );
     834        5325 :             nBits = sub( nBits, 1 );
     835             :         }
     836             : 
     837             :         /*-----------------------------------------------------------------*
     838             :          * search for the best quantizer
     839             :          *-----------------------------------------------------------------*/
     840      517754 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size );
     841      517754 :         push_indice( hBstr, IND_GAIN, index, nBits );
     842             :     }
     843             : 
     844             :     /* *norm_gain_code = *gain_code / *gain_inov; */
     845      521364 :     exp = sub( norm_s( *gain_inov ), 1 );
     846      521364 :     exp = s_max( exp, 0 );
     847             : 
     848      521364 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
     849      521364 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
     850      521364 :     move32();
     851             : 
     852      521364 :     return;
     853             : }
     854             : 
     855             : /*---------------------------------------------------------------------*
     856             :  * gain_enc_SQ()
     857             :  *
     858             :  * Scalar Quantization of pitch and codebook gains without prediction
     859             :  * - an initial predicted gain, gcode0, is first determined based on
     860             :  *   the predicted scaled innovation energy
     861             :  * - a correction factor gamma = g_code / gcode0 is then vector quantized
     862             :  *   along with gain_pit
     863             :  * - the mean-squared weighted error criterion is used for codebook search
     864             :  *---------------------------------------------------------------------*/
     865             : 
     866        3358 : void gain_enc_SQ_fx(
     867             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                 */
     868             :     const Word16 gains_mode[], /* i  : gain bits                                                                                                                Q0*/
     869             :     const Word16 i_subfr,      /* i  : subframe index                                                                                                   Q0*/
     870             :     const Word16 *xn,          /* i  : target vector                                                                                                    Q_xn*/
     871             :     const Word16 *yy1,         /* i  : zero-memory filtered adaptive excitation                                                 Q_xn*/
     872             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation                               Q9*/
     873             :     const Word16 *code,        /* i  : algebraic excitation                                                                                             Q9*/
     874             :     const Word16 Es_pred,      /* i  : predicted scaled innovation energy                                                               Q8*/
     875             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                                                                             Q14*/
     876             :     Word32 *gain_code,         /* o  : quantized codebook gain                                                                                  Q16*/
     877             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                                  Q12*/
     878             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                                                    Q16*/
     879             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, <xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>      Qx*/
     880             :     const Word16 clip_gain,    /* i  : gain pitch clipping flag (1 = clipping)                                                  Q0*/
     881             :     const Word16 Q_xn          /* i  : xn and y1 scaling                                                                                                */
     882             : )
     883             : {
     884             :     Word16 index, nBits_pitch, nBits_code;
     885             :     Word16 gcode0, Ei, gain_code16;
     886             :     Word16 coeff[5], exp_coeff[5];
     887             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
     888             : 
     889             :     Word32 L_tmp, L_tmp1, L_tmp2;
     890             :     Word16 tmp1, expg;
     891             :     Word16 exp1, exp2;
     892             :     Word16 exp_num, exp_den, exp_div, frac_den;
     893             :     Word32 L_frac_num, L_frac_den, L_div;
     894             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     895        3358 :     Flag Overflow = 0;
     896        3358 :     move32();
     897             : #endif
     898             : 
     899             :     /*-----------------------------------------------------------------*
     900             :      * calculate the rest of the correlation coefficients
     901             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
     902             :      *-----------------------------------------------------------------*/
     903             :     /*g_corr[1] *= -0.5;*/
     904             :     /*g_corr[2] = dotp( y2, y2, L_SUBFR )  + 0.01f;*/
     905             :     /*g_corr[3] = dotp( xn, y2, L_SUBFR )  - 0.02f;*/
     906             :     /*g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f;*/
     907             : 
     908        3358 :     coeff[0] = g_corr[0];
     909        3358 :     move16();
     910        3358 :     exp_coeff[0] = g_corr[1];
     911        3358 :     move16();
     912        3358 :     coeff[1] = g_corr[2];
     913        3358 :     move16(); /* coeff[1] = xn yy1 */
     914        3358 :     exp_coeff[1] = g_corr[3];
     915        3358 :     move16();
     916             : 
     917             :     /* Compute scalar product <y2[],y2[]> */
     918        3358 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
     919        3358 :     move16();
     920        3358 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
     921        3358 :     move16(); /* -18 (y2 Q9) */
     922             : 
     923             :     /* Compute scalar product <xn[],y2[]> */
     924        3358 :     coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) );
     925        3358 :     move16();
     926        3358 :     exp_coeff[3] = add( sub( exp, 9 ), Q_xn );
     927        3358 :     move16(); /* -9 (y2 Q9), (xn y2) */
     928             : 
     929             :     /* Compute scalar product <y1[],y2[]> */
     930        3358 :     coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
     931        3358 :     move16();
     932        3358 :     exp_coeff[4] = add( sub( exp, 9 ), Q_xn );
     933        3358 :     move16(); /* -9 (y2 Q9), (y1 y2) */
     934             : 
     935             :     /*-----------------------------------------------------------------*
     936             :      * calculate the unscaled innovation energy
     937             :      * calculate the predicted gain code
     938             :      * calculate optimal gains
     939             :      *-----------------------------------------------------------------*/
     940             :     /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
     941             :     /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
     942             : 
     943        3358 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
     944        3358 :     exp_inov = sub( exp_code, 18 + 6 );
     945        3358 :     exp_code = sub( exp_code, 30 );
     946             : 
     947             :     /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     948             :     /*----------------------------------------------------------------*
     949             :      * calculate the predicted gain code
     950             :      *----------------------------------------------------------------*/
     951        3358 :     tmp = norm_l( L_tmp );
     952        3358 :     frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
     953        3358 :     tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
     954        3358 :     L_tmp1 = Mpy_32_16( tmp, frac, 12330 );             /* Q13 */
     955        3358 :     Ei = round_fx( L_shl( L_tmp1, 11 ) );               /* Q8 */
     956             : 
     957             :     /* predicted codebook gain */
     958        3358 :     gcode0 = sub( Es_pred, Ei ); /* Q8 */
     959             : 
     960             :     /*---------------------------------------------------------------*
     961             :      * Decode codebook gain and the adaptive excitation low-pass
     962             :      * filtering factor (Finalize computation )
     963             :      *---------------------------------------------------------------*/
     964             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     965        3358 :     L_tmp = Isqrt_lc( L_tmp, &exp_inov );
     966        3358 :     *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
     967             : 
     968             :     /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
     969             :     /*----------------------------------------------------------------*
     970             :      * gcode0 = pow(10.0, gcode0/20)
     971             :      *        = pow(2, 3.321928*gcode0/20)
     972             :      *        = pow(2, 0.166096*gcode0)
     973             :      *----------------------------------------------------------------*/
     974             : 
     975        3358 :     L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26    */
     976        3358 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16            */
     977        3358 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
     978             : 
     979        3358 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
     980             :     /* output of Pow2() will be: */
     981             :     /* 16384 < Pow2() <= 32767   */
     982        3358 :     exp_gcode0 = sub( exp_gcode0, 14 );
     983             : 
     984             : 
     985             :     /*tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]);
     986             :     tmp2 = g_corr[1]/tmp1;
     987             :     tmp1 = g_corr[3]/tmp1;
     988             : 
     989             :     *gain_pit =  (g_corr[2]*tmp2) - (g_corr[4]*tmp1);
     990             :     *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2);*/
     991             : 
     992             :     /*    *gain_pit =  (g_corr[2]*tmp2) - (g_corr[4]*tmp3);
     993             :                   =  ((g_corr[1]*g_corr[2]) - (g_corr[3]*g_corr[4]))/tmp1;*/
     994             : 
     995             :     /*     *gain_code = (g_corr[0]*tmp3) - (g_corr[4]*tmp2);
     996             :                    = ((g_corr[3]*g_corr[0]) - (g_corr[1]*g_corr[4]))/tmp1;*/
     997             : 
     998        3358 :     L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
     999        3358 :     exp1 = add( exp_coeff[0], exp_coeff[2] );
    1000             : 
    1001        3358 :     L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/
    1002        3358 :     exp2 = add( exp_coeff[4], exp_coeff[4] );
    1003             : 
    1004        3358 :     IF( GT_16( exp1, exp2 ) )
    1005             :     {
    1006        3352 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
    1007        3352 :         exp_den = exp1;
    1008        3352 :         move16();
    1009             :     }
    1010             :     ELSE
    1011             :     {
    1012           6 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
    1013           6 :         exp_den = exp2;
    1014           6 :         move16();
    1015             :     }
    1016        3358 :     L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
    1017             : 
    1018        3358 :     frac_den = extract_h( L_frac_den );  /* Q15 */
    1019        3358 :     frac_den = s_max( frac_den, 1 );     /* Q15 */
    1020        3358 :     L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
    1021        3358 :     exp = norm_l( L_frac_den );
    1022        3358 :     tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
    1023             : 
    1024             : 
    1025        3358 :     L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/
    1026        3358 :     exp1 = add( exp_coeff[3], exp_coeff[4] );
    1027             : 
    1028        3358 :     L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/
    1029        3358 :     exp2 = add( exp_coeff[1], exp_coeff[2] );
    1030             : 
    1031        3358 :     IF( GT_16( exp1, exp2 ) )
    1032             :     {
    1033          40 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
    1034          40 :         exp_num = exp1;
    1035          40 :         move16();
    1036             :     }
    1037             :     ELSE
    1038             :     {
    1039        3318 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
    1040        3318 :         exp_num = exp2;
    1041        3318 :         move16();
    1042             :     }
    1043        3358 :     L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
    1044             : 
    1045        3358 :     L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
    1046        3358 :     exp_div = sub( exp_num, exp_den );
    1047             : 
    1048        3358 :     *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
    1049             : 
    1050        3358 :     L_tmp1 = L_mult( coeff[1], coeff[4] ); /*Q31*/
    1051        3358 :     exp1 = add( exp_coeff[1], exp_coeff[4] );
    1052             : 
    1053        3358 :     L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/
    1054        3358 :     exp2 = add( exp_coeff[0], exp_coeff[3] );
    1055             : 
    1056        3358 :     IF( GT_16( exp1, exp2 ) )
    1057             :     {
    1058         255 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
    1059         255 :         exp_num = exp1;
    1060         255 :         move16();
    1061             :     }
    1062             :     ELSE
    1063             :     {
    1064        3103 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
    1065        3103 :         exp_num = exp2;
    1066        3103 :         move16();
    1067             :     }
    1068        3358 :     L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
    1069             : 
    1070        3358 :     L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
    1071        3358 :     exp_div = sub( exp_num, exp_den );
    1072             : 
    1073        3358 :     *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) );
    1074        3358 :     move32(); /*Q16*/
    1075             : 
    1076        3358 :     *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) );
    1077             : 
    1078             :     /*-----------------------------------------------------------------*
    1079             :      * limit the pitch gain searching range (if indicated by clip_gain)
    1080             :      *-----------------------------------------------------------------*/
    1081             : 
    1082        3358 :     test();
    1083        3358 :     test();
    1084        3358 :     IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) )
    1085             :     {
    1086          26 :         *gain_pit = 15565; /* 0.95 in Q14 */
    1087          26 :         move16();
    1088             :     }
    1089        3332 :     ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) )
    1090             :     {
    1091           0 :         *gain_pit = 10650; /* 0.65 in Q14 */
    1092           0 :         move16();
    1093             :     }
    1094             : 
    1095             :     /*-----------------------------------------------------------------*
    1096             :      * search for the best quantized values
    1097             :      *-----------------------------------------------------------------*/
    1098             : 
    1099        3358 :     nBits_pitch = gains_mode[i_subfr >> 6];
    1100        3358 :     move16();
    1101             : 
    1102             :     /* set number of bits for two SQs */
    1103        3358 :     nBits_code = shr( add( nBits_pitch, 1 ), 1 );
    1104        3358 :     nBits_pitch = shr( nBits_pitch, 1 );
    1105             : 
    1106             :     /* gain_pit Q */
    1107             :     /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/                     /* set quantization step */
    1108        3358 :     tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */
    1109             : 
    1110        3358 :     index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); // Q0
    1111        3358 :     push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch );
    1112             : 
    1113             :     /* gain_code Q */
    1114             :     /* *gain_code /= gcode0; */
    1115        3358 :     IF( gcode0 != 0 )
    1116             :     {
    1117        3358 :         tmp = div_s( 16384, gcode0 );                       /*Q15*/
    1118        3358 :         L_tmp = Mult_32_16( *gain_code, tmp );              /*Q16*/
    1119        3358 :         *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
    1120        3358 :         move32();
    1121             :     }
    1122             : 
    1123        3358 :     index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg );
    1124        3358 :     push_indice( hBstr, IND_GAIN_CODE, index, nBits_code );
    1125        3358 :     L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
    1126        3358 :     *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) );
    1127        3358 :     move32(); /*Q16*/
    1128             : 
    1129             :     /* *norm_gain_code = *gain_code / *gain_inov; */
    1130        3358 :     exp = sub( norm_s( *gain_inov ), 1 );
    1131        3358 :     exp = s_max( exp, 0 );
    1132             : 
    1133        3358 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
    1134        3358 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
    1135        3358 :     move32();
    1136             : 
    1137        3358 :     return;
    1138             : }
    1139             : 
    1140       43280 : void gain_enc_SQ_ivas_fx(
    1141             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                 */
    1142             :     const Word16 gains_mode[], /* i  : gain bits                                                                                                                Q0*/
    1143             :     const Word16 i_subfr,      /* i  : subframe index                                                                                                   Q0*/
    1144             :     const Word16 *xn,          /* i  : target vector                                                                                                    Q_xn*/
    1145             :     const Word16 *yy1,         /* i  : zero-memory filtered adaptive excitation                                                 Q_xn*/
    1146             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation                               Q9*/
    1147             :     const Word16 *code,        /* i  : algebraic excitation                                                                                             Q9*/
    1148             :     const Word16 Es_pred,      /* i  : predicted scaled innovation energy                                                               Q8*/
    1149             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                                                                             Q14*/
    1150             :     Word32 *gain_code,         /* o  : quantized codebook gain                                                                                  Q16*/
    1151             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                                  Q12*/
    1152             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                                                    Q16*/
    1153             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, <xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>      Qx*/
    1154             :     const Word16 clip_gain,    /* i  : gain pitch clipping flag (1 = clipping)                                                  Q0*/
    1155             :     const Word16 Q_xn          /* i  : xn and y1 scaling                                                                                                */
    1156             : )
    1157             : {
    1158             :     Word16 index, nBits_pitch, nBits_code;
    1159             :     Word16 gcode0, Ei, gain_code16;
    1160             :     Word16 coeff[5], exp_coeff[5];
    1161             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
    1162             : 
    1163             :     Word32 L_tmp, L_tmp1, L_tmp2;
    1164             :     Word16 tmp1, expg;
    1165             :     Word16 exp1, exp2;
    1166             :     Word16 exp_num, exp_den, exp_div, frac_den;
    1167             :     Word32 L_frac_num, L_frac_den, L_div;
    1168             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1169       43280 :     Flag Overflow = 0;
    1170       43280 :     move32();
    1171             : #endif
    1172             : 
    1173             :     /*-----------------------------------------------------------------*
    1174             :      * calculate the rest of the correlation coefficients
    1175             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
    1176             :      *-----------------------------------------------------------------*/
    1177             :     /*g_corr[1] *= -0.5;*/
    1178             :     /*g_corr[2] = dotp( y2, y2, L_SUBFR )  + 0.01f;*/
    1179             :     /*g_corr[3] = dotp( xn, y2, L_SUBFR )  - 0.02f;*/
    1180             :     /*g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f;*/
    1181             : 
    1182       43280 :     coeff[0] = g_corr[0];
    1183       43280 :     move16();
    1184       43280 :     exp_coeff[0] = g_corr[1];
    1185       43280 :     move16();
    1186       43280 :     coeff[1] = g_corr[2];
    1187       43280 :     move16(); /* coeff[1] = xn yy1 */
    1188       43280 :     exp_coeff[1] = g_corr[3];
    1189       43280 :     move16();
    1190             : 
    1191             :     /* Compute scalar product <y2[],y2[]> */
    1192       43280 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
    1193       43280 :     move16();
    1194       43280 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
    1195       43280 :     move16(); /* -18 (y2 Q9) */
    1196             : 
    1197             :     /* Compute scalar product <xn[],y2[]> */
    1198       43280 :     coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) );
    1199       43280 :     move16();
    1200       43280 :     exp_coeff[3] = add( sub( exp, 9 ), Q_xn );
    1201       43280 :     move16(); /* -9 (y2 Q9), (xn y2) */
    1202             : 
    1203             :     /* Compute scalar product <y1[],y2[]> */
    1204       43280 :     coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
    1205       43280 :     move16();
    1206       43280 :     exp_coeff[4] = add( sub( exp, 9 ), Q_xn );
    1207       43280 :     move16(); /* -9 (y2 Q9), (y1 y2) */
    1208             : 
    1209             :     /*-----------------------------------------------------------------*
    1210             :      * calculate the unscaled innovation energy
    1211             :      * calculate the predicted gain code
    1212             :      * calculate optimal gains
    1213             :      *-----------------------------------------------------------------*/
    1214             :     /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
    1215             :     /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
    1216             : 
    1217       43280 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
    1218       43280 :     exp_inov = sub( exp_code, 18 + 6 );
    1219       43280 :     exp_code = sub( exp_code, 30 );
    1220             : 
    1221             :     /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
    1222             :     /*----------------------------------------------------------------*
    1223             :      * calculate the predicted gain code
    1224             :      *----------------------------------------------------------------*/
    1225       43280 :     tmp = norm_l( L_tmp );
    1226       43280 :     frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
    1227       43280 :     tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
    1228       43280 :     L_tmp1 = Mpy_32_16( tmp, frac, 12330 );             /* Q13 */
    1229       43280 :     Ei = round_fx( L_shl( L_tmp1, 11 ) );               /* Q8 */
    1230             : 
    1231             :     /* predicted codebook gain */
    1232       43280 :     gcode0 = sub( Es_pred, Ei ); /* Q8 */
    1233             : 
    1234             :     /*---------------------------------------------------------------*
    1235             :      * Decode codebook gain and the adaptive excitation low-pass
    1236             :      * filtering factor (Finalize computation )
    1237             :      *---------------------------------------------------------------*/
    1238             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
    1239       43280 :     L_tmp = Isqrt_lc( L_tmp, &exp_inov );
    1240       43280 :     *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
    1241             : 
    1242             :     /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
    1243             :     /*----------------------------------------------------------------*
    1244             :      * gcode0 = pow(10.0, gcode0/20)
    1245             :      *        = pow(2, 3.321928*gcode0/20)
    1246             :      *        = pow(2, 0.166096*gcode0)
    1247             :      *----------------------------------------------------------------*/
    1248             : 
    1249       43280 :     L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26    */
    1250       43280 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16            */
    1251       43280 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1252             : 
    1253       43280 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1254             :     /* output of Pow2() will be: */
    1255             :     /* 16384 < Pow2() <= 32767   */
    1256       43280 :     exp_gcode0 = sub( exp_gcode0, 14 );
    1257             : 
    1258             : 
    1259             :     /*tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]);
    1260             :     tmp2 = g_corr[1]/tmp1;
    1261             :     tmp1 = g_corr[3]/tmp1;
    1262             : 
    1263             :     *gain_pit =  (g_corr[2]*tmp2) - (g_corr[4]*tmp1);
    1264             :     *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2);*/
    1265             : 
    1266             :     /*    *gain_pit =  (g_corr[2]*tmp2) - (g_corr[4]*tmp3);
    1267             :                   =  ((g_corr[1]*g_corr[2]) - (g_corr[3]*g_corr[4]))/tmp1;*/
    1268             : 
    1269             :     /*     *gain_code = (g_corr[0]*tmp3) - (g_corr[4]*tmp2);
    1270             :                    = ((g_corr[3]*g_corr[0]) - (g_corr[1]*g_corr[4]))/tmp1;*/
    1271             : 
    1272       43280 :     L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
    1273       43280 :     exp1 = add( exp_coeff[0], exp_coeff[2] );
    1274             : 
    1275       43280 :     L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/
    1276       43280 :     exp2 = add( exp_coeff[4], exp_coeff[4] );
    1277             : 
    1278       43280 :     IF( GT_16( exp1, exp2 ) )
    1279             :     {
    1280       43202 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
    1281       43202 :         exp_den = exp1;
    1282       43202 :         move16();
    1283             :     }
    1284             :     ELSE
    1285             :     {
    1286          78 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
    1287          78 :         exp_den = exp2;
    1288          78 :         move16();
    1289             :     }
    1290       43280 :     L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
    1291             : 
    1292       43280 :     frac_den = extract_h( L_frac_den );  /* Q15 */
    1293       43280 :     frac_den = s_max( frac_den, 1 );     /* Q15 */
    1294       43280 :     L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
    1295       43280 :     exp = norm_l( L_frac_den );
    1296       43280 :     tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
    1297             : 
    1298             : 
    1299       43280 :     L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/
    1300       43280 :     exp1 = add( exp_coeff[3], exp_coeff[4] );
    1301             : 
    1302       43280 :     L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/
    1303       43280 :     exp2 = add( exp_coeff[1], exp_coeff[2] );
    1304             : 
    1305       43280 :     IF( GT_16( exp1, exp2 ) )
    1306             :     {
    1307        1306 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
    1308        1306 :         exp_num = exp1;
    1309        1306 :         move16();
    1310             :     }
    1311             :     ELSE
    1312             :     {
    1313       41974 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
    1314       41974 :         exp_num = exp2;
    1315       41974 :         move16();
    1316             :     }
    1317       43280 :     L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
    1318             : 
    1319       43280 :     L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
    1320       43280 :     exp_div = sub( exp_num, exp_den );
    1321             : 
    1322       43280 :     *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
    1323       43280 :     move16();
    1324             : 
    1325             :     // To be checked
    1326       43280 :     L_tmp1 = L_mult_o( coeff[1], coeff[4], &Overflow ); /*Q31*/
    1327       43280 :     exp1 = add( exp_coeff[1], exp_coeff[4] );
    1328             : 
    1329       43280 :     L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/
    1330       43280 :     exp2 = add( exp_coeff[0], exp_coeff[3] );
    1331             : 
    1332       43280 :     IF( GT_16( exp1, exp2 ) )
    1333             :     {
    1334        1285 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
    1335        1285 :         exp_num = exp1;
    1336        1285 :         move16();
    1337             :     }
    1338             :     ELSE
    1339             :     {
    1340       41995 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
    1341       41995 :         exp_num = exp2;
    1342       41995 :         move16();
    1343             :     }
    1344       43280 :     L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
    1345             : 
    1346       43280 :     L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
    1347       43280 :     exp_div = sub( exp_num, exp_den );
    1348             : 
    1349       43280 :     *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) );
    1350       43280 :     move32(); /*Q16*/
    1351             : 
    1352       43280 :     *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) );
    1353             : 
    1354             :     /*-----------------------------------------------------------------*
    1355             :      * limit the pitch gain searching range (if indicated by clip_gain)
    1356             :      *-----------------------------------------------------------------*/
    1357             : 
    1358       43280 :     test();
    1359       43280 :     test();
    1360       43280 :     IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) )
    1361             :     {
    1362           2 :         *gain_pit = 15565; /* 0.95 in Q14 */
    1363           2 :         move16();
    1364             :     }
    1365       43278 :     ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) )
    1366             :     {
    1367        1029 :         *gain_pit = 10650; /* 0.65 in Q14 */
    1368        1029 :         move16();
    1369             :     }
    1370             : 
    1371             :     /*-----------------------------------------------------------------*
    1372             :      * search for the best quantized values
    1373             :      *-----------------------------------------------------------------*/
    1374             : 
    1375       43280 :     nBits_pitch = gains_mode[i_subfr >> 6];
    1376       43280 :     move16();
    1377             : 
    1378             :     /* set number of bits for two SQs */
    1379       43280 :     nBits_code = shr( add( nBits_pitch, 1 ), 1 );
    1380       43280 :     nBits_pitch = shr( nBits_pitch, 1 );
    1381             : 
    1382             :     /* gain_pit Q */
    1383             :     /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/                     /* set quantization step */
    1384       43280 :     tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */
    1385             : 
    1386       43280 :     index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) );
    1387       43280 :     push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch );
    1388             : 
    1389             :     /* gain_code Q */
    1390             :     /* *gain_code /= gcode0; */
    1391       43280 :     IF( gcode0 != 0 )
    1392             :     {
    1393       43280 :         tmp = div_s( 16384, gcode0 );                       /*Q15*/
    1394       43280 :         L_tmp = Mult_32_16( *gain_code, tmp );              /*Q16*/
    1395       43280 :         *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
    1396       43280 :         move32();
    1397             :     }
    1398             : 
    1399       43280 :     index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg );
    1400       43280 :     push_indice( hBstr, IND_GAIN_CODE, index, nBits_code );
    1401       43280 :     L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
    1402       43280 :     *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) );
    1403       43280 :     move32(); /*Q16*/
    1404             : 
    1405             :     /* *norm_gain_code = *gain_code / *gain_inov; */
    1406       43280 :     exp = sub( norm_s( *gain_inov ), 1 );
    1407       43280 :     exp = s_max( exp, 0 );
    1408             : 
    1409       43280 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
    1410       43280 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
    1411       43280 :     move32();
    1412             : 
    1413       43280 :     return;
    1414             : }
    1415             : 
    1416             : /*-------------------------------------------------------------------*
    1417             :  * gain_enc_gaus()
    1418             :  *
    1419             :  * Quantization of gain for Gaussian codebook
    1420             :  *-------------------------------------------------------------------*/
    1421           0 : Word16 gain_enc_gaus_fx(                           /* o  : Return index of quantization     */
    1422             :                          Word32 *gain,             /* i/o: Code gain to quantize            Q16*/
    1423             :                          const Word16 bits,        /* i  : number of bits to quantize       Q0*/
    1424             :                          const Word16 lowBound,    /* i  : lower bound of quantizer (dB)        Q8*/
    1425             :                          const Word16 stepSize,    /* i  : Step size choice                                     Q14*/
    1426             :                          const Word16 inv_stepSize /* i  : Step size choice                                     Q15*/
    1427             : )
    1428             : {
    1429             :     Word16 index, exp_gain, frac_gain, wtmp;
    1430             :     Word16 enr_q, wenr;
    1431             :     Word32 Ltmp, enr;
    1432             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1433           0 :     Flag Overflow = 0;
    1434           0 :     move32();
    1435             : #endif
    1436             :     /*enr = 20.0 * log10(*gain + 0.001)     codebook gain in dB  */
    1437           0 :     exp_gain = norm_l( *gain );
    1438           0 :     frac_gain = Log2_norm_lc( L_shl( *gain, exp_gain ) );
    1439           0 :     exp_gain = sub( 30 - 16, exp_gain );
    1440             : 
    1441           0 :     enr = Mpy_32_16( exp_gain, frac_gain, LG10 ); /* Output in Q13 */
    1442           0 :     wenr = extract_h( L_shl( enr, 8 + 3 ) );
    1443             : 
    1444             :     /*----------------------------------------------------------------*
    1445             :      * Quantize linearly the log E
    1446             :      *----------------------------------------------------------------*/
    1447             : 
    1448           0 :     wtmp = sub( wenr, lowBound ); /* Q8 */
    1449             : 
    1450           0 :     index = extract_l( L_shr( L_mac( 8388608, wtmp, inv_stepSize ), 16 + 8 ) ); // Q0
    1451             : 
    1452             :     /* index [0 (1<<bits)-1] */
    1453           0 :     index = s_min( index, sub( shl( 1, bits ), 1 ) ); // Q0
    1454           0 :     index = s_max( index, 0 );
    1455             : 
    1456           0 :     Ltmp = L_mac( L_shl( lowBound, 7 ), index, stepSize );
    1457           0 :     enr_q = round_fx( L_shl( Ltmp, 16 - 7 ) ); /* enr_q Q8 */
    1458             : 
    1459             :     /* gain = (float)pow( 10.0f, enr/20.0f )   quantized codebook gain */
    1460           0 :     enr = L_mult( enr_q, 21772 ); /* 0.166096 in Q17 -> Q26 */
    1461           0 :     enr = L_shr( enr, 10 );       /*Q26->Q16*/
    1462           0 :     frac_gain = L_Extract_lc( enr, &exp_gain );
    1463             : 
    1464           0 :     Ltmp = Pow2( 14, frac_gain );   /* Put 14 as exponent */
    1465           0 :     exp_gain = sub( exp_gain, 14 ); /* Retreive exponent of wtmp */
    1466           0 :     *gain = L_shl_o( Ltmp, add( 16, exp_gain ), &Overflow );
    1467           0 :     move32(); /*Q16*/
    1468             : 
    1469           0 :     return index;
    1470             : }
    1471             : /*-----------------------------------------------------------------*
    1472             :  * gain_enc_tc()
    1473             :  *
    1474             :  * Search and quantization of gain_code for subframes (in the
    1475             :  * beginning of frame) without pulses in TC - 3b coding.
    1476             :  * In this case:
    1477             :  * - gain_pit = 0
    1478             :  * - gain_code - scalar quantization (no prediciton history used)
    1479             :  *-----------------------------------------------------------------*/
    1480         102 : void gain_enc_tc_fx(
    1481             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                   */
    1482             :     const Word16 gains_mode[], /* i  : gain bits                                          Q0*/
    1483             :     const Word16 i_subfr,      /* i  : subframe index                                     Q0*/
    1484             :     const Word16 xn_fx[],      /* i  : target vector                                      Q_xn*/
    1485             :     const Word16 y2_fx[],      /* i  : zero-memory filtered algebraic codebook excitation Q_xn*/
    1486             :     const Word16 code_fx[],    /* i  : algebraic excitation                               Q9*/
    1487             :     const Word16 Es_pred_fx,   /* i  : predicted scaled innovation energy                 Q8*/
    1488             :     Word16 *gain_pit_fx,       /* o  : Pitch gain / Quantized pitch gain                  Q14*/
    1489             :     Word32 *gain_code_fx,      /* o  : quantized codebook gain                            Q16*/
    1490             :     Word16 *gain_inov_fx,      /* o  : innovation gain                                    Q12*/
    1491             :     Word32 *norm_gain_code_fx, /* o  : norm. gain of the codebook excitation              Q16*/
    1492             :     const Word16 Q_xn          /* i  : xn and y1 scaling                                                                  */
    1493             : )
    1494             : {
    1495         102 :     Word16 i, index = 0, nBits, num, den, exp_num, exp_den;
    1496             :     Word16 Ei_fx, g_code_fx, gcode0_fx;
    1497             :     Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac, tmp16;
    1498             :     Word32 L_tmp, L_tmp1;
    1499         102 :     Word16 wgain_code = 0, gain_code16;
    1500         102 :     *gain_pit_fx = 0;
    1501         102 :     move16();
    1502         102 :     move16();
    1503         102 :     move16();
    1504             : 
    1505             :     /*----------------------------------------------------------------*
    1506             :      * get number of bits for gain quantization
    1507             :      *----------------------------------------------------------------*/
    1508         102 :     nBits = gains_mode[shr( i_subfr, 6 )];
    1509             : 
    1510             :     /*----------------------------------------------------------------*
    1511             :      * find the code pitch (for current subframe)
    1512             :      *----------------------------------------------------------------*/
    1513             : 
    1514             :     /**gain_code = dotp( xn, y2, L_SUBFR )/( dotp( y2, y2, L_SUBFR ) + 0.01f );*/
    1515             :     /* Compute scalar product <y2[],y2[]> */
    1516         102 :     L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
    1517         102 :     exp_den = norm_l( L_tmp );
    1518         102 :     den = extract_h( L_shl( L_tmp, exp_den ) );
    1519         102 :     exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
    1520             : 
    1521             :     /* Compute scalar product <xn[],y2[]> */
    1522         102 :     L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9)  */
    1523         102 :     exp_num = sub( norm_l( L_tmp1 ), 1 );
    1524         102 :     num = extract_h( L_shl( L_tmp1, exp_num ) );
    1525         102 :     exp_num = sub( add( exp_num, 8 ), Q_xn );
    1526             : 
    1527         102 :     tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
    1528         102 :     num = abs_s( num );
    1529             : 
    1530             :     /*----------------------------------------------------------------*
    1531             :      * compute gain = xy/yy
    1532             :      *----------------------------------------------------------------*/
    1533         102 :     g_code_fx = div_s( num, den );
    1534             : 
    1535         102 :     i = sub( exp_num, exp_den );             /* Gain_trans in Q7 */
    1536         102 :     g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */
    1537         102 :     *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i );
    1538         102 :     move32();
    1539             : 
    1540             :     /*----------------------------------------------------------------*
    1541             :      * calculate the predicted gain code
    1542             :      * decode codebook gain
    1543             :      *----------------------------------------------------------------*/
    1544             : 
    1545         102 :     *gain_pit_fx = 0;
    1546         102 :     move16();
    1547             : 
    1548             :     /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
    1549             :      *gain_inov = 1.0f / (float)sqrt( Ecode );*/
    1550             : 
    1551         102 :     L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
    1552         102 :     expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
    1553         102 :     expg2 = expg;
    1554         102 :     move16();
    1555         102 :     L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
    1556         102 :     move32();
    1557         102 :     L_tmp = Isqrt_lc( L_tmp, &expg );
    1558             : 
    1559         102 :     *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
    1560         102 :     move16(); /* gain_inov in Q12 */
    1561             : 
    1562             :     /*Ei = 10 * (float)log10( Ecode );*/
    1563         102 :     e_tmp = norm_l( L_tmp1 );
    1564         102 :     f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
    1565         102 :     e_tmp = sub( expg2, add( 1, e_tmp ) );
    1566         102 :     L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
    1567         102 :     Ei_fx = round_fx( L_shl( L_tmp1, 11 ) );             /* Q8 */
    1568             :     /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
    1569         102 :     gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
    1570             :     /*-----------------------------------------------------------------*
    1571             :      * gcode0 = pow(10.0, gcode0/20)
    1572             :      * = pow(2, 3.321928*gcode0/20)
    1573             :      * = pow(2, 0.166096*gcode0)
    1574             :      *-----------------------------------------------------------------*/
    1575         102 :     L_tmp = L_mult( gcode0_fx, 21771 );        /* *0.166096 in Q17 -> Q26 */
    1576         102 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16 */
    1577         102 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1578         102 :     gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1579         102 :     exp_gcode0 = sub( exp_gcode0, 14 );
    1580         102 :     IF( GT_16( nBits, 3 ) )
    1581             :     {
    1582             :         /*g_code = *gain_code / gcode0;*/
    1583          12 :         IF( gcode0_fx != 0 )
    1584             :         {
    1585          12 :             tmp16 = div_s( 16384, gcode0_fx );                     /*Q15*/
    1586          12 :             L_tmp = Mult_32_16( *gain_code_fx, tmp16 );            /*Q16*/
    1587          12 :             *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
    1588          12 :             move32();
    1589             :         }
    1590             :         ELSE
    1591             :         {
    1592           0 :             *gain_code_fx = MAX_32;
    1593           0 :             move32();
    1594             :         }
    1595             : 
    1596             :         /*index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits );*/
    1597          12 :         index = gain_quant_fx( gain_code_fx, &gain_code16, LG10_G_CODE_MIN_TC_Q14, LG10_G_CODE_MAX_TC_Q13, nBits, &expg );
    1598             : 
    1599             :         /**gain_code = g_code * gcode0;*/
    1600          12 :         L_tmp = L_mult( gain_code16, gcode0_fx );                           /*Q0*Q0 -> Q1*/
    1601          12 :         *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
    1602          12 :         move32();
    1603             : 
    1604          12 :         push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1605             :     }
    1606             :     ELSE
    1607             :     {
    1608          90 :         index = N_GAIN_CODE_TC - 1;
    1609          90 :         move16();
    1610         386 :         FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
    1611             :         {
    1612         383 :             L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
    1613         383 :             L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) );                /*    Q14 -> Q16 */
    1614             : 
    1615         383 :             IF( LT_32( *gain_code_fx, L_tmp ) )
    1616             :             {
    1617          87 :                 index = i;
    1618          87 :                 move16();
    1619          87 :                 BREAK;
    1620             :             }
    1621             :         }
    1622             :         /*----------------------------------------------------------------*
    1623             :          * 3-bit -> 2-bit encoding
    1624             :          *----------------------------------------------------------------*/
    1625          90 :         IF( EQ_16( nBits, 2 ) )
    1626             :         {
    1627             :             /* 2-bit -> 3-bit decoding */
    1628           0 :             index = shr( index, 1 );
    1629           0 :             wgain_code = tbl_gain_code_tc_fx[shl( index, 1 )];
    1630           0 :             move16();
    1631             :             /**gain_code *= gcode0;*/
    1632           0 :             L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
    1633           0 :             *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) );
    1634           0 :             move32(); /* Q14 -> Q16 */
    1635           0 :             push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1636             :         }
    1637             :         ELSE /* nBits == 3 */
    1638             :         {
    1639          90 :             wgain_code = tbl_gain_code_tc_fx[index];
    1640          90 :             move16();
    1641             :             /**gain_code *= gcode0;*/
    1642          90 :             L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
    1643          90 :             *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
    1644          90 :             move32(); /* Q14 -> Q16 */
    1645          90 :             push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1646             :         }
    1647             :     }
    1648             : 
    1649             :     /*-----------------------------------------------------------------*
    1650             :      * decode normalized codebook gain
    1651             :      *-----------------------------------------------------------------*/
    1652             :     /**norm_gain_code = *gain_code / *gain_inov;*/
    1653         102 :     expg = sub( norm_s( *gain_inov_fx ), 1 );
    1654         102 :     expg = s_max( expg, 0 );
    1655             : 
    1656         102 :     tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
    1657         102 :     *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q16
    1658         102 :     move32();
    1659         102 :     return;
    1660             : }
    1661             : 
    1662       20048 : void gain_enc_tc_ivas_fx(
    1663             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                         */
    1664             :     const Word16 gains_mode[], /* i  : gain bits                                                                                        Q0*/
    1665             :     const Word16 i_subfr,      /* i  : subframe index                                                                           Q0*/
    1666             :     const Word16 xn_fx[],      /* i  : target vector                                                                            Q_xn*/
    1667             :     const Word16 y2_fx[],      /* i  : zero-memory filtered algebraic codebook excitation       Q_xn*/
    1668             :     const Word16 code_fx[],    /* i  : algebraic excitation                                                                     Q9*/
    1669             :     const Word16 Es_pred_fx,   /* i  : predicted scaled innovation energy                                       Q8*/
    1670             :     Word16 *gain_pit_fx,       /* o  : Pitch gain / Quantized pitch gain                                        Q14*/
    1671             :     Word32 *gain_code_fx,      /* o  : quantized codebook gain                                                          Q16*/
    1672             :     Word16 *gain_inov_fx,      /* o  : innovation gain                                                                          Q12*/
    1673             :     Word32 *norm_gain_code_fx, /* o  : norm. gain of the codebook excitation                            Q6*/
    1674             :     const Word16 Q_xn          /* i  : xn and y1 scaling                                                                        */
    1675             : )
    1676             : {
    1677       20048 :     Word16 i, index = 0, nBits, num, den, exp_num, exp_den;
    1678             :     Word16 Ei_fx, g_code_fx, gcode0_fx;
    1679             :     Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac, tmp16;
    1680             :     Word32 L_tmp, L_tmp1;
    1681       20048 :     Word16 wgain_code = 0, gain_code16;
    1682       20048 :     *gain_pit_fx = 0;
    1683       20048 :     move16();
    1684       20048 :     move16();
    1685       20048 :     move16();
    1686             : 
    1687             :     /*----------------------------------------------------------------*
    1688             :      * get number of bits for gain quantization
    1689             :      *----------------------------------------------------------------*/
    1690       20048 :     nBits = gains_mode[i_subfr >> 6]; // Q0
    1691       20048 :     move16();
    1692             : 
    1693             :     /*----------------------------------------------------------------*
    1694             :      * find the code pitch (for current subframe)
    1695             :      *----------------------------------------------------------------*/
    1696             : 
    1697             :     /**gain_code = dotp( xn, y2, L_SUBFR )/( dotp( y2, y2, L_SUBFR ) + 0.01f );*/
    1698             :     /* Compute scalar product <y2[],y2[]> */
    1699       20048 :     L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
    1700       20048 :     exp_den = norm_l( L_tmp );
    1701       20048 :     den = extract_h( L_shl( L_tmp, exp_den ) );
    1702       20048 :     exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
    1703             : 
    1704             :     /* Compute scalar product <xn[],y2[]> */
    1705       20048 :     L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9)  */
    1706       20048 :     exp_num = sub( norm_l( L_tmp1 ), 1 );
    1707       20048 :     num = extract_h( L_shl( L_tmp1, exp_num ) );
    1708       20048 :     exp_num = sub( add( exp_num, 8 ), Q_xn );
    1709             : 
    1710       20048 :     tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
    1711       20048 :     num = abs_s( num );
    1712             : 
    1713             :     /*----------------------------------------------------------------*
    1714             :      * compute gain = xy/yy
    1715             :      *----------------------------------------------------------------*/
    1716       20048 :     g_code_fx = div_s( num, den );
    1717             : 
    1718       20048 :     i = sub( exp_num, exp_den );                              /* Gain_trans in Q7 */
    1719       20048 :     g_code_fx = i_mult2( g_code_fx, tmp16 );                  /* apply sign */
    1720       20048 :     *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i ); /* Q16 */
    1721       20048 :     move32();
    1722             : 
    1723             :     /*----------------------------------------------------------------*
    1724             :      * calculate the predicted gain code
    1725             :      * decode codebook gain
    1726             :      *----------------------------------------------------------------*/
    1727             : 
    1728       20048 :     *gain_pit_fx = 0;
    1729       20048 :     move16();
    1730             : 
    1731             :     /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
    1732             :      *gain_inov = 1.0f / (float)sqrt( Ecode );*/
    1733             : 
    1734       20048 :     L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
    1735       20048 :     expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
    1736       20048 :     expg2 = expg;
    1737       20048 :     move16();
    1738       20048 :     L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
    1739       20048 :     move32();
    1740       20048 :     L_tmp = Isqrt_lc( L_tmp, &expg );
    1741             : 
    1742       20048 :     *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
    1743       20048 :     move16(); /* gain_inov in Q12 */
    1744             : 
    1745             :     /*Ei = 10 * (float)log10( Ecode );*/
    1746       20048 :     e_tmp = norm_l( L_tmp1 );
    1747       20048 :     f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
    1748       20048 :     e_tmp = sub( expg2, add( 1, e_tmp ) );
    1749       20048 :     L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
    1750       20048 :     Ei_fx = round_fx( L_shl( L_tmp1, 11 ) );             /* Q8 */
    1751             :     /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
    1752       20048 :     gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
    1753             :     /*-----------------------------------------------------------------*
    1754             :      * gcode0 = pow(10.0, gcode0/20)
    1755             :      * = pow(2, 3.321928*gcode0/20)
    1756             :      * = pow(2, 0.166096*gcode0)
    1757             :      *-----------------------------------------------------------------*/
    1758       20048 :     L_tmp = L_mult( gcode0_fx, 21771 );        /* *0.166096 in Q17 -> Q26 */
    1759       20048 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16 */
    1760       20048 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1761       20048 :     gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1762       20048 :     exp_gcode0 = sub( exp_gcode0, 14 );
    1763       20048 :     IF( GT_16( nBits, 3 ) )
    1764             :     {
    1765             :         /*g_code = *gain_code / gcode0;*/
    1766        1415 :         IF( gcode0_fx != 0 )
    1767             :         {
    1768        1415 :             tmp16 = div_s( 16384, gcode0_fx );                     /*Q15*/
    1769        1415 :             L_tmp = Mult_32_16( *gain_code_fx, tmp16 );            /*Q16*/
    1770        1415 :             *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
    1771        1415 :             move32();
    1772             :         }
    1773             :         ELSE
    1774             :         {
    1775           0 :             *gain_code_fx = MAX_32;
    1776           0 :             move32();
    1777             :         }
    1778             : 
    1779             :         /*index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits );*/
    1780        1415 :         index = gain_quant_fx( gain_code_fx, &gain_code16, LG10_G_CODE_MIN_TC_Q14, LG10_G_CODE_MAX_TC_Q13, nBits, &expg );
    1781             : 
    1782             :         /**gain_code = g_code * gcode0;*/
    1783        1415 :         L_tmp = L_mult( gain_code16, gcode0_fx );                           /*Q0*Q0 -> Q1*/
    1784        1415 :         *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
    1785        1415 :         move32();
    1786             : 
    1787        1415 :         push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1788             :     }
    1789             :     ELSE
    1790             :     {
    1791       18633 :         index = N_GAIN_CODE_TC - 1;
    1792       18633 :         move16();
    1793       63084 :         FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
    1794             :         {
    1795       62209 :             L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
    1796       62209 :             L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) );                /*    Q14 -> Q16 */
    1797             : 
    1798       62209 :             IF( LT_32( *gain_code_fx, L_tmp ) )
    1799             :             {
    1800       17758 :                 index = i;
    1801       17758 :                 move16();
    1802       17758 :                 BREAK;
    1803             :             }
    1804             :         }
    1805             :         /*----------------------------------------------------------------*
    1806             :          * 3-bit -> 2-bit encoding
    1807             :          *----------------------------------------------------------------*/
    1808       18633 :         IF( EQ_16( nBits, 2 ) )
    1809             :         {
    1810             :             /* 2-bit -> 3-bit decoding */
    1811           0 :             index = shr( index, 1 );
    1812           0 :             wgain_code = tbl_gain_code_tc_fx[index * 2]; // Q13
    1813           0 :             move16();
    1814             :             /**gain_code *= gcode0;*/
    1815           0 :             L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
    1816           0 :             *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) );
    1817           0 :             move32(); /* Q14 -> Q16 */
    1818           0 :             push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1819             :         }
    1820             :         ELSE /* nBits == 3 */
    1821             :         {
    1822       18633 :             wgain_code = tbl_gain_code_tc_fx[index]; // Q13
    1823       18633 :             move16();
    1824             :             /**gain_code *= gcode0;*/
    1825       18633 :             L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
    1826       18633 :             *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
    1827       18633 :             move32(); /* Q14 -> Q16 */
    1828       18633 :             push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1829             :         }
    1830             :     }
    1831             : 
    1832             :     /*-----------------------------------------------------------------*
    1833             :      * decode normalized codebook gain
    1834             :      *-----------------------------------------------------------------*/
    1835             :     /**norm_gain_code = *gain_code / *gain_inov;*/
    1836       20048 :     expg = sub( norm_s( *gain_inov_fx ), 1 );
    1837       20048 :     expg = s_max( expg, 0 );
    1838             : 
    1839       20048 :     tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
    1840       20048 :     *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q6
    1841       20048 :     move32();
    1842       20048 :     return;
    1843             : }
    1844             : /*-----------------------------------------------------------------*
    1845             :  * Find_Opt_gainQ_fx()
    1846             :  *
    1847             :  * Find the best quantizer
    1848             :  *-----------------------------------------------------------------*/
    1849      538361 : static Word16 Find_Opt_gainQ_fx(
    1850             :     Word16 *coeff, /* exp(exp_coeff) */
    1851             :     Word16 *exp_coeff,
    1852             :     Word16 *gain_pit,  /* Q14 */
    1853             :     Word32 *gain_code, /* Q16 */
    1854             :     Word16 gcode0,     /* exp(exp_gcode0) */
    1855             :     Word16 exp_gcode0,
    1856             :     const Word16 *cdbk, /* i  : Codebook used   Q14*/
    1857             :     const Word16 size   /* i  : size of Codebook used   Q0*/
    1858             : )
    1859             : {
    1860             :     Word16 index, i, j;
    1861             :     const Word16 *p;
    1862             :     Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
    1863             :     Word32 dist_min;
    1864             :     Word16 coeff_lo[5];
    1865             :     Word16 exp_max[5];
    1866             :     Word16 exp_code, e_max;
    1867             :     Word32 L_tmp, L_tmp1;
    1868             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1869      538361 :     Flag Overflow = 0;
    1870      538361 :     move32();
    1871             : #endif
    1872             : 
    1873             : 
    1874             :     /*----------------------------------------------------------------*
    1875             :      * Find the best quantizer
    1876             :      * ~~~~~~~~~~~~~~~~~~~~~~~
    1877             :      * Before doing the computation we need to align exponents of coeff[]
    1878             :      * to be sure to have the maximum precision.
    1879             :      *
    1880             :      * In the table the pitch gains are in Q14, the code gains are in Q9 and
    1881             :      * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
    1882             :      * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
    1883             :      * we divide by 2^15.
    1884             :      * Considering all the scaling above we have:
    1885             :      *
    1886             :      *   exp_code = exp_gcode0-9+15 = exp_gcode0+6
    1887             :      *
    1888             :      *   g_pitch*g_pitch  = -14-14+15
    1889             :      *   g_pitch          = -14
    1890             :      *   g_code*g_code    = (2*exp_code)+15
    1891             :      *   g_code           = exp_code
    1892             :      *   g_pitch*g_code   = -14 + exp_code +15
    1893             :      *
    1894             :      *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13
    1895             :      *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14
    1896             :      *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
    1897             :      *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
    1898             :      *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
    1899             :      *----------------------------------------------------------------*/
    1900             : 
    1901      538361 :     exp_code = add( exp_gcode0, 6 );
    1902             : 
    1903      538361 :     exp_max[0] = sub( exp_coeff[0], 13 );
    1904      538361 :     move16();
    1905      538361 :     exp_max[1] = sub( exp_coeff[1], 14 );
    1906      538361 :     move16();
    1907      538361 :     exp_max[2] = add( exp_coeff[2], add( 15, shl( exp_code, 1 ) ) );
    1908      538361 :     move16();
    1909      538361 :     exp_max[3] = add( exp_coeff[3], exp_code );
    1910      538361 :     move16();
    1911      538361 :     exp_max[4] = add( exp_coeff[4], add( 1, exp_code ) );
    1912      538361 :     move16();
    1913             : 
    1914             :     /* Find maximum exponant */
    1915      538361 :     e_max = exp_max[0];
    1916      538361 :     move16();
    1917     2691805 :     FOR( i = 1; i < 5; i++ )
    1918             :     {
    1919     2153444 :         e_max = s_max( exp_max[i], e_max );
    1920             :     }
    1921             : 
    1922             :     /* align coeff[] and save in special 32 bit double precision */
    1923     3230166 :     FOR( i = 0; i < 5; i++ )
    1924             :     {
    1925     2691805 :         j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
    1926     2691805 :         L_tmp = L_deposit_h( coeff[i] );
    1927     2691805 :         L_tmp = L_shr( L_tmp, j );
    1928     2691805 :         L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
    1929     2691805 :         coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
    1930     2691805 :         move16();
    1931             :     }
    1932             : 
    1933             :     /* searching of codebook */
    1934      538361 :     p = cdbk; // Q14
    1935      538361 :     move16();
    1936      538361 :     dist_min = L_deposit_h( MAX_16 );
    1937      538361 :     index = 0;
    1938      538361 :     move16();
    1939    35334987 :     FOR( i = 0; i < size; i++ )
    1940             :     {
    1941    34796626 :         g_pitch = *p++;
    1942    34796626 :         move16();
    1943    34796626 :         g_code = *p++;
    1944    34796626 :         move16();
    1945             : 
    1946    34796626 :         g_code = mult_r( g_code, gcode0 );     // exp_gcode - 1
    1947    34796626 :         g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
    1948    34796626 :         g_pit_cod = mult_r( g_code, g_pitch );
    1949    34796626 :         L_tmp = L_mult( g_code, g_code );
    1950    34796626 :         g2_code_lo = L_Extract_lc( L_tmp, &g2_code );
    1951             : 
    1952    34796626 :         L_tmp = L_mult( coeff[2], g2_code_lo );
    1953    34796626 :         L_tmp = L_shr( L_tmp, 3 );
    1954    34796626 :         L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
    1955    34796626 :         L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
    1956    34796626 :         L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
    1957    34796626 :         L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
    1958    34796626 :         L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
    1959    34796626 :         L_tmp = L_shr( L_tmp, 12 );
    1960    34796626 :         L_tmp = L_mac( L_tmp, coeff[0], g2_pitch );  /* 15 - coeff_exp + 13 - 1 */
    1961    34796626 :         L_tmp = L_mac( L_tmp, coeff[1], g_pitch );   /* 15 - coeff_exp + 13 - 1 */
    1962    34796626 :         L_tmp = L_mac( L_tmp, coeff[2], g2_code );   /* 15 - coeff_exp + 13 - 1 */
    1963    34796626 :         L_tmp = L_mac( L_tmp, coeff[3], g_code );    /* 15 - coeff_exp + 13 - 1 */
    1964    34796626 :         L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
    1965             : 
    1966    34796626 :         L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
    1967    34796626 :         if ( L_tmp1 < 0 )
    1968             :         {
    1969     6833843 :             index = i;
    1970     6833843 :             move16();
    1971             :         }
    1972    34796626 :         dist_min = L_min( L_tmp, dist_min );
    1973             :     }
    1974             : 
    1975      538361 :     p = &cdbk[add( index, index )]; // Q14
    1976      538361 :     move16();
    1977             : 
    1978      538361 :     *gain_pit = *p++; /* selected pitch gain in Q14 */
    1979      538361 :     move16();
    1980      538361 :     g_code = *p++; /* selected  code gain in Q9 */
    1981      538361 :     move16();
    1982             : 
    1983      538361 :     L_tmp = L_mult( g_code, gcode0 );                 /* Q9*Q0 -> Q10 */
    1984      538361 :     L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16 */
    1985      538361 :     *gain_code = L_tmp;                               /* gain of code in Q16 */
    1986      538361 :     move16();
    1987      538361 :     return index;
    1988             : }
    1989             : /*---------------------------------------------------------------------*
    1990             :  * gain_enc_lbr()
    1991             :  *
    1992             :  * Quantization of pitch and codebook gains without prediction (memory-less)
    1993             :  * in ACELP at 6.6 and 7.5 kbps
    1994             :  * - the gain codebooks and gain estimation constants are different in each subframe
    1995             :  * - the estimated gain, gcode0, is first determined based on
    1996             :  *   classification and/or previous quantized gains (from previous subframes in the current frame)
    1997             :  * - a correction factor gamma = g_code / gcode0 is then vector quantized
    1998             :  *   along with gain_pit
    1999             :  * - the mean-squared error criterion is used for codebook search
    2000             :  *---------------------------------------------------------------------*/
    2001             : 
    2002           0 : void gain_enc_lbr_fx(
    2003             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                  */
    2004             :     const Word16 gains_mode[], /* i  : gain bits                                                       Q0*/
    2005             :     const Word16 coder_type,   /* i  : coding type                                                     Q0*/
    2006             :     const Word16 i_subfr,      /* i  : subframe index                                                  Q0*/
    2007             :     const Word16 *xn,          /* i  : target vector                                                   Q_xn*/
    2008             :     const Word16 *y1,          /* i  : zero-memory filtered adaptive excitation                        Q_xn*/
    2009             :     const Word16 Q_xn,         /* i  : xn and y1 format                                                  */
    2010             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation              Q9*/
    2011             :     const Word16 *code,        /* i  : algebraic excitation                                            Q9*/
    2012             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                            Q14*/
    2013             :     Word32 *gain_code,         /* o  : quantized codebook gain                                         Q16*/
    2014             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                 Q12*/
    2015             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                           Q16*/
    2016             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> mant/exp*/
    2017             :     Word32 gc_mem[],           /* i/o: gain_code from previous subframes                               Q16*/
    2018             :     Word16 gp_mem[],           /* i/o: gain_pitch from previous subframes                              Q14*/
    2019             :     const Word16 clip_gain,    /* i  : gain pitch clipping flag (1 = clipping)                                             Q0*/
    2020             :     const Word16 L_subfr       /* i  : subframe length                                                                                             Q0*/
    2021             : )
    2022             : {
    2023             : 
    2024           0 :     Word16 index = 0, size, nBits, n_pred, ctype;
    2025           0 :     const Word16 *b, *cdbk = 0;
    2026             :     Word16 gcode0, aux[10];
    2027             :     Word16 coeff[5], exp_coeff[5];
    2028             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf;
    2029             :     Word32 L_tmp, L_tmp1, L_inov;
    2030           0 :     move16();
    2031           0 :     move16();
    2032             : 
    2033           0 :     L_subfr_sf = 6;
    2034           0 :     move16();
    2035           0 :     if ( GT_16( L_subfr, L_SUBFR ) )
    2036             :     {
    2037           0 :         L_subfr_sf = 7;
    2038           0 :         move16();
    2039             :     }
    2040             :     /*-----------------------------------------------------------------*
    2041             :      * calculate the rest of the correlation coefficients
    2042             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>, c5* = <xn,xn>
    2043             :      * c5* - not necessary to calculate
    2044             :      *-----------------------------------------------------------------*/
    2045             : 
    2046           0 :     coeff[0] = g_corr[0];
    2047           0 :     move16();
    2048           0 :     exp_coeff[0] = g_corr[1];
    2049           0 :     move16();
    2050           0 :     coeff[1] = negate( g_corr[2] );
    2051           0 :     move16(); /* coeff[1] = -2 xn yy1 */
    2052           0 :     exp_coeff[1] = add( g_corr[3], 1 );
    2053           0 :     move16();
    2054             : 
    2055             :     /* Compute scalar product <y2[],y2[]> */
    2056           0 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) );
    2057           0 :     move16();
    2058           0 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
    2059           0 :     move16();
    2060             : 
    2061             :     /* Compute scalar product -2*<xn[],y2[]> */
    2062             : 
    2063           0 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) );
    2064           0 :     move16();
    2065           0 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
    2066           0 :     move16();
    2067             : 
    2068             :     /* Compute scalar product 2*<y1[],y2[]> */
    2069             : 
    2070           0 :     coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) );
    2071           0 :     move16();
    2072           0 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
    2073           0 :     move16();
    2074             : 
    2075             :     /*g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F;*/
    2076             : 
    2077             :     /*Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
    2078             :      *gain_inov = 1.0f / (float)sqrt(Ecode);*/
    2079           0 :     L_tmp = Dot_product12( code, code, L_subfr, &exp_code );
    2080           0 :     L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */
    2081           0 :     move32();
    2082             :     /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */
    2083             :     /* output gain_inov*/
    2084           0 :     exp_inov = sub( exp_code, add( 18, L_subfr_sf ) );
    2085           0 :     L_inov = Isqrt_lc( L_inov, &exp_inov );
    2086           0 :     *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
    2087           0 :     move16();
    2088             : 
    2089             : 
    2090             :     /*-----------------------------------------------------------------*
    2091             :      * select the codebook, size and number of bits
    2092             :      * set the gains searching range
    2093             :      *-----------------------------------------------------------------*/
    2094             : 
    2095           0 :     nBits = gains_mode[shr( i_subfr, L_subfr_sf )];
    2096           0 :     move16();
    2097           0 :     size = shl( 1, nBits );
    2098             : 
    2099           0 :     ctype = shl( sub( coder_type, 1 ), 1 );
    2100             : 
    2101             :     /*-----------------------------------------------------------------*
    2102             :      * calculate prediction of gcode
    2103             :      * search for the best codeword
    2104             :      *-----------------------------------------------------------------*/
    2105           0 :     test();
    2106           0 :     IF( i_subfr == 0 )
    2107             :     {
    2108           0 :         b = b_1sfr_fx; // Q12
    2109           0 :         move16();
    2110           0 :         n_pred = 2;
    2111           0 :         move16();
    2112             : 
    2113           0 :         SWITCH( nBits )
    2114             :         {
    2115           0 :             case 8:
    2116             :             {
    2117           0 :                 cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */
    2118           0 :                 if ( EQ_16( clip_gain, 1 ) )
    2119             :                 {
    2120           0 :                     size = sub( size, 60 );
    2121             :                 }
    2122           0 :                 BREAK;
    2123             :             }
    2124           0 :             case 7:
    2125             :             {
    2126           0 :                 cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */
    2127           0 :                 if ( EQ_16( clip_gain, 1 ) )
    2128             :                 {
    2129           0 :                     size = sub( size, 27 );
    2130             :                 }
    2131           0 :                 BREAK;
    2132             :             }
    2133           0 :             case 6:
    2134             :             {
    2135           0 :                 cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */
    2136           0 :                 if ( EQ_16( clip_gain, 1 ) )
    2137             :                 {
    2138           0 :                     size = sub( size, 10 );
    2139             :                 }
    2140           0 :                 BREAK;
    2141             :             }
    2142             :         }
    2143             : 
    2144             :         /* calculate predicted gain */
    2145           0 :         aux[0] = 4096; /* 1 in Q12 */
    2146           0 :         move16();
    2147           0 :         aux[1] = shl( ctype, 12 );
    2148           0 :         move16();
    2149             : 
    2150             :         /*     gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
    2151             :                gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
    2152             :                gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
    2153             : 
    2154           0 :         exp_code = sub( exp_code, 18 + 6 + 1 );
    2155           0 :         exp = norm_l( L_tmp );
    2156           0 :         frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
    2157           0 :         exp = sub( exp_code, exp );
    2158           0 :         L_tmp1 = Mpy_32_16( exp, frac, 24660 ); /* Q14 */ /* 10*log10(2) in Q13*/
    2159             : 
    2160           0 :         L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
    2161           0 :         L_tmp = Mult_32_16( L_tmp, 320 );      /*Q14, 20 in Q4*/
    2162           0 :         L_tmp = L_sub( L_tmp, L_tmp1 );        /*Q14*/
    2163             : 
    2164           0 :         gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
    2165             : 
    2166             :         /*-----------------------------------------------------------------*
    2167             :          * gcode0 = pow(10.0, gcode0/20)
    2168             :          *        = pow(2, 3.321928*gcode0/20)
    2169             :          *        = pow(2, 0.166096*gcode0)
    2170             :          *-----------------------------------------------------------------*/
    2171             : 
    2172           0 :         L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26 */
    2173           0 :         L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16 */
    2174           0 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2175             : 
    2176           0 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2177             :         /* output of Pow2() will be: */
    2178             :         /* 16384 < Pow2() <= 32767 */
    2179           0 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2180           0 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    2181             : 
    2182           0 :         gc_mem[0] = *gain_code;
    2183           0 :         move16(); /*Q16*/
    2184           0 :         gp_mem[0] = *gain_pit;
    2185           0 :         move16(); /*Q14*/
    2186             :     }
    2187           0 :     ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
    2188             :     {
    2189           0 :         b = b_2sfr_fx;
    2190           0 :         move16();
    2191           0 :         n_pred = 4;
    2192           0 :         move16();
    2193             : 
    2194           0 :         switch ( nBits )
    2195             :         {
    2196           0 :             case 7:
    2197             :             {
    2198           0 :                 cdbk = gp_gamma_2sfr_7b_fx; /* Q14/Q9 */
    2199           0 :                 if ( EQ_16( clip_gain, 1 ) )
    2200             :                 {
    2201           0 :                     size = sub( size, 30 );
    2202             :                 }
    2203           0 :                 BREAK;
    2204             :             }
    2205           0 :             case 6:
    2206             :             {
    2207           0 :                 cdbk = gp_gamma_2sfr_6b_fx; /* Q14/Q9 */
    2208           0 :                 if ( EQ_16( clip_gain, 1 ) )
    2209             :                 {
    2210           0 :                     size = sub( size, 12 );
    2211             :                 }
    2212           0 :                 BREAK;
    2213             :             }
    2214             :         }
    2215             : 
    2216             :         /* calculate predicted gain */
    2217           0 :         aux[0] = 4096; /* 1 in Q12 */
    2218           0 :         move16();
    2219           0 :         aux[1] = shl( ctype, 12 );
    2220           0 :         move16();
    2221             : 
    2222             :         /*aux[2] = (float)log10(gc_mem[0]);
    2223             :                  = log2(gc_mem[0])*log10(2);*/
    2224           0 :         exp = norm_l( gc_mem[0] );
    2225           0 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    2226           0 :         exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_1sfr_fx)=16*/
    2227           0 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );
    2228           0 :         move16();                                 /* Q16 */
    2229           0 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2230           0 :         move16();
    2231             : 
    2232           0 :         aux[3] = shr( gp_mem[0], 2 );
    2233           0 :         move16(); /*Q12*/
    2234             : 
    2235             :         /*-----------------------------------------------------------------*
    2236             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    2237             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    2238             :          *-----------------------------------------------------------------*/
    2239           0 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    2240           0 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    2241           0 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    2242           0 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2243             : 
    2244           0 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2245             :         /* output of Pow2() will be: */
    2246             :         /* 16384 < Pow2() <= 32767 */
    2247           0 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2248             : 
    2249           0 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    2250           0 :         gc_mem[1] = *gain_code;                                                                             // Q16
    2251           0 :         move32();
    2252           0 :         gp_mem[1] = *gain_pit; // Q14
    2253           0 :         move16();
    2254             :     }
    2255           0 :     ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
    2256             :     {
    2257           0 :         b = b_3sfr_fx; // Q12
    2258           0 :         move16();
    2259           0 :         n_pred = 6;
    2260           0 :         move16();
    2261           0 :         IF( EQ_16( nBits, 7 ) )
    2262             :         {
    2263           0 :             cdbk = gp_gamma_3sfr_7b_fx;
    2264           0 :             if ( clip_gain == 1 )
    2265             :             {
    2266           0 :                 size -= 28;
    2267             :             }
    2268             :         }
    2269             :         ELSE
    2270             :         {
    2271           0 :             cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */
    2272           0 :             if ( EQ_16( clip_gain, 1 ) )
    2273             :             {
    2274           0 :                 size = sub( size, 11 );
    2275             :             }
    2276             :         }
    2277             :         /* calculate predicted gain */
    2278           0 :         aux[0] = 4096; /* 1 in Q12 */
    2279           0 :         move16();
    2280           0 :         aux[1] = shl( ctype, 12 );
    2281           0 :         move16();
    2282             : 
    2283             :         /*aux[2] = (float)log10(gc_mem[0]);
    2284             :                  = log2(gc_mem[0])*log10(2);*/
    2285           0 :         exp = norm_l( gc_mem[0] );
    2286           0 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    2287           0 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[0])=16*/
    2288           0 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2289           0 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2290           0 :         move16();
    2291             : 
    2292             :         /*aux[3] = (float)log10(gc_mem[1]);
    2293             :                  =  log2(gc_mem[1])*log10(2);*/
    2294           0 :         exp = norm_l( gc_mem[1] );
    2295           0 :         frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
    2296           0 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[1])=16*/
    2297           0 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2298           0 :         aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2299           0 :         move16();
    2300             : 
    2301           0 :         aux[4] = shr( gp_mem[0], 2 );
    2302           0 :         move16(); /*Q12*/
    2303           0 :         aux[5] = shr( gp_mem[1], 2 );
    2304           0 :         move16(); /*Q12*/
    2305             : 
    2306             :         /*-----------------------------------------------------------------*
    2307             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    2308             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    2309             :          *-----------------------------------------------------------------*/
    2310           0 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    2311           0 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    2312           0 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    2313           0 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2314             : 
    2315           0 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2316             :         /* output of Pow2() will be: */
    2317             :         /* 16384 < Pow2() <= 32767 */
    2318           0 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2319             : 
    2320             :         /*----------------------------------------------------------------*
    2321             :          * Find the best quantizer
    2322             :          * ~~~~~~~~~~~~~~~~~~~~~~~
    2323             :          * Before doing the computation we need to align exponents of coeff[]
    2324             :          * to be sure to have the maximum precision.
    2325             :          *
    2326             :          * In the table the pitch gains are in Q14, the code gains are in Q9 and
    2327             :          * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
    2328             :          * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
    2329             :          * we divide by 2^15.
    2330             :          * Considering all the scaling above we have:
    2331             :          *
    2332             :          *   exp_code = exp_gcode0-9+15 = exp_gcode0+6
    2333             :          *
    2334             :          *   g_pitch*g_pitch  = -14-14+15
    2335             :          *   g_pitch          = -14
    2336             :          *   g_code*g_code    = (2*exp_code)+15
    2337             :          *   g_code           = exp_code
    2338             :          *   g_pitch*g_code   = -14 + exp_code +15
    2339             :          *
    2340             :          *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13
    2341             :          *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14
    2342             :          *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
    2343             :          *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
    2344             :          *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
    2345             :          *----------------------------------------------------------------*/
    2346             : 
    2347           0 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
    2348             : 
    2349           0 :         gc_mem[2] = *gain_code; // Q16
    2350           0 :         move32();
    2351           0 :         gp_mem[2] = *gain_pit; // Q14
    2352           0 :         move16();
    2353             :     }
    2354           0 :     ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
    2355             :     {
    2356           0 :         b = b_4sfr_fx; // Q12
    2357           0 :         move16();
    2358           0 :         n_pred = 8;
    2359           0 :         move16();
    2360           0 :         IF( EQ_16( nBits, 7 ) )
    2361             :         {
    2362           0 :             cdbk = gp_gamma_4sfr_7b_fx;
    2363           0 :             if ( clip_gain == 1 )
    2364             :             {
    2365           0 :                 size -= 25;
    2366             :             }
    2367             :         }
    2368             :         ELSE
    2369             :         {
    2370           0 :             cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */
    2371           0 :             if ( EQ_16( clip_gain, 1 ) )
    2372             :             {
    2373           0 :                 size = sub( size, 11 );
    2374             :             }
    2375             :         }
    2376             :         /* calculate predicted gain */
    2377           0 :         aux[0] = 4096; /* 1 in Q12 */
    2378           0 :         move16();
    2379           0 :         aux[1] = shl( ctype, 12 );
    2380           0 :         move16();
    2381             : 
    2382             :         /*aux[2] = (float)log10(gc_mem[0]);
    2383             :                  = log2(gc_mem[0])*log10(2);*/
    2384           0 :         exp = norm_l( gc_mem[0] );
    2385           0 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    2386           0 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[0])=16*/
    2387           0 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2388           0 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2389           0 :         move16();
    2390             : 
    2391             :         /*aux[3] = (float)log10(gc_mem[1]);
    2392             :                  =  log2(gc_mem[1])*log10(2);*/
    2393           0 :         exp = norm_l( gc_mem[1] );
    2394           0 :         frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
    2395           0 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[1])=16*/
    2396           0 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2397           0 :         aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2398           0 :         move16();
    2399             : 
    2400             : 
    2401             :         /*aux[4] = (float)log10(gc_mem[2]);
    2402             :                  =  log2(gc_mem[2])*log10(2);*/
    2403           0 :         exp = norm_l( gc_mem[2] );
    2404           0 :         frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) );
    2405           0 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[2])=16*/
    2406           0 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2407           0 :         aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2408           0 :         move16();
    2409             : 
    2410           0 :         aux[5] = shr( gp_mem[0], 2 );
    2411           0 :         move16(); /*Q12*/
    2412           0 :         aux[6] = shr( gp_mem[1], 2 );
    2413           0 :         move16(); /*Q12*/
    2414           0 :         aux[7] = shr( gp_mem[2], 2 );
    2415           0 :         move16(); /*Q12*/
    2416             :         /*-----------------------------------------------------------------*
    2417             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    2418             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    2419             :          *-----------------------------------------------------------------*/
    2420           0 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    2421           0 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    2422           0 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    2423           0 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2424             : 
    2425           0 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2426             :         /* output of Pow2() will be: */
    2427             :         /* 16384 < Pow2() <= 32767 */
    2428           0 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2429             : 
    2430           0 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    2431             :     }
    2432             : 
    2433             :     /* *norm_gain_code = *gain_code / *gain_inov; */
    2434           0 :     exp = sub( norm_s( *gain_inov ), 1 );
    2435           0 :     exp = s_max( exp, 0 );
    2436             : 
    2437           0 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
    2438           0 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
    2439           0 :     move32();
    2440             :     {
    2441           0 :         push_indice( hBstr, IND_GAIN, index, nBits );
    2442             :     }
    2443           0 :     return;
    2444             : }
    2445             : 
    2446       17714 : void gain_enc_lbr_ivas_fx(
    2447             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                  */
    2448             :     const Word16 gains_mode[], /* i  : gain bits                                                       Q0*/
    2449             :     const Word16 coder_type,   /* i  : coding type                                                     Q0*/
    2450             :     const Word16 i_subfr,      /* i  : subframe index                                                  Q0*/
    2451             :     const Word16 *xn,          /* i  : target vector                                                   Q_xn*/
    2452             :     const Word16 *y1,          /* i  : zero-memory filtered adaptive excitation                        Q_xn*/
    2453             :     const Word16 Q_xn,         /* i  : xn and y1 format                                                  */
    2454             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation              Q9*/
    2455             :     const Word16 *code,        /* i  : algebraic excitation                                            Q9*/
    2456             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                            Q14*/
    2457             :     Word32 *gain_code,         /* o  : quantized codebook gain                                         Q16*/
    2458             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                 Q12*/
    2459             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                           Q16*/
    2460             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> mant/exp*/
    2461             :     Word32 gc_mem[],           /* i/o: gain_code from previous subframes                                                           Q16*/
    2462             :     Word16 gp_mem[],           /* i/o: gain_pitch from previous subframes                                                          Q14*/
    2463             :     const Word16 clip_gain,    /* i  : gain pitch clipping flag (1 = clipping)                         Q0*/
    2464             :     const Word16 L_subfr       /* i  : subframe length                                                 Q0*/
    2465             : )
    2466             : {
    2467             : 
    2468       17714 :     Word16 index = 0, size, nBits, n_pred, ctype;
    2469       17714 :     const Word16 *b, *cdbk = 0;
    2470             :     Word16 gcode0, aux[10];
    2471             :     Word16 coeff[5], exp_coeff[5];
    2472             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf;
    2473             :     Word32 L_tmp, L_tmp1, L_inov;
    2474       17714 :     move16();
    2475             : 
    2476       17714 :     L_subfr_sf = 6;
    2477       17714 :     move16();
    2478       17714 :     if ( GT_16( L_subfr, L_SUBFR ) )
    2479             :     {
    2480        4218 :         L_subfr_sf = 7;
    2481        4218 :         move16();
    2482             :     }
    2483             :     /*-----------------------------------------------------------------*
    2484             :      * calculate the rest of the correlation coefficients
    2485             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>, c5* = <xn,xn>
    2486             :      * c5* - not necessary to calculate
    2487             :      *-----------------------------------------------------------------*/
    2488             : 
    2489       17714 :     coeff[0] = g_corr[0];
    2490       17714 :     move16();
    2491       17714 :     exp_coeff[0] = g_corr[1];
    2492       17714 :     move16();
    2493       17714 :     coeff[1] = negate( g_corr[2] );
    2494       17714 :     move16(); /* coeff[1] = -2 xn yy1 */
    2495       17714 :     exp_coeff[1] = add( g_corr[3], 1 );
    2496       17714 :     move16();
    2497             : 
    2498             :     /* Compute scalar product <y2[],y2[]> */
    2499             : #ifdef DEBUG
    2500             :     if ( L_subfr != L_SUBFR )
    2501             :     {
    2502             :         PMT( "Entire function needs review to accommode for L_subfr > L_SUBFR" );
    2503             :     }
    2504             : #endif
    2505       17714 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) );
    2506       17714 :     move16();
    2507       17714 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
    2508       17714 :     move16();
    2509             : 
    2510             :     /* Compute scalar product -2*<xn[],y2[]> */
    2511             : 
    2512       17714 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) );
    2513       17714 :     move16();
    2514       17714 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
    2515       17714 :     move16();
    2516             : 
    2517             :     /* Compute scalar product 2*<y1[],y2[]> */
    2518             : 
    2519       17714 :     coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) );
    2520       17714 :     move16();
    2521       17714 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
    2522       17714 :     move16();
    2523             : 
    2524             :     /*g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F;*/
    2525             : 
    2526             :     /*Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
    2527             :      *gain_inov = 1.0f / (float)sqrt(Ecode);*/
    2528       17714 :     L_tmp = Dot_product12( code, code, L_subfr, &exp_code );
    2529       17714 :     L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */
    2530       17714 :     move32();
    2531             :     /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */
    2532             :     /* output gain_inov*/
    2533       17714 :     exp_inov = sub( exp_code, add( 18, L_subfr_sf ) );
    2534       17714 :     L_inov = Isqrt_lc( L_inov, &exp_inov );
    2535       17714 :     *gain_inov = extract_h( L_shl_sat( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
    2536       17714 :     move16();
    2537             : 
    2538             : 
    2539             :     /*-----------------------------------------------------------------*
    2540             :      * select the codebook, size and number of bits
    2541             :      * set the gains searching range
    2542             :      *-----------------------------------------------------------------*/
    2543             : 
    2544       17714 :     nBits = gains_mode[shr( i_subfr, L_subfr_sf )];
    2545       17714 :     move16();
    2546       17714 :     size = shl( 1, nBits );
    2547             : 
    2548       17714 :     ctype = shl( sub( coder_type, 1 ), 1 );
    2549             : 
    2550             :     /*-----------------------------------------------------------------*
    2551             :      * calculate prediction of gcode
    2552             :      * search for the best codeword
    2553             :      *-----------------------------------------------------------------*/
    2554       17714 :     test();
    2555       17714 :     IF( i_subfr == 0 )
    2556             :     {
    2557        5483 :         b = b_1sfr_fx; // Q12
    2558        5483 :         move16();
    2559        5483 :         n_pred = 2;
    2560        5483 :         move16();
    2561             : 
    2562        5483 :         SWITCH( nBits )
    2563             :         {
    2564        2174 :             case 8:
    2565             :             {
    2566        2174 :                 cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */
    2567        2174 :                 if ( EQ_16( clip_gain, 1 ) )
    2568             :                 {
    2569           0 :                     size = sub( size, 60 );
    2570             :                 }
    2571        2174 :                 BREAK;
    2572             :             }
    2573         442 :             case 7:
    2574             :             {
    2575         442 :                 cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */
    2576         442 :                 if ( EQ_16( clip_gain, 1 ) )
    2577             :                 {
    2578           0 :                     size = sub( size, 27 );
    2579             :                 }
    2580         442 :                 BREAK;
    2581             :             }
    2582        2867 :             case 6:
    2583             :             {
    2584        2867 :                 cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */
    2585        2867 :                 if ( EQ_16( clip_gain, 1 ) )
    2586             :                 {
    2587           0 :                     size = sub( size, 10 );
    2588             :                 }
    2589        2867 :                 BREAK;
    2590             :             }
    2591             :         }
    2592             : 
    2593             :         /* calculate predicted gain */
    2594        5483 :         aux[0] = 4096; /* 1 in Q12 */
    2595        5483 :         move16();
    2596        5483 :         aux[1] = shl( ctype, 12 );
    2597        5483 :         move16();
    2598             : 
    2599             :         /*     gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
    2600             :         gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
    2601             :         gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
    2602             : 
    2603        5483 :         exp_code = sub( exp_code, 18 + 6 + 1 );
    2604        5483 :         exp = norm_l( L_tmp );
    2605        5483 :         frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
    2606        5483 :         exp = sub( exp_code, exp );
    2607        5483 :         L_tmp1 = Mpy_32_16( exp, frac, 24660 ); /* Q14 */ /* 10*log10(2) in Q13*/
    2608             : 
    2609        5483 :         L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
    2610        5483 :         L_tmp = Mult_32_16( L_tmp, 320 );      /*Q14, 20 in Q4*/
    2611        5483 :         L_tmp = L_sub( L_tmp, L_tmp1 );        /*Q14*/
    2612             : 
    2613        5483 :         gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
    2614             : 
    2615             :         /*-----------------------------------------------------------------*
    2616             :          * gcode0 = pow(10.0, gcode0/20)
    2617             :          *        = pow(2, 3.321928*gcode0/20)
    2618             :          *        = pow(2, 0.166096*gcode0)
    2619             :          *-----------------------------------------------------------------*/
    2620             : 
    2621        5483 :         L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26 */
    2622        5483 :         L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16 */
    2623        5483 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2624             : 
    2625        5483 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2626             :                                                 /* output of Pow2() will be: */
    2627             :                                                 /* 16384 < Pow2() <= 32767 */
    2628        5483 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2629        5483 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
    2630             : 
    2631        5483 :         gc_mem[0] = *gain_code;
    2632        5483 :         move16(); /*Q16*/
    2633        5483 :         gp_mem[0] = *gain_pit;
    2634        5483 :         move16(); /*Q14*/
    2635             :     }
    2636       12231 :     ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
    2637             :     {
    2638        5483 :         b = b_2sfr_fx; // Q12
    2639        5483 :         move16();
    2640        5483 :         n_pred = 4;
    2641        5483 :         move16();
    2642             : 
    2643        5483 :         switch ( nBits )
    2644             :         {
    2645        2172 :             case 7:
    2646             :             {
    2647        2172 :                 cdbk = gp_gamma_2sfr_7b_fx; /* Q14 / Q9 */
    2648        2172 :                 if ( EQ_16( clip_gain, 1 ) )
    2649             :                 {
    2650           0 :                     size = sub( size, 30 );
    2651             :                 }
    2652        2172 :                 BREAK;
    2653             :             }
    2654        3311 :             case 6:
    2655             :             {
    2656        3311 :                 cdbk = gp_gamma_2sfr_6b_fx; /* Q14 / Q9 */
    2657        3311 :                 if ( EQ_16( clip_gain, 1 ) )
    2658             :                 {
    2659           0 :                     size = sub( size, 12 );
    2660             :                 }
    2661        3311 :                 BREAK;
    2662             :             }
    2663             :         }
    2664             : 
    2665             :         /* calculate predicted gain */
    2666        5483 :         aux[0] = 4096; /* 1 in Q12 */
    2667        5483 :         move16();
    2668        5483 :         aux[1] = shl( ctype, 12 );
    2669        5483 :         move16();
    2670             : 
    2671             :         /*aux[2] = (float)log10(gc_mem[0]);
    2672             :         = log2(gc_mem[0])*log10(2);*/
    2673        5483 :         exp = norm_l( gc_mem[0] );
    2674        5483 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    2675        5483 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_1sfr_fx)=16*/
    2676        5483 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2677        5483 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2678        5483 :         move16();
    2679             : 
    2680        5483 :         aux[3] = shr( gp_mem[0], 2 );
    2681        5483 :         move16(); /*Q12*/
    2682             : 
    2683             :         /*-----------------------------------------------------------------*
    2684             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    2685             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    2686             :          *-----------------------------------------------------------------*/
    2687        5483 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    2688        5483 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    2689        5483 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    2690        5483 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2691             : 
    2692        5483 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2693             :                                                 /* output of Pow2() will be: */
    2694             :                                                 /* 16384 < Pow2() <= 32767 */
    2695        5483 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2696             : 
    2697        5483 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    2698        5483 :         gc_mem[1] = *gain_code;                                                                             // Q16
    2699        5483 :         move32();
    2700        5483 :         gp_mem[1] = *gain_pit; // Q14
    2701        5483 :         move16();
    2702             :     }
    2703        6748 :     ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
    2704             :     {
    2705        3374 :         b = b_3sfr_fx; // Q12
    2706        3374 :         move16();
    2707        3374 :         n_pred = 6;
    2708        3374 :         move16();
    2709        3374 :         IF( EQ_16( nBits, 7 ) )
    2710             :         {
    2711           2 :             cdbk = gp_gamma_3sfr_7b_fx; /* Q14 / Q9 */
    2712           2 :             if ( EQ_16( clip_gain, 1 ) )
    2713             :             {
    2714           0 :                 size = sub( size, 28 );
    2715             :             }
    2716             :         }
    2717             :         ELSE
    2718             :         {
    2719        3372 :             cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */
    2720        3372 :             if ( EQ_16( clip_gain, 1 ) )
    2721             :             {
    2722           0 :                 size = sub( size, 11 );
    2723             :             }
    2724             :         }
    2725             :         /* calculate predicted gain */
    2726        3374 :         aux[0] = 4096; // Q12
    2727        3374 :         move16();
    2728        3374 :         aux[1] = shl( ctype, 12 );
    2729        3374 :         move16();
    2730             : 
    2731             :         /*aux[2] = (float)log10(gc_mem[0]);
    2732             :         = log2(gc_mem[0])*log10(2);*/
    2733        3374 :         exp = norm_l( gc_mem[0] );
    2734        3374 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    2735        3374 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[0])=16*/
    2736        3374 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2737        3374 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2738        3374 :         move16();
    2739             : 
    2740             :         /*aux[3] = (float)log10(gc_mem[1]);
    2741             :         =  log2(gc_mem[1])*log10(2);*/
    2742        3374 :         exp = norm_l( gc_mem[1] );
    2743        3374 :         frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
    2744        3374 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[1])=16*/
    2745        3374 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2746        3374 :         aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2747        3374 :         move16();
    2748             : 
    2749        3374 :         aux[4] = shr( gp_mem[0], 2 );
    2750        3374 :         move16(); /*Q12*/
    2751        3374 :         aux[5] = shr( gp_mem[1], 2 );
    2752        3374 :         move16(); /*Q12*/
    2753             : 
    2754             :         /*-----------------------------------------------------------------*
    2755             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    2756             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    2757             :          *-----------------------------------------------------------------*/
    2758        3374 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    2759        3374 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    2760        3374 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    2761        3374 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2762             : 
    2763        3374 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2764             :                                                 /* output of Pow2() will be: */
    2765             :                                                 /* 16384 < Pow2() <= 32767 */
    2766        3374 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2767             : 
    2768             :         /*----------------------------------------------------------------*
    2769             :          * Find the best quantizer
    2770             :          * ~~~~~~~~~~~~~~~~~~~~~~~
    2771             :          * Before doing the computation we need to align exponents of coeff[]
    2772             :          * to be sure to have the maximum precision.
    2773             :          *
    2774             :          * In the table the pitch gains are in Q14, the code gains are in Q9 and
    2775             :          * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
    2776             :          * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
    2777             :          * we divide by 2^15.
    2778             :          * Considering all the scaling above we have:
    2779             :          *
    2780             :          *   exp_code = exp_gcode0-9+15 = exp_gcode0+6
    2781             :          *
    2782             :          *   g_pitch*g_pitch  = -14-14+15
    2783             :          *   g_pitch          = -14
    2784             :          *   g_code*g_code    = (2*exp_code)+15
    2785             :          *   g_code           = exp_code
    2786             :          *   g_pitch*g_code   = -14 + exp_code +15
    2787             :          *
    2788             :          *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13
    2789             :          *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14
    2790             :          *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
    2791             :          *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
    2792             :          *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
    2793             :          *----------------------------------------------------------------*/
    2794             : 
    2795        3374 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
    2796             : 
    2797        3374 :         gc_mem[2] = *gain_code; /* Q16 */
    2798        3374 :         move32();
    2799        3374 :         gp_mem[2] = *gain_pit; /* Q14 */
    2800        3374 :         move16();
    2801             :     }
    2802        3374 :     ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
    2803             :     {
    2804        3374 :         b = b_4sfr_fx; /* Q12 */
    2805        3374 :         move16();
    2806        3374 :         n_pred = 8;
    2807        3374 :         move16();
    2808        3374 :         IF( EQ_16( nBits, 7 ) )
    2809             :         {
    2810           0 :             cdbk = gp_gamma_4sfr_7b_fx; /* Q14 / Q9 */
    2811           0 :             if ( EQ_16( clip_gain, 1 ) )
    2812             :             {
    2813           0 :                 size = sub( size, 25 );
    2814             :             }
    2815             :         }
    2816             :         ELSE
    2817             :         {
    2818        3374 :             cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */
    2819        3374 :             if ( EQ_16( clip_gain, 1 ) )
    2820             :             {
    2821           0 :                 size = sub( size, 11 );
    2822             :             }
    2823             :         }
    2824             :         /* calculate predicted gain */
    2825        3374 :         aux[0] = 4096; // Q12
    2826        3374 :         move16();
    2827        3374 :         aux[1] = shl( ctype, 12 );
    2828        3374 :         move16();
    2829             : 
    2830             :         /*aux[2] = (float)log10(gc_mem[0]);
    2831             :         = log2(gc_mem[0])*log10(2);*/
    2832        3374 :         exp = norm_l( gc_mem[0] );
    2833        3374 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    2834        3374 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[0])=16*/
    2835        3374 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2836        3374 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2837        3374 :         move16();
    2838             : 
    2839             :         /*aux[3] = (float)log10(gc_mem[1]);
    2840             :         =  log2(gc_mem[1])*log10(2);*/
    2841        3374 :         exp = norm_l( gc_mem[1] );
    2842        3374 :         frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
    2843        3374 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[1])=16*/
    2844        3374 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2845        3374 :         aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2846        3374 :         move16();
    2847             : 
    2848             :         /*aux[4] = (float)log10(gc_mem[2]);
    2849             :         =  log2(gc_mem[2])*log10(2);*/
    2850        3374 :         exp = norm_l( gc_mem[2] );
    2851        3374 :         frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) );
    2852        3374 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[2])=16*/
    2853        3374 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    2854        3374 :         aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    2855        3374 :         move16();
    2856             : 
    2857        3374 :         aux[5] = shr( gp_mem[0], 2 );
    2858        3374 :         move16(); /*Q12*/
    2859        3374 :         aux[6] = shr( gp_mem[1], 2 );
    2860        3374 :         move16(); /*Q12*/
    2861        3374 :         aux[7] = shr( gp_mem[2], 2 );
    2862        3374 :         move16();                                  /*Q12*/
    2863             :                                                    /*-----------------------------------------------------------------*
    2864             :                                                     * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    2865             :                                                     * = pow(2, 3.321928*dotp(b, aux, n_pred)
    2866             :                                                     *-----------------------------------------------------------------*/
    2867        3374 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    2868        3374 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    2869        3374 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    2870        3374 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    2871             : 
    2872        3374 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    2873             :                                                 /* output of Pow2() will be: */
    2874             :                                                 /* 16384 < Pow2() <= 32767 */
    2875        3374 :         exp_gcode0 = sub( exp_gcode0, 14 );
    2876             : 
    2877        3374 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    2878             :     }
    2879             : 
    2880             :     /* *norm_gain_code = *gain_code / *gain_inov; */
    2881       17714 :     exp = sub( norm_s( *gain_inov ), 1 );
    2882       17714 :     exp = s_max( exp, 0 );
    2883             : 
    2884       17714 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
    2885       17714 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
    2886       17714 :     move32();
    2887             :     {
    2888       17714 :         push_indice( hBstr, IND_GAIN, index, nBits );
    2889             :     }
    2890       17714 :     return;
    2891             : }
    2892             : 
    2893             : /*-------------------------------------------------------------------*
    2894             :  * gain_enc_amr_wb()
    2895             :  *
    2896             :  * Quantization of pitch and codebook gains (used also in AMR-WB IO mode)
    2897             :  * MA prediction is performed on the innovation energy (in dB with mean removed).
    2898             :  * An initial predicted gain, gcode0, is first determined and the correction
    2899             :  * factor     alpha = g_code / gcode0   is quantized.
    2900             :  * The pitch gain and the correction factor are vector quantized and the
    2901             :  * mean-squared weighted error criterion is used in the quantizer search.
    2902             :  *-------------------------------------------------------------------*/
    2903             : 
    2904             : 
    2905           0 : void gain_enc_amr_wb_fx(
    2906             :     BSTR_ENC_HANDLE hBstr,   /* i/o: encoder bitstream handle                                                                                   */
    2907             :     const Word16 *xn,        /* i  : target vector                                                                                                              Q_xn*/
    2908             :     const Word16 Q_xn,       /* i  : xn and yy1 format                                                                                                  */
    2909             :     const Word16 *yy1,       /* i  : zero-memory filtered adaptive excitation                                                   Q_xn*/
    2910             :     const Word16 *y2,        /* i  : zero-memory filtered algebraic codebook excitation                                 Q9*/
    2911             :     const Word16 *code,      /* i  : algebraic excitation                                                                                               Q9*/
    2912             :     const Word32 core_brate, /* i  : core bitrate                                                                                                               Q0*/
    2913             :     Word16 *gain_pit,        /* i/o: pitch gain / Quantized pitch gain                                                                  Q14*/
    2914             :     Word32 *gain_code,       /* o  : quantized codebook gain                                                                                    Q16*/
    2915             :     Word16 *gain_inov,       /* o  : gain of the innovation (used for normalization)                                    Q12*/
    2916             :     Word32 *norm_gain_code,  /* o  : norm. gain of the codebook excitation                                                              Q16*/
    2917             :     Word16 *g_coeff,         /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>      Qx*/
    2918             :     const Word16 clip_gain,  /* i  : gain pitch clipping flag (1 = clipping)                                                    Q0*/
    2919             :     Word16 *past_qua_en      /* i/o: gain quantization memory (4 words)                                                                 Q10*/
    2920             : )
    2921             : {
    2922             : 
    2923             :     Word16 i, j, index, min_ind, size;
    2924             :     Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, exp_inov, qua_ener;
    2925             :     Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
    2926             :     Word16 coeff[5], coeff_lo[5], exp_coeff[5];
    2927             :     Word16 exp_max[5], tmp, nBits;
    2928             :     Word32 L_tmp, dist_min, L_inov, L_tmp1;
    2929             :     const Word16 *t_qua_gain, *p;
    2930             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    2931           0 :     Flag Overflow = 0;
    2932           0 :     move32();
    2933             : #endif
    2934             : 
    2935             :     /*----------------------------------------------------------------*
    2936             :      * Find the initial quantization pitch index
    2937             :      * Set gains search range
    2938             :      *----------------------------------------------------------------*/
    2939           0 :     IF( GE_32( core_brate, ACELP_12k65 ) )
    2940             :     {
    2941           0 :         t_qua_gain = t_qua_gain7b_fx; // Q14
    2942           0 :         move16();
    2943             :         /* pt at 1/4th of table */
    2944           0 :         p = t_qua_gain7b_fx + RANGE;
    2945           0 :         move16();
    2946             : 
    2947           0 :         j = NB_QUA_GAIN7B - RANGE;
    2948           0 :         move16();
    2949             : 
    2950           0 :         IF( EQ_16( clip_gain, 1 ) )
    2951             :         {
    2952           0 :             j = sub( j, 27 ); /* limit gain pitch to 1.0 */
    2953             :         }
    2954           0 :         min_ind = 0;
    2955           0 :         move16();
    2956           0 :         g_pitch = *gain_pit; // Q14
    2957           0 :         move16();
    2958             : 
    2959           0 :         FOR( i = 0; i < j; i++ )
    2960             :         {
    2961           0 :             if ( GT_16( g_pitch, *p ) )
    2962             :             {
    2963           0 :                 min_ind = add( min_ind, 1 ); // Q0
    2964             :             }
    2965           0 :             p += 2;
    2966             :         }
    2967           0 :         size = RANGE;
    2968           0 :         move16();
    2969           0 :         nBits = 7;
    2970             :     }
    2971             :     ELSE
    2972             :     {
    2973           0 :         t_qua_gain = t_qua_gain6b_fx; // Q14
    2974           0 :         min_ind = 0;
    2975           0 :         move16();
    2976           0 :         size = RANGE;
    2977           0 :         move16();
    2978           0 :         if ( EQ_16( clip_gain, 1 ) )
    2979             :         {
    2980           0 :             size = sub( size, 16 ); /* limit gain pitch to 1.0 */
    2981             :         }
    2982           0 :         nBits = 6;
    2983             :     }
    2984             :     /*----------------------------------------------------------------*
    2985             :      *  Compute coefficients needed for the quantization.
    2986             :      *
    2987             :      *  coeff[0] =    yy1 yy1
    2988             :      *  coeff[1] = -2 xn yy1
    2989             :      *  coeff[2] =    y2 y2
    2990             :      *  coeff[3] = -2 xn y2
    2991             :      *  coeff[4] =  2 yy1 y2
    2992             :      *
    2993             :      * Product <yy1 yy1> and <xn yy1> have been computed in Adpt_enr() and
    2994             :      * are in vector g_coeff[].
    2995             :      *----------------------------------------------------------------*/
    2996           0 :     coeff[0] = g_coeff[0];
    2997           0 :     move16();
    2998           0 :     exp_coeff[0] = g_coeff[1];
    2999           0 :     move16();
    3000           0 :     coeff[1] = negate( g_coeff[2] );
    3001           0 :     move16(); /* coeff[1] = -2 xn yy1 */
    3002           0 :     exp_coeff[1] = add( g_coeff[3], 1 );
    3003           0 :     move16();
    3004             : 
    3005             :     /* Compute scalar product <y2[],y2[]> */
    3006           0 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
    3007           0 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
    3008           0 :     move16();
    3009           0 :     move16();
    3010             : 
    3011             :     /* Compute scalar product -2*<xn[],y2[]> */
    3012           0 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
    3013           0 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
    3014           0 :     move16();
    3015           0 :     move16();
    3016             : 
    3017             :     /* Compute scalar product 2*<yy1[],y2[]> */
    3018           0 :     coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
    3019           0 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
    3020           0 :     move16();
    3021           0 :     move16();
    3022             : 
    3023             :     /*----------------------------------------------------------------*
    3024             :      *  Find energy of code and compute:
    3025             :      *
    3026             :      *    L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr)
    3027             :      *          = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr)
    3028             :      *----------------------------------------------------------------*/
    3029           0 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
    3030           0 :     L_inov = L_add( L_tmp, 0 );
    3031             :     /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */
    3032             :     /* output gain_inov*/
    3033           0 :     exp_inov = sub( exp_code, 18 + 6 );
    3034           0 :     L_inov = Isqrt_lc( L_inov, &exp_inov );
    3035           0 :     *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
    3036           0 :     move16();
    3037             : 
    3038           0 :     exp_code = sub( exp_code, 18 + 6 + 31 );
    3039           0 :     frac = Log2_lc( L_tmp, &exp );
    3040           0 :     exp = add( exp, exp_code );
    3041           0 :     L_tmp = Mpy_32_16( exp, frac, -24660 ); /* x -3.0103(Q13) -> Q14 */
    3042             : 
    3043           0 :     L_tmp = L_mac( L_tmp, MEAN_ENER, 8192 ); /* + MEAN_ENER in Q14 */
    3044             : 
    3045             :     /*----------------------------------------------------------------*
    3046             :      * predicted codebook gain
    3047             :      *----------------------------------------------------------------*/
    3048           0 :     L_tmp = L_shl( L_tmp, 10 );                               /* From Q14 to Q24 */
    3049           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[0], past_qua_en[0] ); /* Q14*Q10 -> Q24 */
    3050           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[1], past_qua_en[1] ); /* Q14*Q10 -> Q24 */
    3051           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[2], past_qua_en[2] ); /* Q14*Q10 -> Q24 */
    3052           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[3], past_qua_en[3] ); /* Q14*Q10 -> Q24 */
    3053             : 
    3054           0 :     gcode0 = extract_h( L_tmp ); /* From Q24 to Q8  */
    3055             : 
    3056             :     /*----------------------------------------------------------------*
    3057             :      * gcode0 = pow(10.0, gcode0/20)
    3058             :      *        = pow(2, 3.321928*gcode0/20)
    3059             :      *        = pow(2, 0.166096*gcode0)
    3060             :      *----------------------------------------------------------------*/
    3061           0 :     L_tmp = L_mult( gcode0, 5443 );         /* *0.166096 in Q15 -> Q24    */
    3062           0 :     L_tmp = L_shr( L_tmp, 8 );              /* From Q24 to Q16            */
    3063           0 :     L_Extract( L_tmp, &exp_gcode0, &frac ); /* Extract exponent of gcode0 */
    3064             : 
    3065           0 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    3066             :     /* output of Pow2() will be: */
    3067             :     /* 16384 < Pow2() <= 32767   */
    3068           0 :     exp_gcode0 = sub( exp_gcode0, 14 );
    3069             : 
    3070             :     /*----------------------------------------------------------------*
    3071             :      * Find the best quantizer
    3072             :      * ~~~~~~~~~~~~~~~~~~~~~~~
    3073             :      * Before doing the computation we need to aling exponents of coeff[]
    3074             :      * to be sure to have the maximum precision.
    3075             :      *
    3076             :      * In the table the pitch gains are in Q14, the code gains are in Q11 and
    3077             :      * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
    3078             :      * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
    3079             :      * we divide by 2^15.
    3080             :      * Considering all the scaling above we have:
    3081             :      *
    3082             :      *   exp_code = exp_gcode0-11+15 = exp_gcode0+4
    3083             :      *
    3084             :      *   g_pitch*g_pitch  = -14-14+15
    3085             :      *   g_pitch          = -14
    3086             :      *   g_code*g_code    = (2*exp_code)+15
    3087             :      *   g_code           = exp_code
    3088             :      *   g_pitch*g_code   = -14 + exp_code +15
    3089             :      *
    3090             :      *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13
    3091             :      *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14
    3092             :      *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
    3093             :      *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
    3094             :      *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
    3095             :      *----------------------------------------------------------------*/
    3096             : 
    3097           0 :     exp_code = add( exp_gcode0, 4 );
    3098             : 
    3099           0 :     exp_max[0] = sub( exp_coeff[0], 13 );
    3100           0 :     move16();
    3101           0 :     exp_max[1] = sub( exp_coeff[1], 14 );
    3102           0 :     move16();
    3103           0 :     exp_max[2] = add( exp_coeff[2],
    3104           0 :                       add( 15, shl( exp_code, 1 ) ) );
    3105           0 :     move16();
    3106           0 :     exp_max[3] = add( exp_coeff[3], exp_code );
    3107           0 :     move16();
    3108           0 :     exp_max[4] = add( exp_coeff[4],
    3109           0 :                       add( 1, exp_code ) );
    3110           0 :     move16();
    3111             : 
    3112             :     /* Find maximum exponant */
    3113           0 :     e_max = exp_max[0];
    3114           0 :     move16();
    3115           0 :     FOR( i = 1; i < 5; i++ )
    3116             :     {
    3117           0 :         e_max = s_max( exp_max[i], e_max );
    3118             :     }
    3119             : 
    3120             :     /* align coeff[] and save in special 32 bit double precision */
    3121           0 :     FOR( i = 0; i < 5; i++ )
    3122             :     {
    3123           0 :         j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
    3124           0 :         L_tmp = L_deposit_h( coeff[i] );
    3125           0 :         L_tmp = L_shr( L_tmp, j );
    3126           0 :         L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
    3127           0 :         coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
    3128           0 :         move16();
    3129             :     }
    3130             : 
    3131             :     /* Codebook search */
    3132           0 :     dist_min = L_add( MAX_32, 0 );
    3133           0 :     p = &t_qua_gain[shl( min_ind, 1 )]; // Q14
    3134           0 :     move16();
    3135             : 
    3136           0 :     index = 0;
    3137           0 :     move16();
    3138           0 :     FOR( i = 0; i < size; i++ )
    3139             :     {
    3140           0 :         g_pitch = *p++;
    3141           0 :         move16();
    3142           0 :         g_code = *p++;
    3143           0 :         move16();
    3144             : 
    3145           0 :         g_code = mult_r( g_code, gcode0 );     // exp(gcode) - 1
    3146           0 :         g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
    3147           0 :         g_pit_cod = mult_r( g_code, g_pitch );
    3148           0 :         L_tmp = L_mult( g_code, g_code );
    3149           0 :         L_Extract( L_tmp, &g2_code, &g2_code_lo );
    3150             : 
    3151           0 :         L_tmp = L_mult( coeff[2], g2_code_lo );
    3152           0 :         L_tmp = L_shr( L_tmp, 3 );
    3153           0 :         L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
    3154           0 :         L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
    3155           0 :         L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
    3156           0 :         L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
    3157           0 :         L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
    3158           0 :         L_tmp = L_shr( L_tmp, 12 );
    3159           0 :         L_tmp = L_mac( L_tmp, coeff[0], g2_pitch );  /* 15 - coeff_exp + 13 - 1 */
    3160           0 :         L_tmp = L_mac( L_tmp, coeff[1], g_pitch );   /* 15 - coeff_exp + 13 - 1 */
    3161           0 :         L_tmp = L_mac( L_tmp, coeff[2], g2_code );   /* 15 - coeff_exp + 13 - 1 */
    3162           0 :         L_tmp = L_mac( L_tmp, coeff[3], g_code );    /* 15 - coeff_exp + 13 - 1 */
    3163           0 :         L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
    3164             : 
    3165           0 :         L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
    3166             :         /* splitting the if cost half the complexity of using IF macro */
    3167           0 :         if ( L_tmp1 < 0 )
    3168             :         {
    3169           0 :             dist_min = L_add( L_tmp, 0 );
    3170             :         }
    3171           0 :         if ( L_tmp1 < 0 )
    3172             :         {
    3173           0 :             index = i;
    3174           0 :             move16();
    3175             :         }
    3176             :     }
    3177             :     /* Read the quantized gains */
    3178           0 :     index = add( index, min_ind );
    3179             : 
    3180           0 :     p = &t_qua_gain[add( index, index )];
    3181           0 :     move16();
    3182           0 :     *gain_pit = *p++; /* selected pitch gain in Q14 */
    3183           0 :     move16();
    3184           0 :     g_code = *p++; /* selected  code gain in Q11 */
    3185           0 :     move16();
    3186             : 
    3187           0 :     L_tmp = L_mult( g_code, gcode0 );                          /* Q11*Q0 -> Q12 */
    3188           0 :     L_tmp = L_shl_o( L_tmp, add( exp_gcode0, 4 ), &Overflow ); /* Q12 -> Q16 */
    3189             : 
    3190           0 :     *gain_code = L_tmp; /* gain of code in Q16 */
    3191           0 :     move16();
    3192             : 
    3193             :     /*---------------------------------------------------*
    3194             :      * qua_ener = 20*log10(g_code)
    3195             :      *          = 6.0206*log2(g_code)
    3196             :      *          = 6.0206*(log2(g_codeQ11) - 11)
    3197             :      *---------------------------------------------------*/
    3198           0 :     L_tmp = L_deposit_l( g_code );
    3199           0 :     frac = Log2_lc( L_tmp, &exp );
    3200           0 :     exp = sub( exp, 11 );
    3201           0 :     L_tmp = Mpy_32_16( exp, frac, 24660 ); /* x 6.0206 in Q12 */
    3202             : 
    3203           0 :     qua_ener = extract_l( L_shr( L_tmp, 3 ) ); /* result in Q10 */
    3204             : 
    3205             :     /*----------------------------------------------------------------*
    3206             :      * update table of past quantized energies
    3207             :      *----------------------------------------------------------------*/
    3208             : 
    3209           0 :     past_qua_en[3] = past_qua_en[2]; // Q10
    3210           0 :     move16();
    3211           0 :     past_qua_en[2] = past_qua_en[1]; // Q10
    3212           0 :     move16();
    3213           0 :     past_qua_en[1] = past_qua_en[0]; // Q10
    3214           0 :     move16();
    3215           0 :     past_qua_en[0] = qua_ener; // Q10
    3216           0 :     move16();
    3217             : 
    3218             : 
    3219           0 :     exp = sub( norm_s( *gain_inov ), 1 );
    3220           0 :     exp = s_max( exp, 0 );
    3221             : 
    3222           0 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
    3223           0 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
    3224           0 :     move32();
    3225             : 
    3226           0 :     push_indice( hBstr, IND_GAIN, index, nBits );
    3227             : 
    3228           0 :     return;
    3229             : }

Generated by: LCOV version 1.14