LCOV - code coverage report
Current view: top level - lib_enc - lp_exc_e_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 217 242 89.7 %
Date: 2025-05-03 01:55:50 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "cnst.h"    /* Common constants                       */
       7             : //#include "prot_fx.h"       /* Function prototypes                    */
       8             : #include "basop_util.h"
       9             : #include "prot_fx.h"     /* Function prototypes                    */
      10             : #include "prot_fx_enc.h" /* Function prototypes                    */
      11             : 
      12             : /*-------------------------------------------------------------------*
      13             :  * Local constants
      14             :  *-------------------------------------------------------------------*/
      15             : 
      16             : #define GAIN_PIT_MAX 19661
      17             : 
      18             : 
      19             : /*-------------------------------------------------------------------*
      20             :  * Local function prototypes
      21             :  *-------------------------------------------------------------------*/
      22             : 
      23             : static Word16 adpt_enr_fx( const Word16 codec_mode, const Word16 *exc, const Word16 *h1, Word16 *y1, const Word16 L_subfr, Word16 *gain, Word16 *g_corr, const Word16 clip_gain, const Word16 *xn, Word16 *xn2, Word16 *exp_ener, Word16 use_prev_sf_pit_gain );
      24             : 
      25             : /*-------------------------------------------------------------------*
      26             :  * function lp_filt_exc_enc_fx()
      27             :  *
      28             :  * Low-pass filtering of the adaptive excitation
      29             :  * Innovation target construction
      30             :  * Gain quantization limitation
      31             :  *-------------------------------------------------------------------*/
      32             : 
      33        6156 : Word16 lp_filt_exc_enc_fx(
      34             :     const Word16 codec_mode, /* i  : MODE1 or MODE2                                  Q0 */
      35             :     const Word16 coder_type, /* i  : coding type                                     Q0 */
      36             :     const Word16 i_subfr,    /* i  : subframe index                                  Q0 */
      37             :     Word16 *exc,             /* i/o: pointer to excitation signal frame              Q_new */
      38             :     const Word16 *h1,        /* i  : weighted filter input response                  Q(14+shift) */
      39             :     const Word16 *xn,        /* i  : target vector                                   Q_new-1+shift */
      40             :     Word16 *y1,              /* o  : zero-memory filtered adaptive excitation        Q_new-1+shift */
      41             :     Word16 *xn2,             /* o  : target vector for innovation search             Q_new-1+shift */
      42             :     const Word16 L_subfr,    /* i  : length of vectors for gain quantization         Q0 */
      43             :     const Word16 L_frame,    /* i  : frame size                                      Q0 */
      44             :     Word16 *g_corr,          /* o  : ACELP correlation values                        mant/exp */
      45             :     const Word16 clip_gain,  /* i  : adaptive gain clipping flag                     Q0 */
      46             :     Word16 *gain_pit,        /* o  : adaptive excitation gain                        Q14 */
      47             :     Word16 *lp_flag          /* i/o: mode selection                                  Q0 */
      48             : )
      49             : {
      50             :     Word16 gain1, gain2, g_corr2[4], exc_tmp[5 * L_SUBFR], xn2_tmp[5 * L_SUBFR];
      51             :     Word16 y1_tmp[5 * L_SUBFR];
      52             :     Word16 select, i, exp_ener, exp_ener1;
      53             :     Word16 wtmp, wtmp1;
      54             :     Word32 Ltmp;
      55             : 
      56        6156 :     Word16 use_prev_sf_pit_gain = 0; // Q0
      57        6156 :     move16();
      58             : 
      59        6156 :     gain1 = 0;
      60        6156 :     move16();
      61        6156 :     gain2 = 0;
      62        6156 :     move16();
      63             : 
      64             :     /*----------------------------------------------------------------*
      65             :      * Find the target energy if the adaptive exc. is not filtered
      66             :      *----------------------------------------------------------------*/
      67        6156 :     test();
      68        6156 :     IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) )
      69             :     {
      70           0 :         use_prev_sf_pit_gain = 1; // Q0
      71           0 :         move16();
      72             :     }
      73        6156 :     exp_ener = 0;
      74        6156 :     move16();
      75        6156 :     wtmp = 0;
      76        6156 :     move16();
      77        6156 :     test();
      78        6156 :     IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) )
      79             :     {
      80        6156 :         wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener
      81        6156 :         move16();
      82             :     }
      83             : 
      84             :     /*----------------------------------------------------------------*
      85             :      * Filter the adaptive excitation
      86             :      * Find the target energy if the adapt. exc. is filtered
      87             :      *----------------------------------------------------------------*/
      88             : 
      89        6156 :     exp_ener1 = 0;
      90        6156 :     move16();
      91        6156 :     wtmp1 = 0;
      92        6156 :     move16();
      93        6156 :     test();
      94        6156 :     IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) )
      95             :     {
      96        6142 :         test();
      97        6142 :         IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) )
      98             :         {
      99           0 :             FOR( i = 0; i < L_subfr; i++ )
     100             :             {
     101           0 :                 Ltmp = L_mult( 6881, exc[i - 1 + i_subfr] ); /* constants in Q15 */
     102           0 :                 Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] );
     103           0 :                 Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] );
     104           0 :                 exc_tmp[i] = round_fx( Ltmp );
     105           0 :                 move16();
     106             :             }
     107             :         }
     108             :         ELSE
     109             :         {
     110      399230 :             FOR( i = 0; i < L_subfr; i++ )
     111             :             {
     112      393088 :                 Ltmp = L_mult( 5898, exc[i - 1 + i_subfr] ); /* constants in Q15 */
     113      393088 :                 Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] );
     114      393088 :                 Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] );
     115      393088 :                 exc_tmp[i] = round_fx( Ltmp );
     116      393088 :                 move16();
     117             :             }
     118             :         }
     119             : 
     120        6142 :         wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1
     121             :     }
     122             : 
     123        6156 :     if ( LT_16( exp_ener, exp_ener1 ) )
     124             :     {
     125          72 :         wtmp = shr( wtmp, 1 ); // exp_ener + 1
     126             :     }
     127             : 
     128        6156 :     if ( GT_16( exp_ener, exp_ener1 ) )
     129             :     {
     130         374 :         wtmp1 = shr( wtmp1, 1 ); // exp_ener1 + 1
     131             :     }
     132             : 
     133             :     /*-----------------------------------------------------------------*
     134             :      * use the best prediction (minimize quadratic error)
     135             :      *-----------------------------------------------------------------*/
     136             : 
     137        6156 :     test();
     138        6156 :     test();
     139        6156 :     IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) )
     140             :     {
     141             :         /* use the LP filter for pitch excitation prediction */
     142        4523 :         select = LOW_PASS;
     143        4523 :         move16();
     144        4523 :         Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new
     145        4523 :         Copy( y1_tmp, y1, L_subfr );             // Q_new-1+shift
     146        4523 :         Copy( xn2_tmp, xn2, L_subfr );           // Q_new-1+shift
     147             : 
     148        4523 :         IF( use_prev_sf_pit_gain == 0 )
     149             :         {
     150        4523 :             *gain_pit = gain2; // Q14
     151        4523 :             move16();
     152        4523 :             g_corr[0] = g_corr2[0];
     153        4523 :             move16();
     154        4523 :             g_corr[1] = g_corr2[1];
     155        4523 :             move16();
     156        4523 :             g_corr[2] = g_corr2[2];
     157        4523 :             move16();
     158        4523 :             g_corr[3] = g_corr2[3];
     159        4523 :             move16();
     160             :         }
     161             :     }
     162             :     ELSE
     163             :     {
     164             :         /* no LP filter used for pitch excitation prediction */
     165        1633 :         select = FULL_BAND;
     166        1633 :         move16();
     167        1633 :         IF( use_prev_sf_pit_gain == 0 )
     168             :         {
     169        1633 :             *gain_pit = gain1; // Q14
     170        1633 :             move16();
     171             :         }
     172             :     }
     173             : 
     174        6156 :     return select;
     175             : }
     176             : 
     177      589952 : Word16 lp_filt_exc_enc_ivas_fx(
     178             :     const Word16 codec_mode, /* i  : MODE1 or MODE2                                  Q0 */
     179             :     const Word16 coder_type, /* i  : coding type                                     Q0 */
     180             :     const Word16 i_subfr,    /* i  : subframe index                                  Q0 */
     181             :     Word16 *exc,             /* i/o: pointer to excitation signal frame              Q_new */
     182             :     const Word16 *h1,        /* i  : weighted filter input response                  Q(15) */
     183             :     const Word16 *xn,        /* i  : target vector                                   Q_new-1+shift */
     184             :     Word16 *y1,              /* o  : zero-memory filtered adaptive excitation        Q_new-1+shift */
     185             :     Word16 *xn2,             /* o  : target vector for innovation search             Q_new-1+shift */
     186             :     const Word16 L_subfr,    /* i  : length of vectors for gain quantization         Q0 */
     187             :     const Word16 L_frame,    /* i  : frame size                                      Q0 */
     188             :     Word16 *g_corr,          /* o  : ACELP correlation values                        mant/exp */
     189             :     const Word16 clip_gain,  /* i  : adaptive gain clipping flag                     Q0 */
     190             :     Word16 *gain_pit,        /* o  : adaptive excitation gain                        Q14 */
     191             :     Word16 *lp_flag          /* i/o: mode selection                                  Q0 */
     192             : )
     193             : {
     194             :     Word16 gain1, gain2, g_corr2[4], exc_tmp[5 * L_SUBFR], xn2_tmp[5 * L_SUBFR];
     195             :     Word16 y1_tmp[5 * L_SUBFR];
     196             :     Word16 select, i, exp_ener, exp_ener1;
     197             :     Word16 wtmp, wtmp1;
     198             :     Word32 Ltmp;
     199             : 
     200      589952 :     Word16 use_prev_sf_pit_gain = 0; // Q0
     201      589952 :     move16();
     202             : 
     203      589952 :     gain1 = 0;
     204      589952 :     move16();
     205      589952 :     gain2 = 0;
     206      589952 :     move16();
     207             : 
     208             :     /*----------------------------------------------------------------*
     209             :      * Find the target energy if the adaptive exc. is not filtered
     210             :      *----------------------------------------------------------------*/
     211      589952 :     test();
     212      589952 :     IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) )
     213             :     {
     214           0 :         use_prev_sf_pit_gain = 1; // Q0
     215           0 :         move16();
     216             :     }
     217      589952 :     exp_ener = 0;
     218      589952 :     move16();
     219      589952 :     wtmp = 0;
     220      589952 :     move16();
     221      589952 :     test();
     222      589952 :     IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) )
     223             :     {
     224      549111 :         IF( EQ_16( use_prev_sf_pit_gain, 1 ) )
     225             :         {
     226           0 :             wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener
     227             :         }
     228             :         ELSE
     229             :         {
     230      549111 :             wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener
     231             :         }
     232             :     }
     233             : 
     234             :     /*----------------------------------------------------------------*
     235             :      * Filter the adaptive excitation
     236             :      * Find the target energy if the adapt. exc. is filtered
     237             :      *----------------------------------------------------------------*/
     238             : 
     239      589952 :     exp_ener1 = 0;
     240      589952 :     move16();
     241      589952 :     wtmp1 = 0;
     242      589952 :     move16();
     243      589952 :     test();
     244      589952 :     IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) )
     245             :     {
     246      530488 :         test();
     247      530488 :         IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) )
     248             :         {
     249           0 :             FOR( i = 0; i < L_subfr; i++ )
     250             :             {
     251           0 :                 Ltmp = L_mult( 6881, exc[i - 1 + i_subfr] ); /* constants in Q15 */
     252           0 :                 Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] );
     253           0 :                 Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] );
     254           0 :                 exc_tmp[i] = round_fx( Ltmp );
     255           0 :                 move16();
     256             :             }
     257             :         }
     258             :         ELSE
     259             :         {
     260    34481720 :             FOR( i = 0; i < L_subfr; i++ )
     261             :             {
     262    33951232 :                 Ltmp = L_mult( 5898, exc[i - 1 + i_subfr] ); /* constants in Q15 */
     263    33951232 :                 Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] );
     264    33951232 :                 Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] );
     265    33951232 :                 exc_tmp[i] = round_fx( Ltmp );
     266    33951232 :                 move16();
     267             :             }
     268             :         }
     269      530488 :         IF( EQ_16( use_prev_sf_pit_gain, 1 ) )
     270             :         {
     271           0 :             wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1
     272             :         }
     273             :         ELSE
     274             :         {
     275      530488 :             wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1
     276             :         }
     277             :     }
     278             : 
     279      589952 :     if ( LT_16( exp_ener, exp_ener1 ) )
     280             :     {
     281       46132 :         wtmp = shr( wtmp, 1 );
     282             :     }
     283             : 
     284      589952 :     if ( GT_16( exp_ener, exp_ener1 ) )
     285             :     {
     286       76727 :         wtmp1 = shr( wtmp1, 1 );
     287             :     }
     288             : 
     289             :     /*-----------------------------------------------------------------*
     290             :      * use the best prediction (minimize quadratic error)
     291             :      *-----------------------------------------------------------------*/
     292             : 
     293      589952 :     test();
     294      589952 :     test();
     295      589952 :     IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) )
     296             :     {
     297             :         /* use the LP filter for pitch excitation prediction */
     298      369514 :         select = LOW_PASS;
     299      369514 :         move16();
     300      369514 :         Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new
     301      369514 :         Copy( y1_tmp, y1, L_subfr );             // Q_new-1+shift
     302      369514 :         Copy( xn2_tmp, xn2, L_subfr );           // Q_new-1+shift
     303             : 
     304      369514 :         IF( use_prev_sf_pit_gain == 0 )
     305             :         {
     306      369514 :             *gain_pit = gain2; // Q14
     307      369514 :             move16();
     308      369514 :             g_corr[0] = g_corr2[0];
     309      369514 :             move16();
     310      369514 :             g_corr[1] = g_corr2[1];
     311      369514 :             move16();
     312      369514 :             g_corr[2] = g_corr2[2];
     313      369514 :             move16();
     314      369514 :             g_corr[3] = g_corr2[3];
     315      369514 :             move16();
     316             :         }
     317             :     }
     318             :     ELSE
     319             :     {
     320             :         /* no LP filter used for pitch excitation prediction */
     321      220438 :         select = FULL_BAND;
     322      220438 :         move16();
     323      220438 :         IF( use_prev_sf_pit_gain == 0 )
     324             :         {
     325      220438 :             *gain_pit = gain1; // Q14
     326      220438 :             move16();
     327             :         }
     328             :     }
     329             : 
     330      589952 :     return select;
     331             : }
     332             : 
     333             : /*-------------------------------------------------------------------*
     334             :  * adpt_enr_fx()
     335             :  *
     336             :  * Find  adaptive excitation energy
     337             :  * This serves to decide about the filtering of the adaptive excitation
     338             :  *-------------------------------------------------------------------*/
     339             : 
     340     1091897 : static Word16 adpt_enr_fx(                          /* o  : adaptive excitation energy             mant     */
     341             :                            const Word16 codec_mode, /* i  : MODE1 or MODE2                                  */
     342             :                            const Word16 *exc,       /* i  : excitation vector                      Q_new    */
     343             :                            const Word16 *h1,        /* i  : impuls response                        Q15      */
     344             :                            Word16 *y1,              /* o  : zero-memory filtered adpt. excitation  12 bits  */
     345             :                            const Word16 L_subfr,    /* i  : vector length                                                                   */
     346             :                            Word16 *gain,            /* o  : subframe adaptive gain                 Q14      */
     347             :                            Word16 *g_corr,          /* o  : correlations for adptive gain           mant/exp*/
     348             :                            const Word16 clip_gain,  /* i  : adaptive gain clipping flag             Q0          */
     349             :                            const Word16 *xn,        /* i  : adaptive codebook target               12 bits      Q_new-1+shift*/
     350             :                            Word16 *xn2,             /* o  : algebraic codebook target              12 bits      Q_new-1+shift*/
     351             :                            Word16 *exp_ener         /* o  : adaptive excitation energy             exp      */
     352             :                            ,
     353             :                            Word16 use_prev_sf_pit_gain /* i : flag to use prev sf pitch gain or not */
     354             : )
     355             : {
     356             :     Word16 ener, i;
     357             :     Word16 exc_tmp[L_FRAME16k], xn_tmp[L_FRAME16k];
     358             :     Word32 Ltmp;
     359             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL /* Critical Overflow */
     360     1091897 :     Flag Overflow = 0;
     361             : #endif
     362             : 
     363     1091897 :     Overflow = 0;
     364     1091897 :     move16();
     365     1091897 :     Overflow =
     366     1091897 :         conv_fx( exc, h1, y1, L_subfr );
     367             : 
     368     1091897 :     IF( use_prev_sf_pit_gain == 0 )
     369             :     {
     370     1091897 :         *gain = corr_xy1_fx( xn, y1, g_corr, L_subfr, codec_mode == MODE2, &Overflow );
     371     1091897 :         move16();
     372             : 
     373     1091897 :         test();
     374     1091897 :         IF( GT_16( L_subfr, L_SUBFR ) && Overflow )
     375             :         {
     376       44482 :             FOR( i = 0; i < L_subfr; i++ )
     377             :             {
     378       44224 :                 exc_tmp[i] = mult( exc[i], 8192 /*0.25.Q15*/ ); // Q_new
     379       44224 :                 move16();
     380       44224 :                 xn_tmp[i] = mult( xn[i], 8192 /*0.25.Q15*/ ); // Q_new
     381       44224 :                 move16();
     382             :             }
     383         258 :             Overflow = 0;
     384             : 
     385         258 :             conv_fx( exc_tmp, h1, y1, L_subfr );
     386         258 :             *gain = corr_xy1_fx( xn_tmp, y1, g_corr, L_subfr, codec_mode == MODE2, &Overflow );
     387         258 :             move16();
     388             :         }
     389             : 
     390             :         /* clip gain, if necessary to avoid problems at decoder */
     391     1091897 :         test();
     392     1091897 :         if ( EQ_16( clip_gain, 1 ) && GT_16( *gain, 15565 ) ) /* constant in Q14 */
     393             :         {
     394        4251 :             *gain = 15565; // 0.95.Q14
     395        4251 :             move16();
     396             :         }
     397             : 
     398     1091897 :         test();
     399     1091897 :         IF( EQ_16( clip_gain, 2 ) && GT_16( *gain, 10650 ) ) // 0.65.Q14
     400             :         {
     401        2927 :             *gain = 10650; // 0.65.Q14
     402        2927 :             move16();
     403             :         }
     404             :     }
     405             : 
     406             :     /* find energy of new target xn2[] */
     407     1091897 :     updt_tar_fx( xn, xn2, y1, *gain, L_subfr );
     408             : 
     409     1091897 :     IF( GT_16( L_subfr, L_SUBFR ) )
     410             :     {
     411             :         /* could possibly happen in GSC */
     412       15046 :         Ltmp = Calc_Energy_Autoscaled( xn2, 0, L_subfr, exp_ener );
     413       15046 :         i = norm_l( Ltmp );
     414       15046 :         ener = extract_h( L_shl( Ltmp, i ) ); // exp_ener
     415       15046 :         i = sub( 31, i );
     416       15046 :         *exp_ener = sub( i, *exp_ener );
     417       15046 :         move16();
     418             :     }
     419             :     ELSE
     420             :     {
     421     1076851 :         ener = extract_h( Dot_product12( xn2, xn2, L_SUBFR, exp_ener ) ); // Q15
     422             :     }
     423             : 
     424     1091897 :     return ener;
     425             : }
     426             : 
     427             : /*-------------------------------------------------------------------*
     428             :  * corr_xy1()
     429             :  *
     430             :  * Find the correlations between the target xn[] and the filtered adaptive
     431             :  * codebook excitation y1[]. ( <y1,y1>  and -2<xn,y1> )
     432             :  *-------------------------------------------------------------------*/
     433             : 
     434     1167461 : Word16 corr_xy1_fx(                        /* o  : pitch gain  (0..GAIN_PIT_MAX)         */
     435             :                     const Word16 xn_1[],   /* i  : target signal                         Q_new*/
     436             :                     const Word16 y1_1[],   /* i  : filtered adaptive codebook excitation 12 bits*/
     437             :                     Word16 g_corr[],       /* o  : correlations <y1,y1>  and -2<xn,y1>   mant/exp*/
     438             :                     const Word16 L_subfr,  /* i  : vector length                         */
     439             :                     const Word16 norm_flag /* i  : flag for constraining pitch contribution */
     440             :                     ,
     441             :                     Flag *Overflow_out /* o :  propagating the Overflow flag to upper level */
     442             : )
     443             : {
     444             :     Word16 i;
     445             :     Word16 tmp, xx, xy, yy, exp_xy, exp_xx, exp_yy, exp_div, gain, gain_p_snr;
     446             :     Word32 Ltmp1, Ltmp2;
     447             :     Word16 xn[L_FRAME16k], y1[L_FRAME16k];
     448             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     449     1167461 :     Flag Overflow = 0;
     450             : #endif
     451             : 
     452             :     /*----------------------------------------------------------------*
     453             :      * Find the ACELP correlations and the pitch gain
     454             :      *----------------------------------------------------------------*/
     455             : 
     456             :     /* Compute scalar product <y1[],y1[]> */
     457     1167461 :     Copy( xn_1, xn, L_subfr ); // Q_new
     458     1167461 :     Copy( y1_1, y1, L_subfr );
     459     1167461 :     Overflow = 0;
     460     1167461 :     move16();
     461     1167461 :     Ltmp1 = Dot_product12_o( y1, y1, L_subfr, &exp_yy, &Overflow );
     462     1167461 :     *Overflow_out |= Overflow;
     463     1167461 :     move16();
     464     1167461 :     IF( Overflow )
     465             :     {
     466       82008 :         FOR( i = 0; i < L_subfr; i++ )
     467             :         {
     468       80896 :             xn[i] = mult_r( xn_1[i], 4096 /*0.125.Q15*/ ); // Q-new
     469       80896 :             move16();
     470       80896 :             y1[i] = mult_r( y1_1[i], 4096 /*0.125.Q15*/ );
     471       80896 :             move16();
     472             :         }
     473             : 
     474        1112 :         Ltmp1 = Dot_product12( y1, y1, L_subfr, &exp_yy );
     475        1112 :         exp_yy = add( exp_yy, 6 );
     476        1112 :         yy = extract_h( Ltmp1 );
     477             : 
     478             :         /* Compute scalar product <xn[],y1[]> */
     479        1112 :         Ltmp2 = Dot_product12( xn, y1, L_subfr, &exp_xy );
     480        1112 :         xy = extract_h( Ltmp2 );
     481        1112 :         exp_xy = add( exp_xy, 6 );
     482             : 
     483        1112 :         g_corr[0] = yy;
     484        1112 :         move16();
     485        1112 :         g_corr[1] = exp_yy;
     486        1112 :         move16();
     487             :         /* -2.0*temp1 + 0.01 is done in Gain_enc_2 function */
     488        1112 :         g_corr[2] = xy;
     489        1112 :         move16();
     490        1112 :         g_corr[3] = exp_xy;
     491        1112 :         move16();
     492             :     }
     493             :     ELSE
     494             :     {
     495     1166349 :         yy = extract_h( Ltmp1 ); // exp_yy
     496             :         /* Ltmp1 = L_shr(Ltmp1, sub(30, exp_yy));*/
     497             : 
     498             :         /* Compute scalar product <xn[],y1[]> */
     499     1166349 :         Ltmp2 = Dot_product12_o( xn, y1, L_subfr, &exp_xy, &Overflow );
     500     1166349 :         *Overflow_out |= Overflow;
     501     1166349 :         move16();
     502     1166349 :         xy = extract_h( Ltmp2 );
     503             :         /* Ltmp2 = L_shr(Ltmp2, sub(30, exp_xy));*/
     504             : 
     505     1166349 :         g_corr[0] = yy;
     506     1166349 :         move16();
     507     1166349 :         g_corr[1] = exp_yy;
     508     1166349 :         move16();
     509             :         /* -2.0*temp1 + 0.01 is done in Gain_enc_2 function*/
     510     1166349 :         g_corr[2] = xy; // exp_xy
     511     1166349 :         move16();
     512     1166349 :         g_corr[3] = exp_xy;
     513     1166349 :         move16();
     514             :     }
     515             : 
     516             :     /* find pitch gain and bound it by [0,GAIN_PIT_MAX] */
     517     1167461 :     test();
     518     1167461 :     IF( xy >= 0 && NE_16( s_or( yy, xy ), 16384 ) )
     519             :     {
     520             :         /* compute gain = xy/yy */
     521     1114458 :         xy = shr( xy, 1 );      /* be sure that xy < yy */
     522     1114458 :         gain = div_s( xy, yy ); // Q15
     523     1114458 :         i = sub( exp_xy, exp_yy );
     524     1114458 :         gain = shl_o( gain, i, &Overflow ); /* saturation can occur here */
     525     1114458 :         *Overflow_out |= Overflow;
     526     1114458 :         move16();
     527             : 
     528     1114458 :         gain = s_max( gain, 0 );
     529     1114458 :         gain = s_min( gain, GAIN_PIT_MAX ); /* 1.2 in Q14 */
     530             :     }
     531             :     ELSE
     532             :     {
     533       53003 :         gain = 0;
     534       53003 :         move16();
     535             :     }
     536             : 
     537             :     /* Limit the energy of pitch contribution */
     538     1167461 :     IF( norm_flag )
     539             :     {
     540             :         /*that part of code seems never used*/
     541             :         /* Compute scalar product <xn[],xn[]> */
     542           0 :         xx = round_fx( Dot_product12_offs( xn, xn, L_subfr, &exp_xx, 1 ) );
     543             : 
     544             :         /* gain_p_snr = sqrt(<xn,xn>/<y1,y1>) */
     545           0 :         tmp = BASOP_Util_Divide1616_Scale( xx, yy, &exp_div );
     546           0 :         exp_xx = add( sub( exp_xx, exp_yy ), exp_div );
     547           0 :         tmp = Sqrt16( tmp, &exp_xx ); // exp_xx
     548             : 
     549             :         /* Note: shl works as shl or shr. */
     550           0 :         exp_xx = sub( exp_xx, 1 );
     551             :         BASOP_SATURATE_WARNING_OFF_EVS
     552           0 :         gain_p_snr = round_fx_sat( L_shl_sat( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_xx ) );
     553             :         BASOP_SATURATE_WARNING_ON_EVS
     554             : 
     555           0 :         gain = s_min( gain, gain_p_snr ); // Q14
     556             :     }
     557             : 
     558     1167461 :     return gain; // Q14
     559             : }

Generated by: LCOV version 1.14