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

Generated by: LCOV version 1.14