LCOV - code coverage report
Current view: top level - lib_enc - gain_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 678 898 75.5 %
Date: 2025-09-14 03:13:15 Functions: 6 8 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      133403 : 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             : #ifndef ISSUE_1867_replace_overflow_libenc
      68             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      69             :     Flag Overflow = 0;
      70             :     move32();
      71             : #endif
      72             : #endif
      73             : 
      74      133403 :     Lmean_ener_code = L_deposit_l( 0 );
      75      133403 :     Q_res = sub( shl( Q_new, 1 ), 3 );
      76             : 
      77      133403 :     IF( EQ_16( L_frame, L_FRAME ) )
      78             :     {
      79       61429 :         weight = 8192;
      80       61429 :         move16(); /*0.25f in Q15*/
      81             :     }
      82             :     ELSE /* L_frame == L_FRAME16k */
      83             :     {
      84       71974 :         weight = 6554;
      85       71974 :         move16(); /*0.2f in Q15*/
      86             :     }
      87             : 
      88             :     /*----------------------------------------------------------*
      89             :      * calculate the average residual signal energy in four sframes
      90             :      *----------------------------------------------------------*/
      91             : 
      92      738989 :     FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
      93             :     {
      94             :         /* calculate the energy of residual signal */
      95      605586 :         tmp16 = mult_r( res[i_subfr + 0], 8192 /* 1 in Q13 */ ); /* remove 2bits        Q_new - 2*/
      96      605586 :         ener_fx = L_mult( tmp16, tmp16 );
      97    38757504 :         FOR( i = 1; i < L_SUBFR; i++ )
      98             :         {
      99    38151918 :             tmp16 = mult_r( res[i_subfr + i], 8192 /* 1 in Q13 */ ); /* remove 2bits    Q_new - 2*/
     100             : #ifdef ISSUE_1867_replace_overflow_libenc
     101    38151918 :             ener_fx = L_mac_sat( ener_fx, tmp16, tmp16 );
     102             : #else
     103             :             ener_fx = L_mac_o( ener_fx, tmp16, tmp16, &Overflow );
     104             : #endif
     105             :         }
     106             : 
     107             :         /* ener = 10 * (float)log10(ener / (float)L_SUBFR) */
     108      605586 :         s1 = 0;
     109      605586 :         move16();
     110      605586 :         s0 = norm_l( ener_fx );
     111             : 
     112      605586 :         IF( ener_fx != 0 ) /* Log2_norm_lc doesn't Support Input <= 0; deal with it here */
     113             :         {
     114      599882 :             s1 = Log2_norm_lc( L_shl( ener_fx, s0 ) );
     115      599882 :             s0 = sub( 30, s0 );
     116             :         }
     117      605586 :         s0 = sub( s0, add( Q_res, 6 ) );
     118      605586 :         Ltmp = Mpy_32_16( s0, s1, LG10 );
     119      605586 :         ener_dB = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 Energy in log10 */
     120      605586 :         test();
     121      605586 :         if ( ( ener_dB < 0 ) && ( no_ltp == 0 ) )
     122             :         {
     123       13356 :             ener_dB = 0;
     124       13356 :             move16();
     125             :         }
     126             : 
     127             :         /* update the average energy of residual signal */
     128      605586 :         Lmean_ener_code = L_mac( Lmean_ener_code, ener_dB, weight ); /* Q24 */
     129             :     }
     130             : 
     131      133403 :     IF( no_ltp == 0 )
     132             :     {
     133             :         /*----------------------------------------------------------*
     134             :          * subtract an estimate of adaptive codebook contribution
     135             :          *----------------------------------------------------------*/
     136             :         /*mean_ener_code -= 10.0f * (0.5f * voicing[0] + 0.5f * voicing[1]);*/
     137      131387 :         Lmean_ener_code = L_msu( Lmean_ener_code, voicing[0], 1280 ); /*Q24*/
     138      131387 :         Lmean_ener_code = L_msu( Lmean_ener_code, voicing[1], 1280 ); /*Q24*/
     139      131387 :         mean_ener_code16 = extract_h( Lmean_ener_code );              /*Q8*/
     140             : 
     141             :         /*----------------------------------------------------------*n
     142             :          * quantize the average predicted innovation energy
     143             :          *----------------------------------------------------------*/
     144      131387 :         SWITCH( nb_bits )
     145             :         {
     146      113152 :             case 5:
     147             :             {
     148      113152 :                 qua_table = Es_pred_qua_5b_fx; // Q8
     149      113152 :                 BREAK;
     150             :             }
     151       17623 :             case 4:
     152             :             {
     153       17623 :                 qua_table = Es_pred_qua_4b_fx; // Q8
     154       17623 :                 BREAK;
     155             :             }
     156         612 :             case 3:
     157             :             {
     158         612 :                 qua_table = Es_pred_qua_3b_fx; // Q8
     159         612 :                 BREAK;
     160             :             }
     161           0 :             default:
     162             :             {
     163           0 :                 qua_table = Es_pred_qua_5b_fx; // Q8
     164           0 :                 BREAK;
     165             :             }
     166             :         }
     167             :     }
     168             :     ELSE
     169             :     {
     170        2016 :         mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
     171             : 
     172        2016 :         qua_table = Es_pred_qua_4b_no_ltp_fx; // Q8
     173             :     }
     174             :     /*size = extract_l(pow2_fx[nb_bits]); */ /*maximum number of bit is 6 */
     175      133403 :     size = shl( 1, nb_bits );                /*maximum number of bit is 6 */
     176             : 
     177             :     /* find the nearest neighbour (codevector) */
     178      133403 :     *Es_pred = qua_table[0]; // Q8
     179      133403 :     move16();
     180      133403 :     tmp16 = abs_s( sub( mean_ener_code16, qua_table[0] ) );
     181      133403 :     *indice = 0;
     182      133403 :     move16();
     183             : 
     184     3939984 :     FOR( i = 1; i < size; i++ )
     185             :     {
     186             : #ifdef ISSUE_1867_replace_overflow_libenc
     187     3806581 :         tmp16_2 = abs_s( sub_sat( mean_ener_code16, qua_table[i] ) );
     188             : #else
     189             :         tmp16_2 = abs_s( sub_o( mean_ener_code16, qua_table[i], &Overflow ) );
     190             : #endif
     191     3806581 :         IF( LT_16( tmp16_2, tmp16 ) )
     192             :         {
     193     1959106 :             tmp16 = tmp16_2;
     194     1959106 :             move16();
     195     1959106 :             *indice = i;
     196     1959106 :             move16();
     197     1959106 :             *Es_pred = qua_table[i]; // Q8
     198     1959106 :             move16();
     199             :         }
     200             :     }
     201             : 
     202             : 
     203      133403 :     return;
     204             : }
     205             : /*---------------------------------------------------------------------*
     206             :  * gain_enc_mless()
     207             :  *
     208             :  * Quantization of pitch and codebook gains without prediction (memory-less)
     209             :  * - an initial predicted gain, gcode0, is first determined based on
     210             :  *   the predicted average innovation energy
     211             :  * - a correction factor gamma = g_code / gcode0 is then vector quantized along with gain_pit
     212             :  * - the mean-squared weighted error criterion is used for codebook search
     213             :  *---------------------------------------------------------------------*/
     214      527586 : void gain_enc_mless_fx(
     215             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                 */
     216             :     const Word16 gains_mode[], /* i  : gain bits                                                                                                                Q0*/
     217             :     const Word16 element_mode, /* i  : element mode                                                                                                             Q0*/
     218             :     const Word16 L_frame,      /* i  : length of the frame                                                                                              Q0*/
     219             :     const Word16 i_subfr,      /* i  : subframe index                                                                                                   Q0*/
     220             :     const Word16 tc_subfr,     /* i  : TC subframe index                                                                                                Q0*/
     221             :     const Word16 *xn,          /* i  : target vector                                                                                                    Q_xn*/
     222             :     const Word16 *y1,          /* i  : zero-memory filtered adaptive excitation                                                 Q_xn*/
     223             :     const Word16 Q_xn,         /* i  : xn and y1 scaling                                                                                                */
     224             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation                               Q9*/
     225             :     const Word16 *code,        /* i  : algebraic excitation                                                                                             Q9*/
     226             :     const Word16 Es_pred,      /* i  : predicted scaled innovation energy                                                               Q8*/
     227             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                                                                             Q14*/
     228             :     Word32 *gain_code,         /* o  : quantized codebook gain                                                                                  Q16*/
     229             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                                  Q12*/
     230             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                                                    Q16*/
     231             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>    Qx*/
     232             :     const Word16 clip_gain     /* i  : gain pitch clipping flag (1 = clipping)                                                  Q0*/
     233             : )
     234             : {
     235             : 
     236             :     Word16 index, size, nBits, nBits2;
     237             :     Word16 gcode0, Ei, gain_code16;
     238             :     const Word16 *qua_table;
     239             :     Word16 coeff[5], exp_coeff[5];
     240             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
     241             :     Word32 L_tmp, L_tmp1, L_tmp2;
     242             :     Word16 tmp1, expg;
     243             :     Word16 exp1, exp2;
     244             :     Word16 exp_num, exp_den, exp_div, frac_den;
     245             :     Word32 L_frac_num, L_frac_den, L_div;
     246             : #ifndef ISSUE_1867_replace_overflow_libenc
     247             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     248             :     Flag Overflow = 0;
     249             :     move32();
     250             : #endif
     251             : #endif
     252             : 
     253             :     /*-----------------------------------------------------------------*
     254             :      * calculate the rest of the correlation coefficients
     255             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
     256             :      *-----------------------------------------------------------------*/
     257             : 
     258      527586 :     coeff[0] = g_corr[0];
     259      527586 :     move16();
     260      527586 :     exp_coeff[0] = g_corr[1];
     261      527586 :     move16();
     262      527586 :     coeff[1] = negate( g_corr[2] );
     263      527586 :     move16(); /* coeff[1] = -2 xn yy1 */
     264      527586 :     exp_coeff[1] = add( g_corr[3], 1 );
     265      527586 :     move16();
     266             : 
     267             :     /* Compute scalar product <y2[],y2[]> */
     268      527586 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
     269      527586 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
     270      527586 :     move16(); /* -18 (y2 Q9) */
     271             : 
     272             :     /* Compute scalar product -2*<xn[],y2[]> */
     273      527586 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
     274      527586 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
     275      527586 :     move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
     276             : 
     277             :     /* Compute scalar product 2*<y1[],y2[]> */
     278      527586 :     coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
     279      527586 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
     280      527586 :     move16(); /* -9 (y2 Q9), +1 (2 y1 y2) */
     281             : 
     282             :     /*-----------------------------------------------------------------*
     283             :      * calculate the unscaled innovation energy
     284             :      * calculate the predicted gain code
     285             :      *-----------------------------------------------------------------*/
     286             : 
     287             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     288      527586 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
     289      527586 :     exp_inov = sub( exp_code, 18 + 6 );
     290             :     // To avoid crash in case code value is 0,
     291      527586 :     test();
     292      527586 :     IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, exp_inov, 21474836, 0 ), -1 ) && element_mode > EVS_MONO )
     293             :     {
     294             :         // setting values to avoid extra computation
     295           0 :         *gain_inov = 32767; /*8(max value gain_inov can hold) in Q12*/
     296           0 :         Ei = -9743;         /* -38 in Q8*/
     297           0 :         move16();
     298           0 :         move16();
     299             :     }
     300             :     ELSE
     301             :     {
     302             : 
     303      527586 :         exp_code = sub( exp_code, 30 );
     304             : 
     305             :         /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     306             : 
     307             :         /*----------------------------------------------------------------*
     308             :          * calculate the predicted gain code
     309             :          *----------------------------------------------------------------*/
     310      527586 :         tmp = norm_l( L_tmp );
     311      527586 :         frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
     312      527586 :         tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
     313      527586 :         L_tmp1 = Mpy_32_16( tmp, frac, 12330 );             /* Q13 */
     314      527586 :         Ei = round_fx( L_shl( L_tmp1, 11 ) );               /* Q8 */
     315             :         /*---------------------------------------------------------------*
     316             :          * Decode codebook gain and the adaptive excitation low-pass
     317             :          * filtering factor (Finalize computation )
     318             :          *---------------------------------------------------------------*/
     319             :         /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     320      527586 :         L_tmp = Isqrt_lc( L_tmp, &exp_inov );
     321      527586 :         *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
     322      527586 :         move16();
     323             :     }
     324             :     /* predicted codebook gain */
     325      527586 :     gcode0 = sub( Es_pred, Ei ); /* Q8 */
     326             :     /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
     327             :     /*----------------------------------------------------------------*
     328             :      * gcode0 = pow(10.0, gcode0/20)
     329             :      *        = pow(2, 3.321928*gcode0/20)
     330             :      *        = pow(2, 0.166096*gcode0)
     331             :      *----------------------------------------------------------------*/
     332             : 
     333      527586 :     L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26    */
     334      527586 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16            */
     335      527586 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
     336             : 
     337      527586 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
     338             :     /* output of Pow2() will be: */
     339             :     /* 16384 < Pow2() <= 32767   */
     340      527586 :     exp_gcode0 = sub( exp_gcode0, 14 );
     341             : 
     342             :     /*-----------------------------------------------------------------*
     343             :      * select the codebook, size and number of bits
     344             :      * set the gains searching range
     345             :      *-----------------------------------------------------------------*/
     346      527586 :     nBits = gains_mode[i_subfr >> 6];
     347      527586 :     move16();
     348             : 
     349      527586 :     test();
     350      527586 :     test();
     351      527586 :     test();
     352      527586 :     test();
     353      527586 :     test();
     354      527586 :     IF( ( EQ_16( tc_subfr, 3 * L_SUBFR ) && EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( L_frame, L_FRAME ) ) ||
     355             :         ( EQ_16( tc_subfr, 4 * L_SUBFR ) && EQ_16( i_subfr, 4 * L_SUBFR ) && EQ_16( L_frame, L_FRAME16k ) ) )
     356             :     {
     357             :         /*    *gain_pit =  (g_corr[2]*tmp2) - (0.5f*g_corr[4]*tmp3);
     358             :                         =  ((-0.5f*g_corr[1]*g_corr[2]) - (-0.25*g_corr[3]*g_corr[4]))/tmp1;
     359             :                         =  ((0.25*g_corr[3]*g_corr[4]) - (0.5*g_corr[1]*g_corr[2]))/tmp1; */
     360             : 
     361             :         /*     *gain_code = (g_corr[0]*tmp3) - (0.5f*g_corr[4]*tmp2);
     362             :                           = ((-0.5*g_corr[3]*g_corr[0]) - (-0.25*g_corr[1]*g_corr[4]))/tmp1;
     363             :                           = ((0.25*g_corr[1]*g_corr[4]) - (0.5*g_corr[0]*g_corr[3]))/tmp1; */
     364             : 
     365        3666 :         L_tmp1 = L_mult_sat( coeff[0], coeff[2] ); /*Q31*/
     366        3666 :         exp1 = add( exp_coeff[0], exp_coeff[2] );
     367             : 
     368        3666 :         L_tmp2 = L_shr( L_mult_sat( coeff[4], coeff[4] ), 2 ); /*Q31*/
     369        3666 :         exp2 = add( exp_coeff[4], exp_coeff[4] );
     370             : 
     371        3666 :         IF( GT_16( exp1, exp2 ) )
     372             :         {
     373        3567 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     374        3567 :             exp_den = exp1;
     375        3567 :             move16();
     376             :         }
     377             :         ELSE
     378             :         {
     379          99 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     380          99 :             exp_den = exp2;
     381          99 :             move16();
     382             :         }
     383        3666 :         L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     384             : 
     385        3666 :         frac_den = extract_h( L_frac_den );  /* Q15 */
     386        3666 :         frac_den = s_max( frac_den, 1 );     /* Q15 */
     387        3666 :         L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
     388        3666 :         exp = norm_l( L_frac_den );
     389        3666 :         tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
     390             : 
     391        3666 :         L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
     392        3666 :         exp1 = add( exp_coeff[3], exp_coeff[4] );
     393             : 
     394        3666 :         L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
     395        3666 :         exp2 = add( exp_coeff[1], exp_coeff[2] );
     396             : 
     397        3666 :         IF( GT_16( exp1, exp2 ) )
     398             :         {
     399         115 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     400         115 :             exp_num = exp1;
     401         115 :             move16();
     402             :         }
     403             :         ELSE
     404             :         {
     405        3551 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     406        3551 :             exp_num = exp2;
     407        3551 :             move16();
     408             :         }
     409        3666 :         L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     410             : 
     411        3666 :         L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     412        3666 :         exp_div = sub( exp_num, exp_den );
     413             : 
     414             : #ifdef ISSUE_1867_replace_overflow_libenc
     415        3666 :         *gain_pit = round_fx_sat( L_shl_sat( L_div, add( exp, exp_div ) ) ); /*Q14*/
     416             : #else
     417             :         *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
     418             : #endif
     419             : 
     420        3666 :         L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
     421        3666 :         exp1 = add( exp_coeff[1], exp_coeff[4] );
     422             : 
     423        3666 :         L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
     424        3666 :         exp2 = add( exp_coeff[0], exp_coeff[3] );
     425             : 
     426        3666 :         IF( GT_16( exp1, exp2 ) )
     427             :         {
     428          58 :             L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     429          58 :             exp_num = exp1;
     430          58 :             move16();
     431             :         }
     432             :         ELSE
     433             :         {
     434        3608 :             L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     435        3608 :             exp_num = exp2;
     436        3608 :             move16();
     437             :         }
     438        3666 :         L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     439             : 
     440        3666 :         L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     441        3666 :         exp_div = sub( exp_num, exp_den );
     442             : 
     443             : #ifdef ISSUE_1867_replace_overflow_libenc
     444        3666 :         *gain_code = L_shl_sat( L_div, sub( add( exp, exp_div ), 14 ) );
     445             : #else
     446             :         *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
     447             : #endif
     448        3666 :         move32(); /*Q16*/
     449             : 
     450        3666 :         *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) );
     451        3666 :         move16();
     452             : 
     453             :         /* set number of bits for two SQs */
     454        3666 :         nBits2 = shr( add( nBits, 1 ), 1 );
     455        3666 :         nBits = shr( nBits, 1 );
     456             : 
     457             :         /* gain_pit Q */
     458             : 
     459        3666 :         tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
     460        3666 :         index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
     461        3666 :         move16();
     462        3666 :         push_indice( hBstr, IND_GAIN_PIT, index, nBits );
     463             : 
     464             :         /* gain_code Q */
     465             :         /**gain_code /= gcode0;*/
     466        3666 :         IF( gcode0 != 0 )
     467             :         {
     468        3666 :             tmp = div_s( 16384, gcode0 );                       /*Q15*/
     469        3666 :             L_tmp = Mult_32_16( *gain_code, tmp );              /*Q16*/
     470        3666 :             *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
     471        3666 :             move32();
     472             :         }
     473             : 
     474        3666 :         index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
     475        3666 :         push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
     476        3666 :         L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
     477             : #ifdef ISSUE_1867_replace_overflow_libenc
     478        3666 :         *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
     479             : #else
     480             :         *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow );      /*Q16*/
     481             : #endif
     482             :     }
     483             :     ELSE
     484             :     {
     485      523920 :         size = shl( 1, nBits );
     486             : 
     487      523920 :         SWITCH( nBits )
     488             :         {
     489         749 :             case 7:
     490             :             {
     491         749 :                 qua_table = gain_qua_mless_7b_fx;
     492         749 :                 move16();
     493         749 :                 if ( EQ_16( clip_gain, 1 ) )
     494             :                 {
     495           0 :                     size = sub( size, 30 );
     496             :                 }
     497         749 :                 BREAK;
     498             :             }
     499      522646 :             case 6:
     500             :             {
     501      522646 :                 qua_table = gain_qua_mless_6b_fx;
     502      522646 :                 if ( element_mode > EVS_MONO )
     503             :                 {
     504      519755 :                     qua_table = gain_qua_mless_6b_stereo_fx;
     505             :                 }
     506      522646 :                 move16();
     507      522646 :                 if ( EQ_16( clip_gain, 1 ) )
     508             :                 {
     509        5958 :                     size = sub( size, 14 );
     510             :                 }
     511      522646 :                 BREAK;
     512             :             }
     513         525 :             case 5:
     514             :             {
     515         525 :                 qua_table = gain_qua_mless_5b_fx; // Q14
     516         525 :                 move16();
     517         525 :                 if ( EQ_16( clip_gain, 1 ) )
     518             :                 {
     519           0 :                     size = sub( size, 6 );
     520             :                 }
     521         525 :                 BREAK;
     522             :             }
     523           0 :             default:
     524             :             {
     525           0 :                 qua_table = gain_qua_mless_6b_fx; // Q14
     526           0 :                 move16();
     527           0 :                 if ( EQ_16( clip_gain, 1 ) )
     528             :                 {
     529           0 :                     size = sub( size, 14 );
     530             :                 }
     531           0 :                 BREAK;
     532             :             }
     533             :         }
     534             : 
     535             :         /* in case of AVQ inactive, limit the gain_pit to 0.65 */
     536      523920 :         test();
     537      523920 :         IF( EQ_16( clip_gain, 2 ) && EQ_16( nBits, 6 ) )
     538             :         {
     539        5320 :             size = sub( size, 36 );
     540        5320 :             nBits = sub( nBits, 1 );
     541             :         }
     542             : 
     543             :         /*-----------------------------------------------------------------*
     544             :          * search for the best quantizer
     545             :          *-----------------------------------------------------------------*/
     546      523920 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0
     547      523920 :         push_indice( hBstr, IND_GAIN, index, nBits );
     548             :     }
     549             : 
     550             :     /* *norm_gain_code = *gain_code / *gain_inov; */
     551      527586 :     exp = sub( norm_s( *gain_inov ), 1 );
     552      527586 :     exp = s_max( exp, 0 );
     553             : 
     554      527586 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
     555      527586 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) );
     556      527586 :     move32();
     557             : 
     558      527586 :     return;
     559             : }
     560             : /*---------------------------------------------------------------------*
     561             :  * gain_enc_SQ()
     562             :  *
     563             :  * Scalar Quantization of pitch and codebook gains without prediction
     564             :  * - an initial predicted gain, gcode0, is first determined based on
     565             :  *   the predicted scaled innovation energy
     566             :  * - a correction factor gamma = g_code / gcode0 is then vector quantized
     567             :  *   along with gain_pit
     568             :  * - the mean-squared weighted error criterion is used for codebook search
     569             :  *---------------------------------------------------------------------*/
     570             : 
     571       46508 : void gain_enc_SQ_fx(
     572             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                 */
     573             :     const Word16 gains_mode[], /* i  : gain bits                                                                                                                Q0*/
     574             :     const Word16 i_subfr,      /* i  : subframe index                                                                                                   Q0*/
     575             :     const Word16 *xn,          /* i  : target vector                                                                                                    Q_xn*/
     576             :     const Word16 *yy1,         /* i  : zero-memory filtered adaptive excitation                                                 Q_xn*/
     577             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation                               Q9*/
     578             :     const Word16 *code,        /* i  : algebraic excitation                                                                                             Q9*/
     579             :     const Word16 Es_pred,      /* i  : predicted scaled innovation energy                                                               Q8*/
     580             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                                                                             Q14*/
     581             :     Word32 *gain_code,         /* o  : quantized codebook gain                                                                                  Q16*/
     582             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                                  Q12*/
     583             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                                                    Q16*/
     584             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, <xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>      Qx*/
     585             :     const Word16 clip_gain,    /* i  : gain pitch clipping flag (1 = clipping)                                                  Q0*/
     586             :     const Word16 Q_xn          /* i  : xn and y1 scaling                                                                                                */
     587             : )
     588             : {
     589             :     Word16 index, nBits_pitch, nBits_code;
     590             :     Word16 gcode0, Ei, gain_code16;
     591             :     Word16 coeff[5], exp_coeff[5];
     592             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
     593             : 
     594             :     Word32 L_tmp, L_tmp1, L_tmp2;
     595             :     Word16 tmp1, expg;
     596             :     Word16 exp1, exp2;
     597             :     Word16 exp_num, exp_den, exp_div, frac_den;
     598             :     Word32 L_frac_num, L_frac_den, L_div;
     599             : #ifndef ISSUE_1867_replace_overflow_libenc
     600             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     601             :     Flag Overflow = 0;
     602             :     move32();
     603             : #endif
     604             : #endif
     605             : 
     606             :     /*-----------------------------------------------------------------*
     607             :      * calculate the rest of the correlation coefficients
     608             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
     609             :      *-----------------------------------------------------------------*/
     610             :     /*g_corr[1] *= -0.5;*/
     611             :     /*g_corr[2] = dotp( y2, y2, L_SUBFR )  + 0.01f;*/
     612             :     /*g_corr[3] = dotp( xn, y2, L_SUBFR )  - 0.02f;*/
     613             :     /*g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f;*/
     614             : 
     615       46508 :     coeff[0] = g_corr[0];
     616       46508 :     move16();
     617       46508 :     exp_coeff[0] = g_corr[1];
     618       46508 :     move16();
     619       46508 :     coeff[1] = g_corr[2];
     620       46508 :     move16(); /* coeff[1] = xn yy1 */
     621       46508 :     exp_coeff[1] = g_corr[3];
     622       46508 :     move16();
     623             : 
     624             :     /* Compute scalar product <y2[],y2[]> */
     625       46508 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
     626       46508 :     move16();
     627       46508 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
     628       46508 :     move16(); /* -18 (y2 Q9) */
     629             : 
     630             :     /* Compute scalar product <xn[],y2[]> */
     631       46508 :     coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) );
     632       46508 :     move16();
     633       46508 :     exp_coeff[3] = add( sub( exp, 9 ), Q_xn );
     634       46508 :     move16(); /* -9 (y2 Q9), (xn y2) */
     635             : 
     636             :     /* Compute scalar product <y1[],y2[]> */
     637       46508 :     coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
     638       46508 :     move16();
     639       46508 :     exp_coeff[4] = add( sub( exp, 9 ), Q_xn );
     640       46508 :     move16(); /* -9 (y2 Q9), (y1 y2) */
     641             : 
     642             :     /*-----------------------------------------------------------------*
     643             :      * calculate the unscaled innovation energy
     644             :      * calculate the predicted gain code
     645             :      * calculate optimal gains
     646             :      *-----------------------------------------------------------------*/
     647             :     /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
     648             :     /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
     649             : 
     650       46508 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
     651       46508 :     exp_inov = sub( exp_code, 18 + 6 );
     652       46508 :     exp_code = sub( exp_code, 30 );
     653             : 
     654             :     /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     655             :     /*----------------------------------------------------------------*
     656             :      * calculate the predicted gain code
     657             :      *----------------------------------------------------------------*/
     658       46508 :     tmp = norm_l( L_tmp );
     659       46508 :     frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
     660       46508 :     tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
     661       46508 :     L_tmp1 = Mpy_32_16( tmp, frac, 12330 );             /* Q13 */
     662       46508 :     Ei = round_fx( L_shl( L_tmp1, 11 ) );               /* Q8 */
     663             : 
     664             :     /* predicted codebook gain */
     665       46508 :     gcode0 = sub( Es_pred, Ei ); /* Q8 */
     666             : 
     667             :     /*---------------------------------------------------------------*
     668             :      * Decode codebook gain and the adaptive excitation low-pass
     669             :      * filtering factor (Finalize computation )
     670             :      *---------------------------------------------------------------*/
     671             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     672       46508 :     L_tmp = Isqrt_lc( L_tmp, &exp_inov );
     673       46508 :     *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
     674             : 
     675             :     /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
     676             :     /*----------------------------------------------------------------*
     677             :      * gcode0 = pow(10.0, gcode0/20)
     678             :      *        = pow(2, 3.321928*gcode0/20)
     679             :      *        = pow(2, 0.166096*gcode0)
     680             :      *----------------------------------------------------------------*/
     681             : 
     682       46508 :     L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26    */
     683       46508 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16            */
     684       46508 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
     685             : 
     686       46508 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
     687             :     /* output of Pow2() will be: */
     688             :     /* 16384 < Pow2() <= 32767   */
     689       46508 :     exp_gcode0 = sub( exp_gcode0, 14 );
     690             : 
     691             : 
     692             :     /*tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]);
     693             :     tmp2 = g_corr[1]/tmp1;
     694             :     tmp1 = g_corr[3]/tmp1;
     695             : 
     696             :     *gain_pit =  (g_corr[2]*tmp2) - (g_corr[4]*tmp1);
     697             :     *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2);*/
     698             : 
     699             :     /*    *gain_pit =  (g_corr[2]*tmp2) - (g_corr[4]*tmp3);
     700             :                   =  ((g_corr[1]*g_corr[2]) - (g_corr[3]*g_corr[4]))/tmp1;*/
     701             : 
     702             :     /*     *gain_code = (g_corr[0]*tmp3) - (g_corr[4]*tmp2);
     703             :                    = ((g_corr[3]*g_corr[0]) - (g_corr[1]*g_corr[4]))/tmp1;*/
     704             : 
     705       46508 :     L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
     706       46508 :     exp1 = add( exp_coeff[0], exp_coeff[2] );
     707             : 
     708             : #ifdef ISSUE_1867_replace_overflow_libenc
     709       46508 :     L_tmp2 = L_mult_sat( coeff[4], coeff[4] ); /*Q31*/
     710             : #else
     711             :     L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow );                                    /*Q31*/
     712             : #endif
     713       46508 :     exp2 = add( exp_coeff[4], exp_coeff[4] );
     714             : 
     715       46508 :     IF( GT_16( exp1, exp2 ) )
     716             :     {
     717       46438 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     718       46438 :         exp_den = exp1;
     719       46438 :         move16();
     720             :     }
     721             :     ELSE
     722             :     {
     723          70 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     724          70 :         exp_den = exp2;
     725          70 :         move16();
     726             :     }
     727       46508 :     L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
     728             : 
     729       46508 :     frac_den = extract_h( L_frac_den );  /* Q15 */
     730       46508 :     frac_den = s_max( frac_den, 1 );     /* Q15 */
     731       46508 :     L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
     732       46508 :     exp = norm_l( L_frac_den );
     733       46508 :     tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
     734             : 
     735             : 
     736       46508 :     L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/
     737       46508 :     exp1 = add( exp_coeff[3], exp_coeff[4] );
     738             : 
     739       46508 :     L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/
     740       46508 :     exp2 = add( exp_coeff[1], exp_coeff[2] );
     741             : 
     742       46508 :     IF( GT_16( exp1, exp2 ) )
     743             :     {
     744        1265 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     745        1265 :         exp_num = exp1;
     746        1265 :         move16();
     747             :     }
     748             :     ELSE
     749             :     {
     750       45243 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     751       45243 :         exp_num = exp2;
     752       45243 :         move16();
     753             :     }
     754             : #ifdef ISSUE_1867_replace_overflow_libenc
     755       46508 :     L_frac_num = L_sub_sat( L_tmp2, L_tmp1 ); /*Q31*/
     756             : #else
     757             :     L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow );                                     /*Q31*/
     758             : #endif
     759             : 
     760       46508 :     L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     761       46508 :     exp_div = sub( exp_num, exp_den );
     762             : 
     763             : #ifdef ISSUE_1867_replace_overflow_libenc
     764       46508 :     *gain_pit = round_fx_sat( L_shl_sat( L_div, add( exp, exp_div ) ) ); /*Q14*/
     765             : #else
     766             :     *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
     767             : #endif
     768             : 
     769             : #ifdef FIX_1978_SAT_MISSING_IN_GAIN_ENC
     770       46508 :     L_tmp1 = L_mult_sat( coeff[1], coeff[4] ); /*Q31*/
     771             : #else
     772             :     L_tmp1 = L_mult( coeff[1], coeff[4] );                                                 /*Q31*/
     773             : #endif
     774       46508 :     exp1 = add( exp_coeff[1], exp_coeff[4] );
     775             : 
     776             : #ifdef FIX_1978_SAT_MISSING_IN_GAIN_ENC
     777       46508 :     L_tmp2 = L_mult_sat( coeff[0], coeff[3] ); /*Q31*/
     778             : #else
     779             :     L_tmp2 = L_mult( coeff[0], coeff[3] );                                                 /*Q31*/
     780             : #endif
     781       46508 :     exp2 = add( exp_coeff[0], exp_coeff[3] );
     782             : 
     783       46508 :     IF( GT_16( exp1, exp2 ) )
     784             :     {
     785        1399 :         L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
     786        1399 :         exp_num = exp1;
     787        1399 :         move16();
     788             :     }
     789             :     ELSE
     790             :     {
     791       45109 :         L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
     792       45109 :         exp_num = exp2;
     793       45109 :         move16();
     794             :     }
     795             : #ifdef ISSUE_1867_replace_overflow_libenc
     796       46508 :     L_frac_num = L_sub_sat( L_tmp2, L_tmp1 ); /*Q31*/
     797             : #else
     798             :     L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow );                                     /*Q31*/
     799             : #endif
     800             : 
     801       46508 :     L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
     802       46508 :     exp_div = sub( exp_num, exp_den );
     803             : 
     804       46508 :     *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) );
     805       46508 :     move32(); /*Q16*/
     806             : 
     807       46508 :     *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) );
     808             : 
     809             :     /*-----------------------------------------------------------------*
     810             :      * limit the pitch gain searching range (if indicated by clip_gain)
     811             :      *-----------------------------------------------------------------*/
     812             : 
     813       46508 :     test();
     814       46508 :     test();
     815       46508 :     IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) )
     816             :     {
     817          29 :         *gain_pit = 15565; /* 0.95 in Q14 */
     818          29 :         move16();
     819             :     }
     820       46479 :     ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) )
     821             :     {
     822        1541 :         *gain_pit = 10650; /* 0.65 in Q14 */
     823        1541 :         move16();
     824             :     }
     825             : 
     826             :     /*-----------------------------------------------------------------*
     827             :      * search for the best quantized values
     828             :      *-----------------------------------------------------------------*/
     829             : 
     830       46508 :     nBits_pitch = gains_mode[i_subfr >> 6];
     831       46508 :     move16();
     832             : 
     833             :     /* set number of bits for two SQs */
     834       46508 :     nBits_code = shr( add( nBits_pitch, 1 ), 1 );
     835       46508 :     nBits_pitch = shr( nBits_pitch, 1 );
     836             : 
     837             :     /* gain_pit Q */
     838             :     /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/                     /* set quantization step */
     839       46508 :     tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */
     840             : 
     841       46508 :     index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); // Q0
     842       46508 :     push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch );
     843             : 
     844             :     /* gain_code Q */
     845             :     /* *gain_code /= gcode0; */
     846       46508 :     IF( gcode0 != 0 )
     847             :     {
     848       46508 :         tmp = div_s( 16384, gcode0 );                       /*Q15*/
     849       46508 :         L_tmp = Mult_32_16( *gain_code, tmp );              /*Q16*/
     850       46508 :         *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
     851       46508 :         move32();
     852             :     }
     853             : 
     854       46508 :     index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg );
     855       46508 :     push_indice( hBstr, IND_GAIN_CODE, index, nBits_code );
     856       46508 :     L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
     857       46508 :     *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) );
     858       46508 :     move32(); /*Q16*/
     859             : 
     860             :     /* *norm_gain_code = *gain_code / *gain_inov; */
     861       46508 :     exp = sub( norm_s( *gain_inov ), 1 );
     862       46508 :     exp = s_max( exp, 0 );
     863             : 
     864       46508 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
     865       46508 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
     866       46508 :     move32();
     867             : 
     868       46508 :     return;
     869             : }
     870             : /*-------------------------------------------------------------------*
     871             :  * gain_enc_gaus()
     872             :  *
     873             :  * Quantization of gain for Gaussian codebook
     874             :  *-------------------------------------------------------------------*/
     875           0 : Word16 gain_enc_gaus_fx(                           /* o  : Return index of quantization     */
     876             :                          Word32 *gain,             /* i/o: Code gain to quantize            Q16*/
     877             :                          const Word16 bits,        /* i  : number of bits to quantize       Q0*/
     878             :                          const Word16 lowBound,    /* i  : lower bound of quantizer (dB)        Q8*/
     879             :                          const Word16 stepSize,    /* i  : Step size choice                                     Q14*/
     880             :                          const Word16 inv_stepSize /* i  : Step size choice                                     Q15*/
     881             : )
     882             : {
     883             :     Word16 index, exp_gain, frac_gain, wtmp;
     884             :     Word16 enr_q, wenr;
     885             :     Word32 Ltmp, enr;
     886             : #ifndef ISSUE_1867_replace_overflow_libenc
     887             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     888             :     Flag Overflow = 0;
     889             :     move32();
     890             : #endif
     891             : #endif
     892             :     /*enr = 20.0 * log10(*gain + 0.001)     codebook gain in dB  */
     893           0 :     exp_gain = norm_l( *gain );
     894           0 :     frac_gain = Log2_norm_lc( L_shl( *gain, exp_gain ) );
     895           0 :     exp_gain = sub( 30 - 16, exp_gain );
     896             : 
     897           0 :     enr = Mpy_32_16( exp_gain, frac_gain, LG10 ); /* Output in Q13 */
     898           0 :     wenr = extract_h( L_shl( enr, 8 + 3 ) );
     899             : 
     900             :     /*----------------------------------------------------------------*
     901             :      * Quantize linearly the log E
     902             :      *----------------------------------------------------------------*/
     903             : 
     904           0 :     wtmp = sub( wenr, lowBound ); /* Q8 */
     905             : 
     906           0 :     index = extract_l( L_shr( L_mac( 8388608, wtmp, inv_stepSize ), 16 + 8 ) ); // Q0
     907             : 
     908             :     /* index [0 (1<<bits)-1] */
     909           0 :     index = s_min( index, sub( shl( 1, bits ), 1 ) ); // Q0
     910           0 :     index = s_max( index, 0 );
     911             : 
     912           0 :     Ltmp = L_mac( L_shl( lowBound, 7 ), index, stepSize );
     913           0 :     enr_q = round_fx( L_shl( Ltmp, 16 - 7 ) ); /* enr_q Q8 */
     914             : 
     915             :     /* gain = (float)pow( 10.0f, enr/20.0f )   quantized codebook gain */
     916           0 :     enr = L_mult( enr_q, 21772 ); /* 0.166096 in Q17 -> Q26 */
     917           0 :     enr = L_shr( enr, 10 );       /*Q26->Q16*/
     918           0 :     frac_gain = L_Extract_lc( enr, &exp_gain );
     919             : 
     920           0 :     Ltmp = Pow2( 14, frac_gain );   /* Put 14 as exponent */
     921           0 :     exp_gain = sub( exp_gain, 14 ); /* Retreive exponent of wtmp */
     922             : #ifdef ISSUE_1867_replace_overflow_libenc
     923           0 :     *gain = L_shl_sat( Ltmp, add( 16, exp_gain ) );
     924             : #else
     925             :     *gain = L_shl_o( Ltmp, add( 16, exp_gain ), &Overflow );
     926             : #endif
     927           0 :     move32(); /*Q16*/
     928             : 
     929           0 :     return index;
     930             : }
     931             : /*-----------------------------------------------------------------*
     932             :  * gain_enc_tc()
     933             :  *
     934             :  * Search and quantization of gain_code for subframes (in the
     935             :  * beginning of frame) without pulses in TC - 3b coding.
     936             :  * In this case:
     937             :  * - gain_pit = 0
     938             :  * - gain_code - scalar quantization (no prediciton history used)
     939             :  *-----------------------------------------------------------------*/
     940       20393 : void gain_enc_tc_fx(
     941             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                   */
     942             :     const Word16 gains_mode[], /* i  : gain bits                                          Q0*/
     943             :     const Word16 i_subfr,      /* i  : subframe index                                     Q0*/
     944             :     const Word16 xn_fx[],      /* i  : target vector                                      Q_xn*/
     945             :     const Word16 y2_fx[],      /* i  : zero-memory filtered algebraic codebook excitation Q_xn*/
     946             :     const Word16 code_fx[],    /* i  : algebraic excitation                               Q9*/
     947             :     const Word16 Es_pred_fx,   /* i  : predicted scaled innovation energy                 Q8*/
     948             :     Word16 *gain_pit_fx,       /* o  : Pitch gain / Quantized pitch gain                  Q14*/
     949             :     Word32 *gain_code_fx,      /* o  : quantized codebook gain                            Q16*/
     950             :     Word16 *gain_inov_fx,      /* o  : innovation gain                                    Q12*/
     951             :     Word32 *norm_gain_code_fx, /* o  : norm. gain of the codebook excitation              Q16*/
     952             :     const Word16 Q_xn          /* i  : xn and y1 scaling                                                                  */
     953             : )
     954             : {
     955       20393 :     Word16 i, index = 0, nBits, num, den, exp_num, exp_den;
     956             :     Word16 Ei_fx, g_code_fx, gcode0_fx;
     957             :     Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac, tmp16;
     958             :     Word32 L_tmp, L_tmp1;
     959       20393 :     Word16 wgain_code = 0, gain_code16;
     960       20393 :     *gain_pit_fx = 0;
     961       20393 :     move16();
     962       20393 :     move16();
     963       20393 :     move16();
     964             : 
     965             :     /*----------------------------------------------------------------*
     966             :      * get number of bits for gain quantization
     967             :      *----------------------------------------------------------------*/
     968       20393 :     nBits = gains_mode[shr( i_subfr, 6 )];
     969             : 
     970             :     /*----------------------------------------------------------------*
     971             :      * find the code pitch (for current subframe)
     972             :      *----------------------------------------------------------------*/
     973             : 
     974             :     /**gain_code = dotp( xn, y2, L_SUBFR )/( dotp( y2, y2, L_SUBFR ) + 0.01f );*/
     975             :     /* Compute scalar product <y2[],y2[]> */
     976       20393 :     L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
     977       20393 :     exp_den = norm_l( L_tmp );
     978       20393 :     den = extract_h( L_shl( L_tmp, exp_den ) );
     979       20393 :     exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
     980             : 
     981             :     /* Compute scalar product <xn[],y2[]> */
     982       20393 :     L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9)  */
     983       20393 :     exp_num = sub( norm_l( L_tmp1 ), 1 );
     984       20393 :     num = extract_h( L_shl( L_tmp1, exp_num ) );
     985       20393 :     exp_num = sub( add( exp_num, 8 ), Q_xn );
     986             : 
     987       20393 :     tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
     988       20393 :     num = abs_s( num );
     989             : 
     990             :     /*----------------------------------------------------------------*
     991             :      * compute gain = xy/yy
     992             :      *----------------------------------------------------------------*/
     993       20393 :     g_code_fx = div_s( num, den );
     994             : 
     995       20393 :     i = sub( exp_num, exp_den );             /* Gain_trans in Q7 */
     996       20393 :     g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */
     997       20393 :     *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i );
     998       20393 :     move32();
     999             : 
    1000             :     /*----------------------------------------------------------------*
    1001             :      * calculate the predicted gain code
    1002             :      * decode codebook gain
    1003             :      *----------------------------------------------------------------*/
    1004             : 
    1005       20393 :     *gain_pit_fx = 0;
    1006       20393 :     move16();
    1007             : 
    1008             :     /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
    1009             :      *gain_inov = 1.0f / (float)sqrt( Ecode );*/
    1010             : 
    1011       20393 :     L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
    1012       20393 :     expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
    1013       20393 :     expg2 = expg;
    1014       20393 :     move16();
    1015       20393 :     L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
    1016       20393 :     move32();
    1017       20393 :     L_tmp = Isqrt_lc( L_tmp, &expg );
    1018             : 
    1019       20393 :     *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
    1020       20393 :     move16(); /* gain_inov in Q12 */
    1021             : 
    1022             :     /*Ei = 10 * (float)log10( Ecode );*/
    1023       20393 :     e_tmp = norm_l( L_tmp1 );
    1024       20393 :     f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
    1025       20393 :     e_tmp = sub( expg2, add( 1, e_tmp ) );
    1026       20393 :     L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
    1027       20393 :     Ei_fx = round_fx( L_shl( L_tmp1, 11 ) );             /* Q8 */
    1028             :     /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
    1029       20393 :     gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
    1030             :     /*-----------------------------------------------------------------*
    1031             :      * gcode0 = pow(10.0, gcode0/20)
    1032             :      * = pow(2, 3.321928*gcode0/20)
    1033             :      * = pow(2, 0.166096*gcode0)
    1034             :      *-----------------------------------------------------------------*/
    1035       20393 :     L_tmp = L_mult( gcode0_fx, 21771 );        /* *0.166096 in Q17 -> Q26 */
    1036       20393 :     L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16 */
    1037       20393 :     frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1038       20393 :     gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1039       20393 :     exp_gcode0 = sub( exp_gcode0, 14 );
    1040       20393 :     IF( GT_16( nBits, 3 ) )
    1041             :     {
    1042             :         /*g_code = *gain_code / gcode0;*/
    1043        1457 :         IF( gcode0_fx != 0 )
    1044             :         {
    1045        1457 :             tmp16 = div_s( 16384, gcode0_fx );                     /*Q15*/
    1046        1457 :             L_tmp = Mult_32_16( *gain_code_fx, tmp16 );            /*Q16*/
    1047        1457 :             *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
    1048        1457 :             move32();
    1049             :         }
    1050             :         ELSE
    1051             :         {
    1052           0 :             *gain_code_fx = MAX_32;
    1053           0 :             move32();
    1054             :         }
    1055             : 
    1056             :         /*index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits );*/
    1057        1457 :         index = gain_quant_fx( gain_code_fx, &gain_code16, LG10_G_CODE_MIN_TC_Q14, LG10_G_CODE_MAX_TC_Q13, nBits, &expg );
    1058             : 
    1059             :         /**gain_code = g_code * gcode0;*/
    1060        1457 :         L_tmp = L_mult( gain_code16, gcode0_fx );                           /*Q0*Q0 -> Q1*/
    1061        1457 :         *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
    1062        1457 :         move32();
    1063             : 
    1064        1457 :         push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1065             :     }
    1066             :     ELSE
    1067             :     {
    1068       18936 :         index = N_GAIN_CODE_TC - 1;
    1069       18936 :         move16();
    1070       63617 :         FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
    1071             :         {
    1072       62741 :             L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
    1073       62741 :             L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) );                /*    Q14 -> Q16 */
    1074             : 
    1075       62741 :             IF( LT_32( *gain_code_fx, L_tmp ) )
    1076             :             {
    1077       18060 :                 index = i;
    1078       18060 :                 move16();
    1079       18060 :                 BREAK;
    1080             :             }
    1081             :         }
    1082             :         /*----------------------------------------------------------------*
    1083             :          * 3-bit -> 2-bit encoding
    1084             :          *----------------------------------------------------------------*/
    1085       18936 :         IF( EQ_16( nBits, 2 ) )
    1086             :         {
    1087             :             /* 2-bit -> 3-bit decoding */
    1088           0 :             index = shr( index, 1 );
    1089           0 :             wgain_code = tbl_gain_code_tc_fx[shl( index, 1 )];
    1090           0 :             move16();
    1091             :             /**gain_code *= gcode0;*/
    1092           0 :             L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
    1093           0 :             *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) );
    1094           0 :             move32(); /* Q14 -> Q16 */
    1095           0 :             push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1096             :         }
    1097             :         ELSE /* nBits == 3 */
    1098             :         {
    1099       18936 :             wgain_code = tbl_gain_code_tc_fx[index];
    1100       18936 :             move16();
    1101             :             /**gain_code *= gcode0;*/
    1102       18936 :             L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
    1103       18936 :             *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
    1104       18936 :             move32(); /* Q14 -> Q16 */
    1105       18936 :             push_indice( hBstr, IND_GAIN_CODE, index, nBits );
    1106             :         }
    1107             :     }
    1108             : 
    1109             :     /*-----------------------------------------------------------------*
    1110             :      * decode normalized codebook gain
    1111             :      *-----------------------------------------------------------------*/
    1112             :     /**norm_gain_code = *gain_code / *gain_inov;*/
    1113       20393 :     expg = sub( norm_s( *gain_inov_fx ), 1 );
    1114       20393 :     expg = s_max( expg, 0 );
    1115             : 
    1116       20393 :     tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
    1117       20393 :     *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q16
    1118       20393 :     move32();
    1119       20393 :     return;
    1120             : }
    1121             : /*-----------------------------------------------------------------*
    1122             :  * Find_Opt_gainQ_fx()
    1123             :  *
    1124             :  * Find the best quantizer
    1125             :  *-----------------------------------------------------------------*/
    1126      541572 : static Word16 Find_Opt_gainQ_fx(
    1127             :     Word16 *coeff, /* exp(exp_coeff) */
    1128             :     Word16 *exp_coeff,
    1129             :     Word16 *gain_pit,  /* Q14 */
    1130             :     Word32 *gain_code, /* Q16 */
    1131             :     Word16 gcode0,     /* exp(exp_gcode0) */
    1132             :     Word16 exp_gcode0,
    1133             :     const Word16 *cdbk, /* i  : Codebook used   Q14*/
    1134             :     const Word16 size   /* i  : size of Codebook used   Q0*/
    1135             : )
    1136             : {
    1137             :     Word16 index, i, j;
    1138             :     const Word16 *p;
    1139             :     Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
    1140             :     Word32 dist_min;
    1141             :     Word16 coeff_lo[5];
    1142             :     Word16 exp_max[5];
    1143             :     Word16 exp_code, e_max;
    1144             :     Word32 L_tmp, L_tmp1;
    1145             : #ifndef ISSUE_1867_replace_overflow_libenc
    1146             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1147             :     Flag Overflow = 0;
    1148             :     move32();
    1149             : #endif
    1150             : #endif
    1151             : 
    1152             : 
    1153             :     /*----------------------------------------------------------------*
    1154             :      * Find the best quantizer
    1155             :      * ~~~~~~~~~~~~~~~~~~~~~~~
    1156             :      * Before doing the computation we need to align exponents of coeff[]
    1157             :      * to be sure to have the maximum precision.
    1158             :      *
    1159             :      * In the table the pitch gains are in Q14, the code gains are in Q9 and
    1160             :      * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
    1161             :      * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
    1162             :      * we divide by 2^15.
    1163             :      * Considering all the scaling above we have:
    1164             :      *
    1165             :      *   exp_code = exp_gcode0-9+15 = exp_gcode0+6
    1166             :      *
    1167             :      *   g_pitch*g_pitch  = -14-14+15
    1168             :      *   g_pitch          = -14
    1169             :      *   g_code*g_code    = (2*exp_code)+15
    1170             :      *   g_code           = exp_code
    1171             :      *   g_pitch*g_code   = -14 + exp_code +15
    1172             :      *
    1173             :      *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13
    1174             :      *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14
    1175             :      *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
    1176             :      *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
    1177             :      *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
    1178             :      *----------------------------------------------------------------*/
    1179             : 
    1180      541572 :     exp_code = add( exp_gcode0, 6 );
    1181             : 
    1182      541572 :     exp_max[0] = sub( exp_coeff[0], 13 );
    1183      541572 :     move16();
    1184      541572 :     exp_max[1] = sub( exp_coeff[1], 14 );
    1185      541572 :     move16();
    1186      541572 :     exp_max[2] = add( exp_coeff[2], add( 15, shl( exp_code, 1 ) ) );
    1187      541572 :     move16();
    1188      541572 :     exp_max[3] = add( exp_coeff[3], exp_code );
    1189      541572 :     move16();
    1190      541572 :     exp_max[4] = add( exp_coeff[4], add( 1, exp_code ) );
    1191      541572 :     move16();
    1192             : 
    1193             :     /* Find maximum exponant */
    1194      541572 :     e_max = exp_max[0];
    1195      541572 :     move16();
    1196     2707860 :     FOR( i = 1; i < 5; i++ )
    1197             :     {
    1198     2166288 :         e_max = s_max( exp_max[i], e_max );
    1199             :     }
    1200             : 
    1201             :     /* align coeff[] and save in special 32 bit double precision */
    1202     3249432 :     FOR( i = 0; i < 5; i++ )
    1203             :     {
    1204     2707860 :         j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
    1205     2707860 :         L_tmp = L_deposit_h( coeff[i] );
    1206     2707860 :         L_tmp = L_shr( L_tmp, j );
    1207     2707860 :         L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
    1208     2707860 :         coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
    1209     2707860 :         move16();
    1210             :     }
    1211             : 
    1212             :     /* searching of codebook */
    1213      541572 :     p = cdbk; // Q14
    1214      541572 :     move16();
    1215      541572 :     dist_min = L_deposit_h( MAX_16 );
    1216      541572 :     index = 0;
    1217      541572 :     move16();
    1218    35546928 :     FOR( i = 0; i < size; i++ )
    1219             :     {
    1220    35005356 :         g_pitch = *p++;
    1221    35005356 :         move16();
    1222    35005356 :         g_code = *p++;
    1223    35005356 :         move16();
    1224             : 
    1225    35005356 :         g_code = mult_r( g_code, gcode0 );     // exp_gcode - 1
    1226    35005356 :         g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
    1227    35005356 :         g_pit_cod = mult_r( g_code, g_pitch );
    1228    35005356 :         L_tmp = L_mult( g_code, g_code );
    1229    35005356 :         g2_code_lo = L_Extract_lc( L_tmp, &g2_code );
    1230             : 
    1231    35005356 :         L_tmp = L_mult( coeff[2], g2_code_lo );
    1232    35005356 :         L_tmp = L_shr( L_tmp, 3 );
    1233    35005356 :         L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
    1234    35005356 :         L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
    1235    35005356 :         L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
    1236    35005356 :         L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
    1237    35005356 :         L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
    1238    35005356 :         L_tmp = L_shr( L_tmp, 12 );
    1239    35005356 :         L_tmp = L_mac( L_tmp, coeff[0], g2_pitch );  /* 15 - coeff_exp + 13 - 1 */
    1240    35005356 :         L_tmp = L_mac( L_tmp, coeff[1], g_pitch );   /* 15 - coeff_exp + 13 - 1 */
    1241    35005356 :         L_tmp = L_mac( L_tmp, coeff[2], g2_code );   /* 15 - coeff_exp + 13 - 1 */
    1242    35005356 :         L_tmp = L_mac( L_tmp, coeff[3], g_code );    /* 15 - coeff_exp + 13 - 1 */
    1243    35005356 :         L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
    1244             : 
    1245             : #ifdef ISSUE_1867_replace_overflow_libenc
    1246    35005356 :         L_tmp1 = L_sub_sat( L_tmp, dist_min );
    1247             : #else
    1248             :         L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
    1249             : #endif
    1250    35005356 :         if ( L_tmp1 < 0 )
    1251             :         {
    1252     6790698 :             index = i;
    1253     6790698 :             move16();
    1254             :         }
    1255    35005356 :         dist_min = L_min( L_tmp, dist_min );
    1256             :     }
    1257             : 
    1258      541572 :     p = &cdbk[add( index, index )]; // Q14
    1259      541572 :     move16();
    1260             : 
    1261      541572 :     *gain_pit = *p++; /* selected pitch gain in Q14 */
    1262      541572 :     move16();
    1263      541572 :     g_code = *p++; /* selected  code gain in Q9 */
    1264      541572 :     move16();
    1265             : 
    1266      541572 :     L_tmp = L_mult( g_code, gcode0 );                 /* Q9*Q0 -> Q10 */
    1267      541572 :     L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16 */
    1268      541572 :     *gain_code = L_tmp;                               /* gain of code in Q16 */
    1269      541572 :     move16();
    1270      541572 :     return index;
    1271             : }
    1272             : /*---------------------------------------------------------------------*
    1273             :  * gain_enc_lbr()
    1274             :  *
    1275             :  * Quantization of pitch and codebook gains without prediction (memory-less)
    1276             :  * in ACELP at 6.6 and 7.5 kbps
    1277             :  * - the gain codebooks and gain estimation constants are different in each subframe
    1278             :  * - the estimated gain, gcode0, is first determined based on
    1279             :  *   classification and/or previous quantized gains (from previous subframes in the current frame)
    1280             :  * - a correction factor gamma = g_code / gcode0 is then vector quantized
    1281             :  *   along with gain_pit
    1282             :  * - the mean-squared error criterion is used for codebook search
    1283             :  *---------------------------------------------------------------------*/
    1284             : 
    1285       17652 : void gain_enc_lbr_fx(
    1286             :     BSTR_ENC_HANDLE hBstr,     /* i/o: encoder bitstream handle                                                                                  */
    1287             :     const Word16 gains_mode[], /* i  : gain bits                                                       Q0*/
    1288             :     const Word16 coder_type,   /* i  : coding type                                                     Q0*/
    1289             :     const Word16 i_subfr,      /* i  : subframe index                                                  Q0*/
    1290             :     const Word16 *xn,          /* i  : target vector                                                   Q_xn*/
    1291             :     const Word16 *y1,          /* i  : zero-memory filtered adaptive excitation                        Q_xn*/
    1292             :     const Word16 Q_xn,         /* i  : xn and y1 format                                                  */
    1293             :     const Word16 *y2,          /* i  : zero-memory filtered algebraic codebook excitation              Q9*/
    1294             :     const Word16 *code,        /* i  : algebraic excitation                                            Q9*/
    1295             :     Word16 *gain_pit,          /* o  : quantized pitch gain                                            Q14*/
    1296             :     Word32 *gain_code,         /* o  : quantized codebook gain                                         Q16*/
    1297             :     Word16 *gain_inov,         /* o  : gain of the innovation (used for normalization)                 Q12*/
    1298             :     Word32 *norm_gain_code,    /* o  : norm. gain of the codebook excitation                           Q16*/
    1299             :     Word16 *g_corr,            /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> mant/exp*/
    1300             :     Word32 gc_mem[],           /* i/o: gain_code from previous subframes                               Q16*/
    1301             :     Word16 gp_mem[],           /* i/o: gain_pitch from previous subframes                              Q14*/
    1302             :     const Word16 clip_gain,    /* i  : gain pitch clipping flag (1 = clipping)                                             Q0*/
    1303             :     const Word16 L_subfr       /* i  : subframe length                                                                                             Q0*/
    1304             :     ,
    1305             :     const Word16 element_mode /* i  : mode element                                                                                                 Q0*/
    1306             : )
    1307             : {
    1308             : 
    1309       17652 :     Word16 index = 0, size, nBits, n_pred, ctype;
    1310       17652 :     const Word16 *b, *cdbk = 0;
    1311             :     Word16 gcode0, aux[10];
    1312             :     Word16 coeff[5], exp_coeff[5];
    1313             :     Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf;
    1314             :     Word32 L_tmp, L_tmp1, L_inov;
    1315       17652 :     move16();
    1316       17652 :     move16();
    1317             : 
    1318       17652 :     L_subfr_sf = 6;
    1319       17652 :     move16();
    1320       17652 :     if ( GT_16( L_subfr, L_SUBFR ) )
    1321             :     {
    1322        4092 :         L_subfr_sf = 7;
    1323        4092 :         move16();
    1324             :     }
    1325             :     /*-----------------------------------------------------------------*
    1326             :      * calculate the rest of the correlation coefficients
    1327             :      * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>, c5* = <xn,xn>
    1328             :      * c5* - not necessary to calculate
    1329             :      *-----------------------------------------------------------------*/
    1330             : 
    1331       17652 :     coeff[0] = g_corr[0];
    1332       17652 :     move16();
    1333       17652 :     exp_coeff[0] = g_corr[1];
    1334       17652 :     move16();
    1335       17652 :     coeff[1] = negate( g_corr[2] );
    1336       17652 :     move16(); /* coeff[1] = -2 xn yy1 */
    1337       17652 :     exp_coeff[1] = add( g_corr[3], 1 );
    1338       17652 :     move16();
    1339             : 
    1340             :     /* Compute scalar product <y2[],y2[]> */
    1341       17652 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) );
    1342       17652 :     move16();
    1343       17652 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
    1344       17652 :     move16();
    1345             : 
    1346             :     /* Compute scalar product -2*<xn[],y2[]> */
    1347             : 
    1348       17652 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) );
    1349       17652 :     move16();
    1350       17652 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
    1351       17652 :     move16();
    1352             : 
    1353             :     /* Compute scalar product 2*<y1[],y2[]> */
    1354             : 
    1355       17652 :     coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) );
    1356       17652 :     move16();
    1357       17652 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
    1358       17652 :     move16();
    1359             : 
    1360             :     /*g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F;*/
    1361             : 
    1362             :     /*Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
    1363             :      *gain_inov = 1.0f / (float)sqrt(Ecode);*/
    1364       17652 :     L_tmp = Dot_product12( code, code, L_subfr, &exp_code );
    1365       17652 :     L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */
    1366       17652 :     move32();
    1367             :     /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */
    1368             :     /* output gain_inov*/
    1369       17652 :     exp_inov = sub( exp_code, add( 18, L_subfr_sf ) );
    1370       17652 :     L_inov = Isqrt_lc( L_inov, &exp_inov );
    1371       17652 :     *gain_inov = extract_h( L_shl_sat( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
    1372       17652 :     move16();
    1373             : 
    1374             : 
    1375             :     /*-----------------------------------------------------------------*
    1376             :      * select the codebook, size and number of bits
    1377             :      * set the gains searching range
    1378             :      *-----------------------------------------------------------------*/
    1379             : 
    1380       17652 :     nBits = gains_mode[shr( i_subfr, L_subfr_sf )];
    1381       17652 :     move16();
    1382       17652 :     size = shl( 1, nBits );
    1383             : 
    1384       17652 :     ctype = shl( sub( coder_type, 1 ), 1 );
    1385             : 
    1386             :     /*-----------------------------------------------------------------*
    1387             :      * calculate prediction of gcode
    1388             :      * search for the best codeword
    1389             :      *-----------------------------------------------------------------*/
    1390       17652 :     test();
    1391       17652 :     IF( i_subfr == 0 )
    1392             :     {
    1393        5436 :         b = b_1sfr_fx; // Q12
    1394        5436 :         move16();
    1395        5436 :         n_pred = 2;
    1396        5436 :         move16();
    1397             : 
    1398        5436 :         SWITCH( nBits )
    1399             :         {
    1400        2189 :             case 8:
    1401             :             {
    1402        2189 :                 cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */
    1403        2189 :                 if ( EQ_16( clip_gain, 1 ) )
    1404             :                 {
    1405           0 :                     size = sub( size, 60 );
    1406             :                 }
    1407        2189 :                 BREAK;
    1408             :             }
    1409         440 :             case 7:
    1410             :             {
    1411         440 :                 cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */
    1412         440 :                 if ( EQ_16( clip_gain, 1 ) )
    1413             :                 {
    1414           0 :                     size = sub( size, 27 );
    1415             :                 }
    1416         440 :                 BREAK;
    1417             :             }
    1418        2807 :             case 6:
    1419             :             {
    1420        2807 :                 cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */
    1421        2807 :                 if ( EQ_16( clip_gain, 1 ) )
    1422             :                 {
    1423           0 :                     size = sub( size, 10 );
    1424             :                 }
    1425        2807 :                 BREAK;
    1426             :             }
    1427             :         }
    1428             : 
    1429             :         /* calculate predicted gain */
    1430        5436 :         aux[0] = 4096; /* 1 in Q12 */
    1431        5436 :         move16();
    1432        5436 :         aux[1] = shl( ctype, 12 );
    1433        5436 :         move16();
    1434             : 
    1435             :         /*     gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
    1436             :                gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
    1437             :                gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
    1438             : 
    1439        5436 :         IF( element_mode > EVS_MONO )
    1440             :         {
    1441             :             // Ecode = (Ecode / L_subfr)
    1442        5436 :             L_tmp = L_shr( L_tmp, L_subfr_sf );                     // Q19 + (Q30-exp_code)
    1443             :                                                                     /* Calculation for log10(Ecode) exponent for applying log10 = Q31 - q = Q31 - Q19 - Q30 + exp_code = exp_code - Q18*/
    1444        5436 :             L_tmp = BASOP_Util_Log10( L_tmp, sub( exp_code, 18 ) ); // new q = Q25
    1445        5436 :             exp = norm_l( L_tmp );
    1446        5436 :             L_tmp = L_shl( L_tmp, exp ); // Q25 + exp
    1447             :             // 10 in Q27 , ( 10 * log10( Ecode ) )
    1448        5436 :             L_tmp1 = Mpy_32_32( L_tmp, 1342177280 ); // Q25 + exp + 1 + Q27 - 32 = Q21 + exp
    1449        5436 :             L_tmp1 = L_shr( L_tmp1, add( 7, exp ) ); // Q21 + exp - 7 - exp = Q14
    1450             :         }
    1451             :         ELSE
    1452             :         {
    1453           0 :             exp_code = sub( exp_code, 18 + 6 + 1 );
    1454           0 :             exp = norm_l( L_tmp );
    1455           0 :             frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
    1456           0 :             exp = sub( exp_code, exp );
    1457           0 :             L_tmp1 = Mpy_32_16( exp, frac, 24660 ); /* Q14 */ /* 10*log10(2) in Q13*/
    1458             :         }
    1459        5436 :         L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
    1460        5436 :         L_tmp = Mult_32_16( L_tmp, 320 );      /*Q14, 20 in Q4*/
    1461        5436 :         L_tmp = L_sub( L_tmp, L_tmp1 );        /*Q14*/
    1462             : 
    1463        5436 :         gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
    1464             : 
    1465             :         /*-----------------------------------------------------------------*
    1466             :          * gcode0 = pow(10.0, gcode0/20)
    1467             :          *        = pow(2, 3.321928*gcode0/20)
    1468             :          *        = pow(2, 0.166096*gcode0)
    1469             :          *-----------------------------------------------------------------*/
    1470             : 
    1471        5436 :         L_tmp = L_mult( gcode0, 21771 );           /* *0.166096 in Q17 -> Q26 */
    1472        5436 :         L_tmp = L_shr( L_tmp, 10 );                /* From Q26 to Q16 */
    1473        5436 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1474             : 
    1475        5436 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1476             :         /* output of Pow2() will be: */
    1477             :         /* 16384 < Pow2() <= 32767 */
    1478        5436 :         exp_gcode0 = sub( exp_gcode0, 14 );
    1479        5436 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    1480             : 
    1481        5436 :         gc_mem[0] = *gain_code;
    1482        5436 :         move16(); /*Q16*/
    1483        5436 :         gp_mem[0] = *gain_pit;
    1484        5436 :         move16(); /*Q14*/
    1485             :     }
    1486       12216 :     ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
    1487             :     {
    1488        5436 :         b = b_2sfr_fx;
    1489        5436 :         move16();
    1490        5436 :         n_pred = 4;
    1491        5436 :         move16();
    1492             : 
    1493        5436 :         switch ( nBits )
    1494             :         {
    1495        2187 :             case 7:
    1496             :             {
    1497        2187 :                 cdbk = gp_gamma_2sfr_7b_fx; /* Q14/Q9 */
    1498        2187 :                 if ( EQ_16( clip_gain, 1 ) )
    1499             :                 {
    1500           0 :                     size = sub( size, 30 );
    1501             :                 }
    1502        2187 :                 BREAK;
    1503             :             }
    1504        3249 :             case 6:
    1505             :             {
    1506        3249 :                 cdbk = gp_gamma_2sfr_6b_fx; /* Q14/Q9 */
    1507        3249 :                 if ( EQ_16( clip_gain, 1 ) )
    1508             :                 {
    1509           0 :                     size = sub( size, 12 );
    1510             :                 }
    1511        3249 :                 BREAK;
    1512             :             }
    1513             :         }
    1514             : 
    1515             :         /* calculate predicted gain */
    1516        5436 :         aux[0] = 4096; /* 1 in Q12 */
    1517        5436 :         move16();
    1518        5436 :         aux[1] = shl( ctype, 12 );
    1519        5436 :         move16();
    1520             : 
    1521             :         /*aux[2] = (float)log10(gc_mem[0]);
    1522             :                  = log2(gc_mem[0])*log10(2);*/
    1523        5436 :         exp = norm_l( gc_mem[0] );
    1524        5436 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    1525        5436 :         exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_1sfr_fx)=16*/
    1526        5436 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );
    1527        5436 :         move16();                                 /* Q16 */
    1528        5436 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    1529        5436 :         move16();
    1530             : 
    1531        5436 :         aux[3] = shr( gp_mem[0], 2 );
    1532        5436 :         move16(); /*Q12*/
    1533             : 
    1534             :         /*-----------------------------------------------------------------*
    1535             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    1536             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    1537             :          *-----------------------------------------------------------------*/
    1538        5436 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    1539        5436 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    1540        5436 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    1541        5436 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1542             : 
    1543        5436 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1544             :         /* output of Pow2() will be: */
    1545             :         /* 16384 < Pow2() <= 32767 */
    1546        5436 :         exp_gcode0 = sub( exp_gcode0, 14 );
    1547             : 
    1548        5436 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    1549        5436 :         gc_mem[1] = *gain_code;                                                                             // Q16
    1550        5436 :         move32();
    1551        5436 :         gp_mem[1] = *gain_pit; // Q14
    1552        5436 :         move16();
    1553             :     }
    1554        6780 :     ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
    1555             :     {
    1556        3390 :         b = b_3sfr_fx; // Q12
    1557        3390 :         move16();
    1558        3390 :         n_pred = 6;
    1559        3390 :         move16();
    1560        3390 :         IF( EQ_16( nBits, 7 ) )
    1561             :         {
    1562           2 :             cdbk = gp_gamma_3sfr_7b_fx;
    1563           2 :             if ( clip_gain == 1 )
    1564             :             {
    1565           0 :                 size -= 28;
    1566             :             }
    1567             :         }
    1568             :         ELSE
    1569             :         {
    1570        3388 :             cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */
    1571        3388 :             if ( EQ_16( clip_gain, 1 ) )
    1572             :             {
    1573           0 :                 size = sub( size, 11 );
    1574             :             }
    1575             :         }
    1576             :         /* calculate predicted gain */
    1577        3390 :         aux[0] = 4096; /* 1 in Q12 */
    1578        3390 :         move16();
    1579        3390 :         aux[1] = shl( ctype, 12 );
    1580        3390 :         move16();
    1581             : 
    1582             :         /*aux[2] = (float)log10(gc_mem[0]);
    1583             :                  = log2(gc_mem[0])*log10(2);*/
    1584        3390 :         exp = norm_l( gc_mem[0] );
    1585        3390 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    1586        3390 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[0])=16*/
    1587        3390 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    1588        3390 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    1589        3390 :         move16();
    1590             : 
    1591             :         /*aux[3] = (float)log10(gc_mem[1]);
    1592             :                  =  log2(gc_mem[1])*log10(2);*/
    1593        3390 :         exp = norm_l( gc_mem[1] );
    1594        3390 :         frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
    1595        3390 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[1])=16*/
    1596        3390 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    1597        3390 :         aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    1598        3390 :         move16();
    1599             : 
    1600        3390 :         aux[4] = shr( gp_mem[0], 2 );
    1601        3390 :         move16(); /*Q12*/
    1602        3390 :         aux[5] = shr( gp_mem[1], 2 );
    1603        3390 :         move16(); /*Q12*/
    1604             : 
    1605             :         /*-----------------------------------------------------------------*
    1606             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    1607             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    1608             :          *-----------------------------------------------------------------*/
    1609        3390 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    1610        3390 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    1611        3390 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    1612        3390 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1613             : 
    1614        3390 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1615             :         /* output of Pow2() will be: */
    1616             :         /* 16384 < Pow2() <= 32767 */
    1617        3390 :         exp_gcode0 = sub( exp_gcode0, 14 );
    1618             : 
    1619             :         /*----------------------------------------------------------------*
    1620             :          * Find the best quantizer
    1621             :          * ~~~~~~~~~~~~~~~~~~~~~~~
    1622             :          * Before doing the computation we need to align exponents of coeff[]
    1623             :          * to be sure to have the maximum precision.
    1624             :          *
    1625             :          * In the table the pitch gains are in Q14, the code gains are in Q9 and
    1626             :          * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
    1627             :          * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
    1628             :          * we divide by 2^15.
    1629             :          * Considering all the scaling above we have:
    1630             :          *
    1631             :          *   exp_code = exp_gcode0-9+15 = exp_gcode0+6
    1632             :          *
    1633             :          *   g_pitch*g_pitch  = -14-14+15
    1634             :          *   g_pitch          = -14
    1635             :          *   g_code*g_code    = (2*exp_code)+15
    1636             :          *   g_code           = exp_code
    1637             :          *   g_pitch*g_code   = -14 + exp_code +15
    1638             :          *
    1639             :          *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13
    1640             :          *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14
    1641             :          *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
    1642             :          *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
    1643             :          *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
    1644             :          *----------------------------------------------------------------*/
    1645             : 
    1646        3390 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
    1647             : 
    1648        3390 :         gc_mem[2] = *gain_code; // Q16
    1649        3390 :         move32();
    1650        3390 :         gp_mem[2] = *gain_pit; // Q14
    1651        3390 :         move16();
    1652             :     }
    1653        3390 :     ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
    1654             :     {
    1655        3390 :         b = b_4sfr_fx; // Q12
    1656        3390 :         move16();
    1657        3390 :         n_pred = 8;
    1658        3390 :         move16();
    1659        3390 :         IF( EQ_16( nBits, 7 ) )
    1660             :         {
    1661           0 :             cdbk = gp_gamma_4sfr_7b_fx;
    1662           0 :             if ( clip_gain == 1 )
    1663             :             {
    1664           0 :                 size -= 25;
    1665             :             }
    1666             :         }
    1667             :         ELSE
    1668             :         {
    1669        3390 :             cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */
    1670        3390 :             if ( EQ_16( clip_gain, 1 ) )
    1671             :             {
    1672           0 :                 size = sub( size, 11 );
    1673             :             }
    1674             :         }
    1675             :         /* calculate predicted gain */
    1676        3390 :         aux[0] = 4096; /* 1 in Q12 */
    1677        3390 :         move16();
    1678        3390 :         aux[1] = shl( ctype, 12 );
    1679        3390 :         move16();
    1680             : 
    1681             :         /*aux[2] = (float)log10(gc_mem[0]);
    1682             :                  = log2(gc_mem[0])*log10(2);*/
    1683        3390 :         exp = norm_l( gc_mem[0] );
    1684        3390 :         frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
    1685        3390 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[0])=16*/
    1686        3390 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    1687        3390 :         aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    1688        3390 :         move16();
    1689             : 
    1690             :         /*aux[3] = (float)log10(gc_mem[1]);
    1691             :                  =  log2(gc_mem[1])*log10(2);*/
    1692        3390 :         exp = norm_l( gc_mem[1] );
    1693        3390 :         frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
    1694        3390 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[1])=16*/
    1695        3390 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    1696        3390 :         aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    1697        3390 :         move16();
    1698             : 
    1699             : 
    1700             :         /*aux[4] = (float)log10(gc_mem[2]);
    1701             :                  =  log2(gc_mem[2])*log10(2);*/
    1702        3390 :         exp = norm_l( gc_mem[2] );
    1703        3390 :         frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) );
    1704        3390 :         exp = sub( sub( 30, exp ), 16 );          /*Q_format(gc_mem[2])=16*/
    1705        3390 :         L_tmp1 = Mpy_32_16( exp, frac, 9864 );    /* Q16 */
    1706        3390 :         aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
    1707        3390 :         move16();
    1708             : 
    1709        3390 :         aux[5] = shr( gp_mem[0], 2 );
    1710        3390 :         move16(); /*Q12*/
    1711        3390 :         aux[6] = shr( gp_mem[1], 2 );
    1712        3390 :         move16(); /*Q12*/
    1713        3390 :         aux[7] = shr( gp_mem[2], 2 );
    1714        3390 :         move16(); /*Q12*/
    1715             :         /*-----------------------------------------------------------------*
    1716             :          * gcode0 = pow(10.0, dotp(b, aux, n_pred)
    1717             :          * = pow(2, 3.321928*dotp(b, aux, n_pred)
    1718             :          *-----------------------------------------------------------------*/
    1719        3390 :         L_tmp = Dot_product( b, aux, n_pred );     /*Q25*/
    1720        3390 :         L_tmp = Mult_32_16( L_tmp, 27213 );        /* *3.321928 in Q13 -> Q23 */
    1721        3390 :         L_tmp = L_shr( L_tmp, 7 );                 /* From Q23 to Q16 */
    1722        3390 :         frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
    1723             : 
    1724        3390 :         gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1725             :         /* output of Pow2() will be: */
    1726             :         /* 16384 < Pow2() <= 32767 */
    1727        3390 :         exp_gcode0 = sub( exp_gcode0, 14 );
    1728             : 
    1729        3390 :         index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
    1730             :     }
    1731             : 
    1732             :     /* *norm_gain_code = *gain_code / *gain_inov; */
    1733       17652 :     exp = sub( norm_s( *gain_inov ), 1 );
    1734       17652 :     exp = s_max( exp, 0 );
    1735             : 
    1736       17652 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
    1737       17652 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
    1738       17652 :     move32();
    1739             :     {
    1740       17652 :         push_indice( hBstr, IND_GAIN, index, nBits );
    1741             :     }
    1742       17652 :     return;
    1743             : }
    1744             : 
    1745             : /*-------------------------------------------------------------------*
    1746             :  * gain_enc_amr_wb()
    1747             :  *
    1748             :  * Quantization of pitch and codebook gains (used also in AMR-WB IO mode)
    1749             :  * MA prediction is performed on the innovation energy (in dB with mean removed).
    1750             :  * An initial predicted gain, gcode0, is first determined and the correction
    1751             :  * factor     alpha = g_code / gcode0   is quantized.
    1752             :  * The pitch gain and the correction factor are vector quantized and the
    1753             :  * mean-squared weighted error criterion is used in the quantizer search.
    1754             :  *-------------------------------------------------------------------*/
    1755             : 
    1756             : 
    1757           0 : void gain_enc_amr_wb_fx(
    1758             :     BSTR_ENC_HANDLE hBstr,   /* i/o: encoder bitstream handle                                                                                   */
    1759             :     const Word16 *xn,        /* i  : target vector                                                                                                              Q_xn*/
    1760             :     const Word16 Q_xn,       /* i  : xn and yy1 format                                                                                                  */
    1761             :     const Word16 *yy1,       /* i  : zero-memory filtered adaptive excitation                                                   Q_xn*/
    1762             :     const Word16 *y2,        /* i  : zero-memory filtered algebraic codebook excitation                                 Q9*/
    1763             :     const Word16 *code,      /* i  : algebraic excitation                                                                                               Q9*/
    1764             :     const Word32 core_brate, /* i  : core bitrate                                                                                                               Q0*/
    1765             :     Word16 *gain_pit,        /* i/o: pitch gain / Quantized pitch gain                                                                  Q14*/
    1766             :     Word32 *gain_code,       /* o  : quantized codebook gain                                                                                    Q16*/
    1767             :     Word16 *gain_inov,       /* o  : gain of the innovation (used for normalization)                                    Q12*/
    1768             :     Word32 *norm_gain_code,  /* o  : norm. gain of the codebook excitation                                                              Q16*/
    1769             :     Word16 *g_coeff,         /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>      Qx*/
    1770             :     const Word16 clip_gain,  /* i  : gain pitch clipping flag (1 = clipping)                                                    Q0*/
    1771             :     Word16 *past_qua_en      /* i/o: gain quantization memory (4 words)                                                                 Q10*/
    1772             : )
    1773             : {
    1774             : 
    1775             :     Word16 i, j, index, min_ind, size;
    1776             :     Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, exp_inov, qua_ener;
    1777             :     Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
    1778             :     Word16 coeff[5], coeff_lo[5], exp_coeff[5];
    1779             :     Word16 exp_max[5], tmp, nBits;
    1780             :     Word32 L_tmp, dist_min, L_inov, L_tmp1;
    1781             :     const Word16 *t_qua_gain, *p;
    1782             : #ifndef ISSUE_1867_replace_overflow_libenc
    1783             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1784             :     Flag Overflow = 0;
    1785             :     move32();
    1786             : #endif
    1787             : #endif
    1788             : 
    1789             :     /*----------------------------------------------------------------*
    1790             :      * Find the initial quantization pitch index
    1791             :      * Set gains search range
    1792             :      *----------------------------------------------------------------*/
    1793           0 :     IF( GE_32( core_brate, ACELP_12k65 ) )
    1794             :     {
    1795           0 :         t_qua_gain = t_qua_gain7b_fx; // Q14
    1796           0 :         move16();
    1797             :         /* pt at 1/4th of table */
    1798           0 :         p = t_qua_gain7b_fx + RANGE;
    1799           0 :         move16();
    1800             : 
    1801           0 :         j = NB_QUA_GAIN7B - RANGE;
    1802           0 :         move16();
    1803             : 
    1804           0 :         IF( EQ_16( clip_gain, 1 ) )
    1805             :         {
    1806           0 :             j = sub( j, 27 ); /* limit gain pitch to 1.0 */
    1807             :         }
    1808           0 :         min_ind = 0;
    1809           0 :         move16();
    1810           0 :         g_pitch = *gain_pit; // Q14
    1811           0 :         move16();
    1812             : 
    1813           0 :         FOR( i = 0; i < j; i++ )
    1814             :         {
    1815           0 :             if ( GT_16( g_pitch, *p ) )
    1816             :             {
    1817           0 :                 min_ind = add( min_ind, 1 ); // Q0
    1818             :             }
    1819           0 :             p += 2;
    1820             :         }
    1821           0 :         size = RANGE;
    1822           0 :         move16();
    1823           0 :         nBits = 7;
    1824             :     }
    1825             :     ELSE
    1826             :     {
    1827           0 :         t_qua_gain = t_qua_gain6b_fx; // Q14
    1828           0 :         min_ind = 0;
    1829           0 :         move16();
    1830           0 :         size = RANGE;
    1831           0 :         move16();
    1832           0 :         if ( EQ_16( clip_gain, 1 ) )
    1833             :         {
    1834           0 :             size = sub( size, 16 ); /* limit gain pitch to 1.0 */
    1835             :         }
    1836           0 :         nBits = 6;
    1837             :     }
    1838             :     /*----------------------------------------------------------------*
    1839             :      *  Compute coefficients needed for the quantization.
    1840             :      *
    1841             :      *  coeff[0] =    yy1 yy1
    1842             :      *  coeff[1] = -2 xn yy1
    1843             :      *  coeff[2] =    y2 y2
    1844             :      *  coeff[3] = -2 xn y2
    1845             :      *  coeff[4] =  2 yy1 y2
    1846             :      *
    1847             :      * Product <yy1 yy1> and <xn yy1> have been computed in Adpt_enr() and
    1848             :      * are in vector g_coeff[].
    1849             :      *----------------------------------------------------------------*/
    1850           0 :     coeff[0] = g_coeff[0];
    1851           0 :     move16();
    1852           0 :     exp_coeff[0] = g_coeff[1];
    1853           0 :     move16();
    1854           0 :     coeff[1] = negate( g_coeff[2] );
    1855           0 :     move16(); /* coeff[1] = -2 xn yy1 */
    1856           0 :     exp_coeff[1] = add( g_coeff[3], 1 );
    1857           0 :     move16();
    1858             : 
    1859             :     /* Compute scalar product <y2[],y2[]> */
    1860           0 :     coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
    1861           0 :     exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
    1862           0 :     move16();
    1863           0 :     move16();
    1864             : 
    1865             :     /* Compute scalar product -2*<xn[],y2[]> */
    1866           0 :     coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
    1867           0 :     exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
    1868           0 :     move16();
    1869           0 :     move16();
    1870             : 
    1871             :     /* Compute scalar product 2*<yy1[],y2[]> */
    1872           0 :     coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
    1873           0 :     exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
    1874           0 :     move16();
    1875           0 :     move16();
    1876             : 
    1877             :     /*----------------------------------------------------------------*
    1878             :      *  Find energy of code and compute:
    1879             :      *
    1880             :      *    L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr)
    1881             :      *          = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr)
    1882             :      *----------------------------------------------------------------*/
    1883           0 :     L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
    1884           0 :     L_inov = L_add( L_tmp, 0 );
    1885             :     /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */
    1886             :     /* output gain_inov*/
    1887           0 :     exp_inov = sub( exp_code, 18 + 6 );
    1888           0 :     L_inov = Isqrt_lc( L_inov, &exp_inov );
    1889           0 :     *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
    1890           0 :     move16();
    1891             : 
    1892           0 :     exp_code = sub( exp_code, 18 + 6 + 31 );
    1893           0 :     frac = Log2_lc( L_tmp, &exp );
    1894           0 :     exp = add( exp, exp_code );
    1895           0 :     L_tmp = Mpy_32_16( exp, frac, -24660 ); /* x -3.0103(Q13) -> Q14 */
    1896             : 
    1897           0 :     L_tmp = L_mac( L_tmp, MEAN_ENER, 8192 ); /* + MEAN_ENER in Q14 */
    1898             : 
    1899             :     /*----------------------------------------------------------------*
    1900             :      * predicted codebook gain
    1901             :      *----------------------------------------------------------------*/
    1902           0 :     L_tmp = L_shl( L_tmp, 10 );                               /* From Q14 to Q24 */
    1903           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[0], past_qua_en[0] ); /* Q14*Q10 -> Q24 */
    1904           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[1], past_qua_en[1] ); /* Q14*Q10 -> Q24 */
    1905           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[2], past_qua_en[2] ); /* Q14*Q10 -> Q24 */
    1906           0 :     L_tmp = L_mac0( L_tmp, pred_gain_fx[3], past_qua_en[3] ); /* Q14*Q10 -> Q24 */
    1907             : 
    1908           0 :     gcode0 = extract_h( L_tmp ); /* From Q24 to Q8  */
    1909             : 
    1910             :     /*----------------------------------------------------------------*
    1911             :      * gcode0 = pow(10.0, gcode0/20)
    1912             :      *        = pow(2, 3.321928*gcode0/20)
    1913             :      *        = pow(2, 0.166096*gcode0)
    1914             :      *----------------------------------------------------------------*/
    1915           0 :     L_tmp = L_mult( gcode0, 5443 );         /* *0.166096 in Q15 -> Q24    */
    1916           0 :     L_tmp = L_shr( L_tmp, 8 );              /* From Q24 to Q16            */
    1917           0 :     L_Extract( L_tmp, &exp_gcode0, &frac ); /* Extract exponent of gcode0 */
    1918             : 
    1919           0 :     gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
    1920             :     /* output of Pow2() will be: */
    1921             :     /* 16384 < Pow2() <= 32767   */
    1922           0 :     exp_gcode0 = sub( exp_gcode0, 14 );
    1923             : 
    1924             :     /*----------------------------------------------------------------*
    1925             :      * Find the best quantizer
    1926             :      * ~~~~~~~~~~~~~~~~~~~~~~~
    1927             :      * Before doing the computation we need to aling exponents of coeff[]
    1928             :      * to be sure to have the maximum precision.
    1929             :      *
    1930             :      * In the table the pitch gains are in Q14, the code gains are in Q11 and
    1931             :      * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
    1932             :      * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
    1933             :      * we divide by 2^15.
    1934             :      * Considering all the scaling above we have:
    1935             :      *
    1936             :      *   exp_code = exp_gcode0-11+15 = exp_gcode0+4
    1937             :      *
    1938             :      *   g_pitch*g_pitch  = -14-14+15
    1939             :      *   g_pitch          = -14
    1940             :      *   g_code*g_code    = (2*exp_code)+15
    1941             :      *   g_code           = exp_code
    1942             :      *   g_pitch*g_code   = -14 + exp_code +15
    1943             :      *
    1944             :      *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] - 13
    1945             :      *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] - 14
    1946             :      *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
    1947             :      *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
    1948             :      *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
    1949             :      *----------------------------------------------------------------*/
    1950             : 
    1951           0 :     exp_code = add( exp_gcode0, 4 );
    1952             : 
    1953           0 :     exp_max[0] = sub( exp_coeff[0], 13 );
    1954           0 :     move16();
    1955           0 :     exp_max[1] = sub( exp_coeff[1], 14 );
    1956           0 :     move16();
    1957           0 :     exp_max[2] = add( exp_coeff[2],
    1958           0 :                       add( 15, shl( exp_code, 1 ) ) );
    1959           0 :     move16();
    1960           0 :     exp_max[3] = add( exp_coeff[3], exp_code );
    1961           0 :     move16();
    1962           0 :     exp_max[4] = add( exp_coeff[4],
    1963           0 :                       add( 1, exp_code ) );
    1964           0 :     move16();
    1965             : 
    1966             :     /* Find maximum exponant */
    1967           0 :     e_max = exp_max[0];
    1968           0 :     move16();
    1969           0 :     FOR( i = 1; i < 5; i++ )
    1970             :     {
    1971           0 :         e_max = s_max( exp_max[i], e_max );
    1972             :     }
    1973             : 
    1974             :     /* align coeff[] and save in special 32 bit double precision */
    1975           0 :     FOR( i = 0; i < 5; i++ )
    1976             :     {
    1977           0 :         j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
    1978           0 :         L_tmp = L_deposit_h( coeff[i] );
    1979           0 :         L_tmp = L_shr( L_tmp, j );
    1980           0 :         L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
    1981           0 :         coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
    1982           0 :         move16();
    1983             :     }
    1984             : 
    1985             :     /* Codebook search */
    1986           0 :     dist_min = L_add( MAX_32, 0 );
    1987           0 :     p = &t_qua_gain[shl( min_ind, 1 )]; // Q14
    1988           0 :     move16();
    1989             : 
    1990           0 :     index = 0;
    1991           0 :     move16();
    1992           0 :     FOR( i = 0; i < size; i++ )
    1993             :     {
    1994           0 :         g_pitch = *p++;
    1995           0 :         move16();
    1996           0 :         g_code = *p++;
    1997           0 :         move16();
    1998             : 
    1999           0 :         g_code = mult_r( g_code, gcode0 );     // exp(gcode) - 1
    2000           0 :         g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
    2001           0 :         g_pit_cod = mult_r( g_code, g_pitch );
    2002           0 :         L_tmp = L_mult( g_code, g_code );
    2003           0 :         L_Extract( L_tmp, &g2_code, &g2_code_lo );
    2004             : 
    2005           0 :         L_tmp = L_mult( coeff[2], g2_code_lo );
    2006           0 :         L_tmp = L_shr( L_tmp, 3 );
    2007           0 :         L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
    2008           0 :         L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
    2009           0 :         L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
    2010           0 :         L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
    2011           0 :         L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
    2012           0 :         L_tmp = L_shr( L_tmp, 12 );
    2013           0 :         L_tmp = L_mac( L_tmp, coeff[0], g2_pitch );  /* 15 - coeff_exp + 13 - 1 */
    2014           0 :         L_tmp = L_mac( L_tmp, coeff[1], g_pitch );   /* 15 - coeff_exp + 13 - 1 */
    2015           0 :         L_tmp = L_mac( L_tmp, coeff[2], g2_code );   /* 15 - coeff_exp + 13 - 1 */
    2016           0 :         L_tmp = L_mac( L_tmp, coeff[3], g_code );    /* 15 - coeff_exp + 13 - 1 */
    2017           0 :         L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
    2018             : 
    2019             : #ifdef ISSUE_1867_replace_overflow_libenc
    2020           0 :         L_tmp1 = L_sub_sat( L_tmp, dist_min );
    2021             : #else
    2022             :         L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
    2023             : #endif
    2024             :         /* splitting the if cost half the complexity of using IF macro */
    2025           0 :         if ( L_tmp1 < 0 )
    2026             :         {
    2027           0 :             dist_min = L_add( L_tmp, 0 );
    2028             :         }
    2029           0 :         if ( L_tmp1 < 0 )
    2030             :         {
    2031           0 :             index = i;
    2032           0 :             move16();
    2033             :         }
    2034             :     }
    2035             :     /* Read the quantized gains */
    2036           0 :     index = add( index, min_ind );
    2037             : 
    2038           0 :     p = &t_qua_gain[add( index, index )];
    2039           0 :     move16();
    2040           0 :     *gain_pit = *p++; /* selected pitch gain in Q14 */
    2041           0 :     move16();
    2042           0 :     g_code = *p++; /* selected  code gain in Q11 */
    2043           0 :     move16();
    2044             : 
    2045           0 :     L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q0 -> Q12 */
    2046             : #ifdef ISSUE_1867_replace_overflow_libenc
    2047           0 :     L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 4 ) ); /* Q12 -> Q16 */
    2048             : #else
    2049             :     L_tmp = L_shl_o( L_tmp, add( exp_gcode0, 4 ), &Overflow ); /* Q12 -> Q16 */
    2050             : #endif
    2051             : 
    2052           0 :     *gain_code = L_tmp; /* gain of code in Q16 */
    2053           0 :     move16();
    2054             : 
    2055             :     /*---------------------------------------------------*
    2056             :      * qua_ener = 20*log10(g_code)
    2057             :      *          = 6.0206*log2(g_code)
    2058             :      *          = 6.0206*(log2(g_codeQ11) - 11)
    2059             :      *---------------------------------------------------*/
    2060           0 :     L_tmp = L_deposit_l( g_code );
    2061           0 :     frac = Log2_lc( L_tmp, &exp );
    2062           0 :     exp = sub( exp, 11 );
    2063           0 :     L_tmp = Mpy_32_16( exp, frac, 24660 ); /* x 6.0206 in Q12 */
    2064             : 
    2065           0 :     qua_ener = extract_l( L_shr( L_tmp, 3 ) ); /* result in Q10 */
    2066             : 
    2067             :     /*----------------------------------------------------------------*
    2068             :      * update table of past quantized energies
    2069             :      *----------------------------------------------------------------*/
    2070             : 
    2071           0 :     past_qua_en[3] = past_qua_en[2]; // Q10
    2072           0 :     move16();
    2073           0 :     past_qua_en[2] = past_qua_en[1]; // Q10
    2074           0 :     move16();
    2075           0 :     past_qua_en[1] = past_qua_en[0]; // Q10
    2076           0 :     move16();
    2077           0 :     past_qua_en[0] = qua_ener; // Q10
    2078           0 :     move16();
    2079             : 
    2080             : 
    2081           0 :     exp = sub( norm_s( *gain_inov ), 1 );
    2082           0 :     exp = s_max( exp, 0 );
    2083             : 
    2084           0 :     tmp = div_s( shr( 8192, exp ), *gain_inov );
    2085           0 :     *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
    2086           0 :     move32();
    2087             : 
    2088           0 :     push_indice( hBstr, IND_GAIN, index, nBits );
    2089             : 
    2090           0 :     return;
    2091             : }

Generated by: LCOV version 1.14