LCOV - code coverage report
Current view: top level - lib_enc - q_gain2p_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 61b27367e0d19b9fc53332787af331bed7af66b1 Lines: 242 272 89.0 %
Date: 2025-10-21 02:53:18 Functions: 3 3 100.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 <assert.h>
       7             : #include "options.h"
       8             : #include "cnst.h" /* Common constants                     */
       9             : #include "basop_util.h"
      10             : #include "rom_com.h"     /* Common constants                       */
      11             : #include "prot_fx.h"     /* Function prototypes                    */
      12             : #include "prot_fx_enc.h" /* Function prototypes                    */
      13             : #include "basop_util.h"  /* Function prototypes                    */
      14             : 
      15             : 
      16             : static Word16 gain_enc(                     /* o   : quantization pitch index                                    <Q0> */
      17             :                         const Word16 *code, /* i   : algebraic excitation                                        <Q9> */
      18             :                         Word16 lcode,       /* i   : Subframe size in range: 40,64,80                            <Q0> */
      19             :                         Word16 *gain_pit,   /* o   : quantized pitch gain                                       <Q16> */
      20             :                         /* i/o : only func=1,coder_type=1 quantized pitch gain              <Q16> */
      21             :                         Word32 *gain_code,       /* o   : quantized codebook gain                                    <Q16> */
      22             :                         ACELP_CbkCorr *g_coeff,  /* i   : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>  */
      23             :                         Word16 mean_ener,        /* i   : only func=0: mean_ener defined in open-loop (3 bits)        <Q8> */
      24             :                         const Word16 clip_gain,  /* i   : only func=0,1: gain pitch clipping flag (1 = clipping)      <Q0> */
      25             :                         Word32 *past_gcode,      /* o   : past gain of code                                          <Q16> */
      26             :                         Word16 *gain_inov,       /* o   : Q12 innovation gain                                        <Q12> */
      27             :                         const Word16 coder_type, /* i   : only func=0,1: coder type                                   <Q0> */
      28             :                         const Word16 func_type   /* i   : algorithm: 0=gain_enc_mless, 1=gain_enc_2                   <Q0> */
      29             : );
      30             : 
      31             : /*-------------------------------------------------------------------------*
      32             :  * procedure q_gain2_plus                                                  *
      33             :  * ~~~~~~~~~~~~~~~~~~~~~~                                                  *
      34             :  * Quantization of pitch and codebook gains.                               *
      35             :  * The following routines is Q_gains updated for AMR_WB_PLUS.              *
      36             :  * MA prediction is removed and MEAN_ENER is now quantized with 2 bits and *
      37             :  * transmitted once every ACELP frame to the gains decoder.                *
      38             :  * The pitch gain and the code gain are vector quantized and the           *
      39             :  * mean-squared weighted error criterion is used in the quantizer search.  *
      40             :  *-------------------------------------------------------------------------*/
      41        3060 : void encode_acelp_gains_fx(
      42             :     Word16 *code,
      43             :     Word16 gains_mode,
      44             :     Word16 mean_ener_code,
      45             :     Word16 clip_gain,
      46             :     ACELP_CbkCorr *g_corr,
      47             :     Word16 *gain_pit,
      48             :     Word32 *gain_code,
      49             :     Word16 **pt_indice,
      50             :     Word32 *past_gcode,
      51             :     Word16 *gain_inov,
      52             :     Word16 L_subfr,
      53             :     Word16 *code2,
      54             :     Word32 *gain_code2,
      55             :     Word16 noisy_speech_flag /* i   : noisy speech flag                                            */
      56             : )
      57             : {
      58        3060 :     Word16 index = 0, func_type = 0;
      59        3060 :     move16();
      60        3060 :     move16();
      61             : 
      62             :     BASOP_SATURATE_ERROR_ON_EVS;
      63             : 
      64        3060 :     SWITCH( gains_mode )
      65             :     {
      66        3060 :         case 1:
      67             :         case 2:
      68             :         case 3:
      69             :             /* Memory-less gain coding */
      70        3060 :             gains_mode = sub( gains_mode, 1 );
      71        3060 :             func_type = FUNC_GAIN_ENC_MLESS;
      72        3060 :             move16();
      73        3060 :             BREAK;
      74           0 :         case 4:
      75             :         case 5:
      76           0 :             assert( 0 );
      77             :             BREAK;
      78           0 :         case 6:
      79             :             /* UV gains quantizer (6 bits/subfr) */
      80           0 :             gains_mode = sub( gains_mode, 6 );
      81           0 :             func_type = FUNC_GAIN_ENC_UV;
      82           0 :             move16();
      83           0 :             BREAK;
      84           0 :         case 7:
      85           0 :             gains_mode = sub( gains_mode, 7 );
      86           0 :             func_type = FUNC_GAIN_ENC_GACELP_UV;
      87           0 :             move16();
      88           0 :             BREAK;
      89           0 :         default:
      90           0 :             IVAS_ERROR( IVAS_ERR_INTERNAL, "invalid gains coding for acelp!" );
      91           0 :             func_type = 0;
      92           0 :             move16(); /*To avoid compiler warning*/
      93           0 :             BREAK;
      94             :     }
      95             : 
      96        3060 :     IF( func_type == FUNC_GAIN_ENC_MLESS )
      97             :     {
      98        3060 :         index = gain_enc( code, L_subfr, gain_pit, gain_code, g_corr, mean_ener_code,
      99             :                           clip_gain, past_gcode, gain_inov, gains_mode, func_type );
     100             :     }
     101             :     ELSE
     102             :     {
     103           0 :         index = gain_enc_uv_fx( code, code2, L_subfr, gain_pit, gain_code, gain_code2,
     104             :                                 noisy_speech_flag, g_corr, mean_ener_code, past_gcode, gain_inov, func_type );
     105             :     }
     106             : 
     107        3060 :     move16();
     108        3060 :     **pt_indice = index;
     109        3060 :     ( *pt_indice )++;
     110             : 
     111             :     BASOP_SATURATE_ERROR_OFF_EVS;
     112        3060 : }
     113             : 
     114             : /*---------------------------------------------------------------------*
     115             :  * procedure gain_enc_mless
     116             :  * Quantization of pitch and codebook gains.
     117             :  * - an initial predicted gain, gcode0, is first determined based on
     118             :  *   the predicted scaled innovation energy
     119             :  * - the correction  factor gamma = g_code / gcode0 is then vector quantized
     120             :  *   along with gain_pit
     121             :  * - the mean-squared weighted error criterion is used for the quantizer search
     122             :  *---------------------------------------------------------------------*/
     123             : 
     124        3060 : static Word16 gain_enc(                     /* o   : quantization pitch index                                    <Q0> */
     125             :                         const Word16 *code, /* i   : algebraic excitation                                        <Q9> */
     126             :                         Word16 lcode,       /* i   : Subframe size in range: 40,64,80                            <Q0> */
     127             :                         Word16 *gain_pit,   /* o   : quantized pitch gain                                       <Q16> */
     128             :                         /* i/o : only func=1,coder_type=1 quantized pitch gain              <Q16> */
     129             :                         Word32 *gain_code,       /* o   : quantized codebook gain                                    <Q16> */
     130             :                         ACELP_CbkCorr *g_coeff,  /* i   : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>  */
     131             :                         Word16 mean_ener,        /* i   : only func=0: mean_ener defined in open-loop (3 bits)        <Q8> */
     132             :                         const Word16 clip_gain,  /* i   : only func=0,1: gain pitch clipping flag (1 = clipping)      <Q0> */
     133             :                         Word32 *past_gcode,      /* o   : past gain of code                                          <Q16> */
     134             :                         Word16 *gain_inov,       /* o   : Q12 innovation gain                                        <Q12> */
     135             :                         const Word16 coder_type, /* i   : only func=0,1: coder type                                   <Q0> */
     136             :                         const Word16 func_type   /* i   : algorithm: 0=gain_enc_mless, 1=gain_enc_2                   <Q0> */
     137             : )
     138             : {
     139             :     Word16 i, j, index, size, min_index, exp_L_tmp1;
     140             :     Word16 gcode0, gcode0_gi, exp_gcode0, exp_sum, exp_code, g_code_shl;
     141             : 
     142             :     Word16 g_code;
     143             :     Word16 coeff0, coeff1, coeff2, coeff3, coeff4, exp_coeff0, exp_coeff1, exp_coeff2, exp_coeff3, exp_coeff4;
     144             :     Word16 shr_coeff0, shr_coeff1, shr_coeff2, shr_coeff3, shr_coeff4;
     145             :     const Word16 *p;
     146             :     const Word16 *t_qua_gain;
     147             :     Word32 L_tmp, dist_min, L_tmp1;
     148             : 
     149        3060 :     assert( ( func_type != FUNC_GAIN_ENC_UV ) && ( func_type != FUNC_GAIN_ENC_GACELP_UV ) );
     150             : 
     151             :     /* Debug test value (not instrumented) */
     152        3060 :     gcode0 = -3000;
     153        3060 :     move16();
     154             : 
     155             :     /*----------------------------------------------------------------*
     156             :      * - calculate the unscaled innovation energy
     157             :      * - calculate the predicted gain code
     158             :      *----------------------------------------------------------------*/
     159             : 
     160             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     161        3060 :     L_tmp = calc_gain_inov( code, lcode, &L_tmp1, &exp_L_tmp1 );
     162        3060 :     move16();
     163        3060 :     *gain_inov = round_fx_sat( L_shl_sat( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */
     164        3060 :     move16();
     165             : 
     166             :     /*----------------------------------------------------------------*
     167             :      * calculate the predicted gain code
     168             :      *----------------------------------------------------------------*/
     169             : 
     170        3060 :     IF( func_type == FUNC_GAIN_ENC_MLESS )
     171             :     {
     172             :         /*j = 10 * log10((dot_product(code, code, lcode) + 0.01) / lcode) */
     173        3060 :         j = BASOP_Util_lin2dB( L_tmp1, exp_L_tmp1, 1 ); /* Q8 */
     174             : 
     175             :         /* predicted codebook gain */
     176        3060 :         gcode0 = sub( mean_ener, j ); /* Q8 */
     177             :     }
     178             : 
     179             :     /*----------------------------------------------------------------*
     180             :      *  Compute coefficients needed for the quantization.
     181             :      *
     182             :      *  coeff[0] =    yy1 yy1
     183             :      *  coeff[1] = -2 xn yy1
     184             :      *  coeff[2] =    y2 y2
     185             :      *  coeff[3] = -2 xn y2
     186             :      *  coeff[4] =  2 yy1 y2
     187             :      *
     188             :      * Product <yy1 yy1> and <xn yy1> have been computed in Adpt_enr() and
     189             :      * are in vector g_coeff[].
     190             :      *----------------------------------------------------------------*/
     191             : 
     192        3060 :     coeff0 = g_coeff->y1y1;
     193        3060 :     move16();
     194        3060 :     exp_coeff0 = g_coeff->y1y1_e;
     195        3060 :     move16();
     196        3060 :     coeff2 = g_coeff->y2y2;
     197        3060 :     move16();
     198        3060 :     exp_coeff2 = g_coeff->y2y2_e;
     199        3060 :     move16();
     200             : 
     201        3060 :     coeff1 = g_coeff->xy1;
     202        3060 :     move16();
     203        3060 :     exp_coeff1 = add( g_coeff->xy1_e, 1 );
     204        3060 :     coeff3 = g_coeff->xy2;
     205        3060 :     move16();
     206        3060 :     exp_coeff3 = add( g_coeff->xy2_e, 1 );
     207        3060 :     coeff4 = g_coeff->y1y2;
     208        3060 :     move16();
     209        3060 :     exp_coeff4 = add( g_coeff->y1y2_e, 1 );
     210             : 
     211             :     /*---------------------------------------------------------------*
     212             :      * Decode codebook gain and the adaptive excitation low-pass
     213             :      * filtering factor (Finalize computation )
     214             :      *---------------------------------------------------------------*/
     215             : 
     216             : 
     217             :     /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
     218             :     /*----------------------------------------------------------------*
     219             :      * gcode0 = pow(10.0, gcode0/20)                    gcode in Q8
     220             :      *        = pow(2, 3.321928*gcode0/20)
     221             :      *        = pow(2, 0.166096*gcode0)
     222             :      *----------------------------------------------------------------*/
     223             : 
     224             :     /* Check if gcode0 was uninitialized. */
     225        3060 :     assert( gcode0 != -3000 );
     226             : 
     227        3060 :     L_tmp = L_mult( gcode0, 5443 /*0.166096f Q15*/ );
     228        3060 :     exp_gcode0 = add( 1, extract_l( L_shr( L_tmp, 24 ) ) );
     229        3060 :     L_tmp = L_lshl( L_tmp, 7 );
     230        3060 :     L_tmp = L_and( 0x7FFFFFFF, L_tmp );
     231             : 
     232        3060 :     L_tmp = Pow2( 30, round_fx( L_tmp ) );
     233        3060 :     gcode0 = round_fx( L_tmp );
     234             :     /* exponent of gcode0 = exp_gcode0 */
     235             : 
     236             :     /*-----------------------------------------------------------------*
     237             :      * gain quantization initializations
     238             :      * - find the initial quantization pitch index
     239             :      * - set the gains searching range
     240             :      *----------------------------------------------------------------*/
     241             : 
     242             :     /*----------------------------------------------------------------*
     243             :      * Find the best quantizer
     244             :      *
     245             :      * Before doing the computation we need to align exponents of coeff[]
     246             :      * to be sure to have the maximum precision.
     247             :      *
     248             :      * In the table the pitch gains are in Q14, the code gains are in Q11 and
     249             :      * are multiplied by gcode0 which have been multiplied by 2^exp_gcode0.
     250             :      * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
     251             :      * we divide by 2^15.
     252             :      * Considering all the scaling above we have:
     253             :      *
     254             :      *   exp_code = exp_gcode0 + 4
     255             :      *   if (func_type == gain_enc_2)
     256             :      *         gcode0 *= gain_inov (in Q12)  => exp_code += 3
     257             :      *
     258             :      *   g_pitch*g_pitch  = +1+1
     259             :      *   g_pitch          = +1
     260             :      *   g_code*g_code    = (2*exp_code)
     261             :      *   g_code           = exp_code
     262             :      *   g_pitch*g_code   = + 1 + exp_code
     263             :      *
     264             :      *   g_pitch*g_pitch * coeff[0]  ;exp_max0 = exp_coeff[0] + 2
     265             :      *   g_pitch         * coeff[1]  ;exp_max1 = exp_coeff[1] + 1
     266             :      *   g_code*g_code   * coeff[2]  ;exp_max2 = exp_coeff[2] + (2*exp_code)
     267             :      *   g_code          * coeff[3]  ;exp_max3 = exp_coeff[3] + exp_code
     268             :      *   g_pitch*g_code  * coeff[4]  ;exp_max4 = exp_coeff[4] + 1 + exp_code
     269             :      *----------------------------------------------------------------*/
     270             : 
     271        3060 :     exp_code = add( exp_gcode0, 4 );
     272             : 
     273        3060 :     exp_coeff0 = add( exp_coeff0, 2 );
     274        3060 :     exp_coeff1 = add( exp_coeff1, 1 );
     275        3060 :     exp_coeff2 = add( exp_coeff2, shl( exp_code, 1 ) );
     276        3060 :     exp_coeff3 = add( exp_coeff3, exp_code );
     277        3060 :     exp_coeff4 = add( exp_coeff4, add( 1, exp_code ) );
     278             : 
     279             :     /* Find maximum exponent */
     280        3060 :     exp_sum = s_max( exp_coeff1, exp_coeff0 );
     281        3060 :     exp_sum = s_max( exp_coeff2, exp_sum );
     282        3060 :     exp_sum = s_max( exp_coeff3, exp_sum );
     283        3060 :     exp_sum = s_max( exp_coeff4, exp_sum );
     284        3060 :     exp_sum = add( exp_sum, 2 );
     285             : 
     286             :     /* Align exponents of summands in loop far below. */
     287        3060 :     shr_coeff0 = sub( exp_sum, exp_coeff0 );
     288        3060 :     shr_coeff1 = sub( exp_sum, exp_coeff1 );
     289        3060 :     shr_coeff2 = sub( exp_sum, exp_coeff2 );
     290        3060 :     shr_coeff3 = sub( exp_sum, exp_coeff3 );
     291        3060 :     shr_coeff4 = sub( exp_sum, exp_coeff4 );
     292             :     /* Codebook search */
     293             : 
     294        3060 :     dist_min = L_deposit_h( MAX_16 );
     295             : 
     296        3060 :     min_index = 0;
     297        3060 :     move16();
     298             : 
     299             :     {
     300             :         Word16 size_clip;
     301             : 
     302             : 
     303        3060 :         IF( coder_type == 0 )
     304             :         {
     305             : 
     306           0 :             t_qua_gain = E_ROM_qua_gain5b_const;
     307           0 :             size_clip = 9;
     308           0 :             size = NB_QUA_GAIN5B;
     309             :         }
     310        3060 :         ELSE IF( coder_type == 1 )
     311             :         {
     312             : 
     313         135 :             t_qua_gain = E_ROM_qua_gain6b_const;
     314         135 :             size_clip = 6;
     315         135 :             size = NB_QUA_GAIN6B; /* searching range of the gain quantizer */
     316             :         }
     317             :         ELSE
     318             :         {
     319             : 
     320        2925 :             t_qua_gain = E_ROM_qua_gain7b_const;
     321        2925 :             size_clip = 21;
     322        2925 :             size = NB_QUA_GAIN7B;
     323             :         }
     324        3060 :         move16();
     325        3060 :         move16();
     326             : 
     327        3060 :         if ( EQ_16( clip_gain, 1 ) )
     328             :         {
     329           0 :             size = sub( size, size_clip ); /* limit pitch gain  to 1.0 */
     330             :         }
     331        3060 :         gcode0_gi = gcode0;
     332        3060 :         move16();
     333             :     }
     334        3060 :     p = t_qua_gain;
     335             : 
     336        3060 :     index = 0;
     337        3060 :     move16();
     338             : 
     339             :     /* divide all coeff1,2,3,4 by coeff0 */
     340             :     /* in order to skip multiplication with coeff0 in loop */
     341        3060 :     assert( coeff0 >= 0x4000 );
     342        3060 :     coeff0 = div_s( 0x4000, coeff0 );
     343        3060 :     coeff1 = mult_r( coeff1, coeff0 );
     344        3060 :     coeff2 = mult_r( coeff2, coeff0 );
     345        3060 :     coeff3 = mult_r( coeff3, coeff0 );
     346        3060 :     coeff4 = mult_r( coeff4, coeff0 );
     347             : 
     348      386100 :     FOR( i = 0; i < size; i++ )
     349             :     {
     350             :         /*
     351             :            Note: gcode0_gi: either gcode0 or gcode0*gain_inov
     352             :            g_pitch = *p++;
     353             :            g_code = gcode0_gi * *p++;
     354             : 
     355             :            dist = g_pitch*g_pitch * coeff.y1y1
     356             :            + g_pitch        * coeff.xy1 (negated)
     357             :            + g_code*g_code  * coeff.y2y2
     358             :            + g_code         * coeff.xy2 (negated)
     359             :            + g_pitch*g_code * coeff.y1y2;
     360             :         */
     361             : 
     362             :         /* Since g_code has a significant dynamic, we prefer to normalize this 16-bit value */
     363      383040 :         g_code_shl = norm_s( p[2 * i + 1] );
     364      383040 :         g_code = shl( p[2 * i + 1], g_code_shl );
     365      383040 :         g_code = mult_r( g_code, gcode0_gi );
     366             :         BASOP_SATURATE_WARNING_OFF_EVS /* needed to skip overflow warnings due to exceeding shift values */
     367      383040 :             L_tmp = L_shr( Mpy_32_16_1( L_mult( g_code, g_code ), coeff2 ), shr_coeff2 );
     368      383040 :         if ( g_code_shl != 0 )
     369      374130 :             L_tmp = L_shr( L_tmp, g_code_shl );
     370      383040 :         L_tmp = L_sub( L_tmp, L_shr( L_mult( g_code, coeff3 ), shr_coeff3 ) );
     371      383040 :         L_tmp = L_add( L_tmp, L_shr( Mpy_32_16_1( L_mult( g_code, p[2 * i + 0] ), coeff4 ), shr_coeff4 ) );
     372      383040 :         if ( g_code_shl != 0 )
     373      374130 :             L_tmp = L_shr( L_tmp, g_code_shl );
     374             :         /* Here, we use L_mult0 to compensate the factor 0.5 applied to coeff[1..4] before */
     375      383040 :         L_tmp = L_add( L_tmp, L_shr( L_mult0( p[2 * i + 0], p[2 * i + 0] ), shr_coeff0 ) );
     376      383040 :         L_tmp = L_sub( L_tmp, L_shr( L_mult( p[2 * i + 0], coeff1 ), shr_coeff1 ) );
     377      383040 :         L_tmp1 = L_sub_sat( L_tmp, dist_min );
     378             :         BASOP_SATURATE_WARNING_ON_EVS
     379      383040 :         if ( L_tmp1 < 0 )
     380             :         {
     381       62796 :             index = i;
     382       62796 :             move16();
     383             :         }
     384      383040 :         if ( L_tmp1 < 0 )
     385             :         {
     386       62796 :             dist_min = L_min( L_tmp, dist_min );
     387             :         }
     388             :     }
     389        3060 :     index = add( index, min_index );
     390        3060 :     *gain_pit = t_qua_gain[2 * index + 0];
     391        3060 :     move16();
     392        3060 :     g_code = t_qua_gain[2 * index + 1];
     393        3060 :     move16();
     394             : 
     395        3060 :     L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q15 -> Q27 */
     396        3060 :     exp_gcode0 = add( exp_gcode0, -11 );
     397        3060 :     L_tmp = L_shl_sat( L_tmp, exp_gcode0 ); /*   Q27 -> Q16 */
     398             : 
     399        3060 :     *gain_code = L_tmp;
     400        3060 :     move32();
     401             :     /* Q16/Q12 => Q5 */
     402        3060 :     L_tmp = L_deposit_h( BASOP_Util_Divide3216_Scale( L_tmp, *gain_inov, &i ) );
     403        3060 :     *past_gcode = L_shl_sat( L_tmp, sub( i, 15 - 12 ) );
     404        3060 :     move16();
     405             : 
     406        3060 :     return index;
     407             : }
     408             : 
     409             : 
     410        8060 : Word16 gain_enc_uv_fx(                           /* o   : quantization pitch index                                    <Q0> */
     411             :                        const Word16 *code,       /* i   : algebraic excitation                                        <Q9> */
     412             :                        const Word16 *code2,      /* i   : gaussian excitation                                         <Q9> */
     413             :                        Word16 lcode,             /* i   : Subframe size in range: 40,64,80                            <Q0> */
     414             :                        Word16 *gain_pit,         /* o   : quantized pitch gain                                       <Q16> */
     415             :                        Word32 *gain_code,        /* o   : quantized codebook gain                                    <Q16> */
     416             :                        Word32 *gain_code2,       /* o   : quantized codebook gain                                    <Q16> */
     417             :                        Word16 noisy_speech_flag, /* i   : noisy speech flag                                                */
     418             :                        ACELP_CbkCorr *g_coeff,   /* i   : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>  */
     419             :                        Word16 mean_ener,         /* i   : only func=0: mean_ener defined in open-loop (3 bits)        <Q8> */
     420             :                        Word32 *past_gcode,       /* o   : past gain of code                                          <Q16> */
     421             :                        Word16 *gain_inov,        /* o   : Q12 innovation gain                                        <Q12> */
     422             :                        const Word16 func_type    /* i   : algorithm: 2=gain_enc_uv_fx, 3=gain_enc_gacelp_uv              <Q0> */
     423             : )
     424             : {
     425             :     Word16 i, index, exp_L_tmp1, tmp;
     426             :     Word16 exp_gcode;
     427             :     Word16 g_code;
     428             :     Word32 L_tmp, L_tmp1;
     429             :     Word8 gacelp_uv;
     430             :     Word32 pred_nrg_frame;
     431             :     Word16 exp_gcode2, g_code2, norm_code2;
     432             :     Word16 c, c_e, c_index2, c_index2_e, c_first, c_first_e;
     433             :     Word16 s, tmp1, s1;
     434             :     Word16 index2;
     435        8060 :     const Word16 log2_scale = 16;
     436        8060 :     move16();
     437        8060 :     pred_nrg_frame = 0; /* to suppress compilation warnings */
     438        8060 :     g_code2 = 0;        /* to suppress compilation warnings */
     439        8060 :     exp_gcode2 = 0;     /* to suppress compilation warnings */
     440        8060 :     move32();
     441        8060 :     move16();
     442        8060 :     move16();
     443             : 
     444        8060 :     assert( ( func_type != FUNC_GAIN_ENC_MLESS ) );
     445             : 
     446             :     /* Debug check value (not instrumented) */
     447        8060 :     index2 = -3000;
     448        8060 :     move16();
     449             : 
     450        8060 :     gacelp_uv = 0;
     451        8060 :     move16();
     452        8060 :     if ( EQ_16( func_type, FUNC_GAIN_ENC_GACELP_UV ) )
     453             :     {
     454        8060 :         gacelp_uv = 1;
     455        8060 :         move16();
     456             :     }
     457             : 
     458             :     /*----------------------------------------------------------------*
     459             :      * - calculate the unscaled innovation energy
     460             :      * - calculate the predicted gain code
     461             :      *----------------------------------------------------------------*/
     462             : 
     463             :     /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
     464        8060 :     L_tmp = calc_gain_inov( code, lcode, NULL, NULL );
     465        8060 :     *gain_inov = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */
     466        8060 :     move16();
     467             : 
     468             :     /*----------------------------------------------------------------*
     469             :      * calculate the predicted gain code
     470             :      *----------------------------------------------------------------*/
     471        8060 :     IF( gacelp_uv != 0 )
     472             :     {
     473             :         /* pred_nrg_frame = (float)pow(10.0,mean_ener/20.0); */
     474        8060 :         L_tmp = L_mult( mean_ener, 10885 /*0.166096f * 2 Q15*/ );                       /* 6Q25 */
     475        8060 :         pred_nrg_frame = BASOP_Util_InvLog2( L_sub( L_tmp, 503316480l /*15.f Q25*/ ) ); /* 15Q16 */
     476             : 
     477             :         /* gcode = pred_nrg_frame * (*gain_inov); */
     478        8060 :         L_tmp = Mpy_32_16_1( pred_nrg_frame, *gain_inov ); /* 18Q13 */
     479        8060 :         i = norm_l( L_tmp );
     480        8060 :         g_code = round_fx_sat( L_shl( L_tmp, i ) );
     481        8060 :         exp_gcode = sub( 18, i );
     482             : 
     483             :         /* norm_code2 = 1.0f / sqrt((dot_product(code2, code2, lcode) + 0.01f) / lcode); */
     484        8060 :         L_tmp = calc_gain_inov( code2, lcode, NULL, NULL );
     485        8060 :         norm_code2 = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* Q12 */
     486             : 
     487             :         /* g_code2 = pred_nrg_frame * norm_code2; */
     488        8060 :         L_tmp = Mpy_32_16_1( pred_nrg_frame, norm_code2 ); /* 18Q13 */
     489        8060 :         i = norm_l( L_tmp );
     490        8060 :         g_code2 = round_fx_sat( L_shl_sat( L_tmp, i ) );
     491        8060 :         exp_gcode2 = sub( 18, i );
     492             :     }
     493             :     ELSE
     494             :     {
     495           0 :         g_code = *gain_inov;
     496           0 :         move16();
     497           0 :         exp_gcode = 3;
     498           0 :         move16();
     499             :     }
     500             : 
     501        8060 :     tmp = BASOP_Util_Divide1616_Scale( g_coeff->xy2, mult_r( g_coeff->y2y2, g_code ), &i ); /*Correlation based*/
     502        8060 :     L_tmp = L_shl( L_deposit_h( tmp ), add( i, sub( g_coeff->xy2_e, add( g_coeff->y2y2_e, add( exp_gcode, log2_scale ) ) ) ) );
     503             :     /* exponent of L_tmp is 16, accounted below by adding log2(2^16) */
     504             : 
     505        8060 :     index = 0;
     506        8060 :     move16();
     507             : 
     508        8060 :     IF( L_tmp > 0 )
     509             :     {
     510             :         /*index = (int)(((20.f*log10(g_code)+30.f)/1.9f)+0.5f))); */
     511             :         /* Since ((20*log10(x)+30)/1.9)+0.5 = 63 (max index) implies x is between 2^15 and 2^16,
     512             :            L_tmp might saturate at 65535 and above. That is why log2_scale is 16. */
     513        8060 :         tmp = BASOP_Util_lin2dB( L_tmp, 16, 0 ); /* Q8 */
     514             : 
     515        8060 :         IF( gacelp_uv != 0 )
     516             :         {
     517        8060 :             L_tmp = L_mult( add( tmp, 5120 /*20.0f Q8*/ ), 26214 /*1.0f/1.25f Q15*/ );
     518             :         }
     519             :         ELSE
     520             :         {
     521           0 :             L_tmp = L_mult( add( tmp, 7680 /*30.0f Q8*/ ), 17246 /*1.0f/1.9f Q15*/ );
     522             :         }
     523             : 
     524        8060 :         index = round_fx( L_shr( L_tmp, 8 ) );
     525        8060 :         index = s_max( 0, s_min( 63, index ) );
     526        8060 :         if ( gacelp_uv != 0 )
     527        8060 :             index = s_min( 31, index );
     528             :     }
     529             : 
     530             :     /* *gain_code= (float) pow(10.f,(((index*1.9f)-30.f)/20.f)); */
     531             : 
     532             :     /*----------------------------------------------------------------*
     533             :      * gcode0 = pow(10.0, gcode0/20)
     534             :      *        = pow(2, 3.321928*gcode0/20)
     535             :      *        = pow(2, 0.166096*gcode0)
     536             :      *----------------------------------------------------------------*/
     537        8060 :     IF( gacelp_uv != 0 )
     538             :     {
     539        8060 :         L_tmp = L_mac( -111465139l /*-0.166096*20.0f Q25*/, shl( index, 16 - 7 ), 6803 /*0.166096f*1.25f Q15*/ );
     540             :     }
     541             :     ELSE
     542             :     {
     543           0 :         L_tmp = L_mac( -167197708l /*-0.166096*30.0f Q25*/, shl( index, 16 - 7 ), 10341 /*0.166096f*1.9f Q15*/ );
     544             :     }
     545        8060 :     i = add( 1, extract_l( L_shr( L_tmp, 25 ) ) );
     546        8060 :     L_tmp = L_lshl( L_tmp, 6 );
     547        8060 :     L_tmp = L_and( 0x7FFFFFFF, L_tmp );
     548             : 
     549        8060 :     L_tmp = Pow2( 30, round_fx( L_tmp ) );
     550        8060 :     L_tmp = L_shl( L_tmp, sub( i, ( 31 - 16 ) ) ); /* Q16 */
     551             : 
     552        8060 :     IF( gacelp_uv != 0 )
     553             :     {
     554             :         /* *past_gcode = L_tmp * pred_nrg_frame; */
     555        8060 :         i = norm_l( L_tmp );
     556        8060 :         L_tmp1 = L_shl( L_tmp, i );
     557        8060 :         exp_L_tmp1 = sub( 15, i );
     558             : 
     559        8060 :         i = norm_l( pred_nrg_frame );
     560        8060 :         L_tmp1 = Mpy_32_32( L_tmp1, L_shl( pred_nrg_frame, i ) );
     561        8060 :         exp_L_tmp1 = add( exp_L_tmp1, sub( 15, i ) );
     562             : 
     563        8060 :         *past_gcode = L_shl( L_tmp1, sub( exp_L_tmp1, 15 ) ); /* Q16 */
     564        8060 :         move32();
     565             :     }
     566             :     ELSE
     567             :     {
     568           0 :         *past_gcode = L_tmp; /*unscaled gain*/
     569           0 :         move32();
     570             :     }
     571             : 
     572             : 
     573        8060 :     *gain_code = L_shl_sat( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 );
     574        8060 :     move32();
     575             : 
     576        8060 :     *gain_pit = 0;
     577        8060 :     move16();
     578             : 
     579        8060 :     IF( gacelp_uv != 0 )
     580             :     {
     581             :         /* c_first = 0.8f*g_coeff->xx - (*gain_code) * (*gain_code) * g_coeff->y2y2; */
     582             :         /* c_first = g_coeff->xx - (*gain_code) * (*gain_code) * g_coeff->y2y2; */
     583        8060 :         tmp = g_coeff->xx;
     584        8060 :         move16();
     585        8060 :         if ( noisy_speech_flag != 0 )
     586             :         {
     587         532 :             tmp = mult_r( 26214 /*0.8f Q15*/, tmp );
     588             :         }
     589             : 
     590        8060 :         s1 = norm_l( *gain_code );
     591        8060 :         tmp1 = round_fx_sat( L_shl( *gain_code, s1 ) );
     592        8060 :         s1 = sub( 15, s1 );
     593        8060 :         tmp1 = mult_r( mult_r( tmp1, tmp1 ), g_coeff->y2y2 );
     594             : 
     595        8060 :         c_first_e = BASOP_Util_Add_MantExp( tmp, g_coeff->xx_e,
     596        8060 :                                             negate( tmp1 ), add( g_coeff->y2y2_e, shl( s1, 1 ) ),
     597             :                                             &c_first );
     598             : 
     599        8060 :         L_tmp = Mpy_32_16_1( *gain_code, BASOP_Util_Divide1616_Scale( g_code2, g_code, &s ) );
     600        8060 :         L_tmp = L_shl( L_tmp, sub( sub( add( s, exp_gcode2 ), exp_gcode ), 2 ) ); /* Q16 */
     601        8060 :         L_tmp1 = L_add( L_tmp, 0 );
     602             : 
     603        8060 :         s1 = norm_l( *gain_code );
     604        8060 :         tmp1 = round_fx_sat( L_shl( *gain_code, s1 ) );
     605        8060 :         s1 = sub( 15, s1 );
     606             : 
     607        8060 :         c_index2 = 0x7FFF;
     608        8060 :         move16();
     609        8060 :         c_index2_e = 127;
     610        8060 :         move16();
     611       40300 :         FOR( i = 0; i < 4; i++ )
     612             :         {
     613             :             /* c = c_first - L_tmp1 * (L_tmp1 * g_coeff->y1y1 + 2 * (*gain_code) * g_coeff->y1y2); */
     614       32240 :             s = norm_l( L_tmp1 );
     615       32240 :             tmp = round_fx_sat( L_shl_sat( L_tmp1, s ) );
     616       32240 :             s = sub( 15, s );
     617             : 
     618       32240 :             c_e = BASOP_Util_Add_MantExp( mult_r( tmp, g_coeff->y1y1 ), add( s, g_coeff->y1y1_e ),
     619       32240 :                                           mult_r( tmp1, g_coeff->y1y2 ), add( add( s1, g_coeff->y1y2_e ), 1 ),
     620             :                                           &c );
     621       32240 :             c = mult_r( c, tmp );
     622       32240 :             c_e = add( c_e, s );
     623       32240 :             c_e = BASOP_Util_Add_MantExp( c_first, c_first_e, negate( c ), c_e, &c );
     624             : 
     625       32240 :             tmp = 0;
     626       32240 :             move16();
     627       32240 :             if ( LT_16( c_e, c_index2_e ) )
     628             :             {
     629       17694 :                 tmp = 1;
     630       17694 :                 move16();
     631             :             }
     632       32240 :             test();
     633       32240 :             if ( EQ_16( c_e, c_index2_e ) && LT_16( abs_s( c ), abs_s( c_index2 ) ) )
     634             :             {
     635        9188 :                 tmp = 1;
     636        9188 :                 move16();
     637             :             }
     638             : 
     639       32240 :             IF( tmp != 0 )
     640             :             {
     641       26882 :                 index2 = i;
     642       26882 :                 move16();
     643       26882 :                 c_index2 = c;
     644       26882 :                 move16();
     645       26882 :                 c_index2_e = c_e;
     646       26882 :                 move16();
     647       26882 :                 *gain_code2 = L_tmp1;
     648       26882 :                 move32();
     649             :             }
     650             : 
     651       32240 :             L_tmp1 = L_add( L_tmp1, L_tmp );
     652             :         }
     653             : 
     654             :         /* check if value was uninitialized */
     655        8060 :         assert( index2 != -3000 );
     656        8060 :         index = add( index, shl( index2, 5 ) );
     657             :     }
     658             : 
     659             : 
     660        8060 :     return index;
     661             : }

Generated by: LCOV version 1.14