LCOV - code coverage report
Current view: top level - lib_enc - pitch_ol2_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ cede165d26d1b794bfc5f5f6f9ec19d4d64a9a3b Lines: 314 323 97.2 %
Date: 2025-11-01 03:16:20 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 "options.h" /* Compilation switches                   */
       7             : #include "cnst.h"    /* Common constants                       */
       8             : #include "rom_enc.h" /* Encoder static table prototypes        */
       9             : #include "rom_com.h" /* Encoder static table prototypes        */
      10             : #include "rom_dec.h"
      11             : #include "prot_fx.h"     /* Function prototypes                    */
      12             : #include "prot_fx_enc.h" /* Function prototypes                    */
      13             : 
      14             : 
      15             : /*-------------------------------------------------------------------*
      16             :  * Local constants
      17             :  *-------------------------------------------------------------------*/
      18             : 
      19             : #define MAX_DELTA   16 /* half-length of the delta search      */
      20             : #define COR_BUF_LEN ( L_INTERPOL1 * 2 + MAX_DELTA * 2 + 1 )
      21             : 
      22             : /*-------------------------------------------------------------------*
      23             :  * pitch_ol2()
      24             :  *
      25             :  * Open-loop pitch precision improvement with 1/4 resolution
      26             :  * The pitch is searched in the interval <pitch_ol-delta, pitch_ol+delta),
      27             :  * i.e. the value pitch_ol + delta is not a part of the interval
      28             :  *-------------------------------------------------------------------*/
      29     1187384 : void pitch_ol2_fx(
      30             :     const Word16 pit_min,  /* i  : minimum pitch value (20 or 29)                   */
      31             :     const Word16 pitch_ol, /* i  : pitch to be improved                             */
      32             :     Word16 *pitch_fr_fx,
      33             :     /* o  : adjusted 1/4 fractional pitch                    */ /*Q7*/
      34             :     Word16 *voicing_fr_fx,
      35             :     /* o  : adjusted 1/4 fractional voicing                  */ /*Q15*/
      36             :     const Word16 pos,                                           /* i  : position in frame where to calculate the improv. */
      37             :     const Word16 *wsp_fx,
      38             :     /* i  : weighted speech for current frame and look-ahead */ /*Q_new-1+shift*/
      39             :     const Word16 delta,                                         /* i  : delta for pitch search (2 or 7)                  */
      40             :     const Word16 element_mode                                   /* i  : EVS or IVAS                                      */
      41             : )
      42             : {
      43             :     Word16 i, t, step, fraction, t0_min, t0_max, t_min, t_max;
      44             :     const Word16 *pt_wsp_fx;
      45             :     Word16 wsp_fr_fx[L_SUBFR];
      46             :     Word16 temp_fx, cor_max_fx, cor_fx[COR_BUF_LEN], *pt_cor_fx;
      47             :     Word32 cor_32[COR_BUF_LEN], *pt_cor_32, t0, t1;
      48             :     Word16 t0s, t1s;
      49             :     Word16 exp3;
      50             :     Word32 R1, R2;
      51             :     Word16 R0, exp_R0, exp_R1, exp_R2, j;
      52             :     Word16 pit_max;
      53             : 
      54             :     /* initialization */
      55     1187384 :     pit_max = PIT_MAX;
      56     1187384 :     move16();
      57     1187384 :     t0_min = sub( pitch_ol, delta );
      58     1187384 :     t0_max = add( pitch_ol, sub( delta, 1 ) );
      59     1187384 :     t0_min = s_max( t0_min, pit_min );
      60     1187384 :     t_min = sub( t0_min, L_INTERPOL1 );
      61             : 
      62     1187384 :     t0_max = s_min( t0_max, pit_max );
      63     1187384 :     t_max = add( t0_max, L_INTERPOL1 );
      64             : 
      65     1187384 :     pt_wsp_fx = wsp_fx + pos;
      66     1187384 :     pt_cor_32 = cor_32;
      67     1187384 :     t1 = L_deposit_l( 0 );
      68    26701108 :     FOR( t = t_min; t <= t_max; t++ )
      69             :     {
      70    25513724 :         t0 = Dot_product( pt_wsp_fx, pt_wsp_fx - t, L_SUBFR );
      71    25513724 :         *pt_cor_32++ = t0;
      72    25513724 :         move32();
      73    25513724 :         t0 = L_abs( t0 );
      74    25513724 :         t1 = L_max( t1, t0 );
      75             :     }
      76     1187384 :     exp3 = norm_l( t1 );
      77     1187384 :     pt_cor_32 = cor_32;
      78     1187384 :     pt_cor_fx = cor_fx;
      79    26701108 :     FOR( t = t_min; t <= t_max; t++ )
      80             :     {
      81    25513724 :         t0 = L_shl_sat( *pt_cor_32++, exp3 );
      82    25513724 :         *pt_cor_fx++ = round_fx_sat( t0 );
      83    25513724 :         move16();
      84             :     }
      85             : 
      86     1187384 :     pt_cor_fx = cor_fx + L_INTERPOL1;
      87     1187384 :     cor_max_fx = *pt_cor_fx++;
      88     1187384 :     move16();
      89     1187384 :     t1s = t0_min;
      90     1187384 :     move16();
      91    16014652 :     FOR( t = t0_min + 1; t <= t0_max; t++ )
      92             :     {
      93    14827268 :         if ( GT_16( *pt_cor_fx, cor_max_fx ) )
      94             :         {
      95     5895211 :             t1s = t;
      96     5895211 :             move16();
      97             :         }
      98    14827268 :         cor_max_fx = s_max( cor_max_fx, *pt_cor_fx );
      99    14827268 :         pt_cor_fx++;
     100             :     }
     101             : 
     102             :     /*----------------------------------------------------------------*
     103             :      * Search fractionnal pitch with 1/4 subsample resolution.
     104             :      * search the fractions around t0 and choose the one which maximizes
     105             :      * the interpolated normalized correlation.
     106             :      *----------------------------------------------------------------*/
     107     1187384 :     pt_cor_fx = cor_fx + sub( L_INTERPOL1, t0_min );
     108     1187384 :     t0s = t1s;
     109     1187384 :     move16();
     110             : 
     111     1187384 :     step = 1;
     112     1187384 :     move16(); /* 1/4 subsample resolution */
     113     1187384 :     fraction = 1;
     114     1187384 :     move16();
     115             : 
     116     1187384 :     IF( NE_16( t0s, t0_min ) ) /* Process negative fractions */
     117             :     {
     118     1088612 :         t0s = sub( t0s, 1 );
     119     1088612 :         cor_max_fx = Interpol_4( &pt_cor_fx[t0s], fraction );
     120     3265836 :         FOR( i = fraction + step; i <= 3; i += step )
     121             :         {
     122     2177224 :             temp_fx = Interpol_4( &pt_cor_fx[t0s], i );
     123     2177224 :             if ( GT_16( temp_fx, cor_max_fx ) )
     124             :             {
     125     2038250 :                 fraction = i;
     126     2038250 :                 move16();
     127             :             }
     128     2177224 :             cor_max_fx = s_max( temp_fx, cor_max_fx );
     129             :         }
     130             :     }
     131             :     ELSE /* Limit case */
     132             :     {
     133       98772 :         fraction = 0;
     134       98772 :         move16();
     135       98772 :         cor_max_fx = Interpol_4( &pt_cor_fx[t0s], fraction );
     136       98772 :         move16();
     137             :     }
     138     5936920 :     FOR( i = 0; i <= 3; i += step ) /* Process positive fractions */
     139             :     {
     140     4749536 :         temp_fx = Interpol_4( &pt_cor_fx[t1s], i );
     141             : 
     142     4749536 :         IF( GT_16( temp_fx, cor_max_fx ) )
     143             :         {
     144     1379661 :             cor_max_fx = temp_fx;
     145     1379661 :             move16();
     146     1379661 :             fraction = i;
     147     1379661 :             move16();
     148     1379661 :             t0s = t1s;
     149     1379661 :             move16();
     150             :         }
     151             :     }
     152             : 
     153     1187384 :     *pitch_fr_fx = shl( add( shl( t0s, 2 ), fraction ), 4 );
     154     1187384 :     move16(); /*Q7*/
     155             : 
     156     1187384 :     IF( NE_32( t1, 1L ) )
     157             :     {
     158     1172011 :         IF( element_mode != EVS_MONO )
     159             :         {
     160     1163617 :             pred_lt4_ivas_fx( pt_wsp_fx, wsp_fr_fx, t0s, fraction, L_SUBFR, L_pitch_inter4_1, 4, PIT_UP_SAMP );
     161             :         }
     162             :         ELSE
     163             :         {
     164        8394 :             pred_lt4( pt_wsp_fx, wsp_fr_fx, t0s, fraction, L_SUBFR, pitch_inter4_1, 4, PIT_UP_SAMP );
     165             :         }
     166             : 
     167     1172011 :         R0 = cor_max_fx;
     168     1172011 :         move16();
     169     1172011 :         R1 = L_mult( pt_wsp_fx[0], pt_wsp_fx[0] );
     170     1172011 :         R2 = L_mult( wsp_fr_fx[0], wsp_fr_fx[0] );
     171    75008704 :         FOR( j = 1; j < L_SUBFR; j++ )
     172             :         {
     173    73836693 :             R1 = L_mac_sat( R1, pt_wsp_fx[j], pt_wsp_fx[j] );
     174    73836693 :             R2 = L_mac_sat( R2, wsp_fr_fx[j], wsp_fr_fx[j] );
     175             :         }
     176             : 
     177             :         /* *voicing_fr = cor_max * inv_sqrt(enr_wsp * enr_old) */
     178             :         /* *voicing_fr = R0 * inv_sqrt(R1 * R2) */
     179     1172011 :         exp_R0 = norm_s( R0 );
     180     1172011 :         R0 = shl( R0, exp_R0 );
     181             : 
     182     1172011 :         exp_R1 = norm_l( R1 );
     183     1172011 :         R1 = L_shl( R1, exp_R1 );
     184             : 
     185     1172011 :         exp_R2 = norm_l( R2 );
     186     1172011 :         R2 = L_shl( R2, exp_R2 );
     187             : 
     188     1172011 :         R1 = L_mult_sat( round_fx_sat( R1 ), round_fx_sat( R2 ) );
     189     1172011 :         i = norm_l( R1 );
     190     1172011 :         R1 = L_shl( R1, i );
     191             : 
     192     1172011 :         exp_R1 = add( exp_R1, exp_R2 );
     193     1172011 :         exp_R1 = add( exp_R1, i );
     194     1172011 :         exp_R1 = sub( 62, exp_R1 );
     195             : 
     196     1172011 :         R1 = Isqrt_lc( R1, &exp_R1 );
     197             : 
     198     1172011 :         R1 = L_mult( R0, round_fx_sat( R1 ) );
     199     1172011 :         exp_R0 = sub( 31, exp_R0 );
     200     1172011 :         exp_R0 = sub( add( exp_R0, exp_R1 ), exp3 );
     201             : 
     202     1172011 :         *voicing_fr_fx = round_fx_sat( L_shl_sat( R1, exp_R0 ) ); /*Q15*/
     203     1172011 :         move16();
     204             :     }
     205             :     ELSE
     206             :     {
     207       15373 :         *voicing_fr_fx = 0;
     208       15373 :         move16();
     209             :     }
     210             : 
     211     1187384 :     return;
     212             : }
     213             : 
     214             : /*-------------------------------------------------------------------*
     215             :  * StableHighPitchDetect()
     216             :  *
     217             :  * stable very short pitch detection
     218             :  *-------------------------------------------------------------------*/
     219        3100 : void StableHighPitchDetect_fx(
     220             :     Word16 *flag_spitch,       /* o  : flag to indicate very short stable pitch */
     221             :     Word16 pitch[],            /* i/o: OL pitch buffer                         */
     222             :     const Word16 voicing[],    /* i  : OL pitch gains                          */
     223             :     const Word16 wsp[],        /* i  : weighted speech                         */
     224             :     const Word16 localVAD,     /* i  : local VAD flag                          */
     225             :     Word16 *voicing_sm,        /* i/o: smoothed open-loop pitch gains          */
     226             :     Word16 *voicing0_sm,       /* i/o: smoothed high pitch gains               */
     227             :     Word16 *LF_EnergyRatio_sm, /* i/o: smoothed [0, 300Hz] relative peak energy*/
     228             :     Word16 *predecision_flag,  /* i/o: predecision flag                        */
     229             :     Word32 *diff_sm,           /* i/o: smoothed pitch frequency difference     */
     230             :     Word32 *energy_sm,         /* i/o: smoothed energy around pitch frequency  */
     231             :     Word16 Q_new,
     232             :     Word16 EspecdB[] )
     233             : {
     234             :     Word16 i, pitch_freq_point;
     235             :     Word16 T, Tp, pit_min;
     236             :     Word16 energy0_16, energy1_16, ratio, voicing_m;
     237             :     Word32 energy0, energy1, cor_max, diff, sum_energy;
     238             :     const Word16 *pt_wsp;
     239             :     Word16 tmp, tmp1, exp, diff16, cor_max16, exp1, exp2, pit_min_up;
     240             :     Word32 L_tmp, L_tmp1;
     241             :     Word16 Top;
     242             : 
     243             :     /*voicing = (voicing[0] + voicing[1] + voicing[2] )/3;*/
     244        3100 :     L_tmp = L_mult( voicing[0], 10923 /*1/3 in Q15*/ );
     245        3100 :     L_tmp = L_mac( L_tmp, voicing[1], 10923 /*1/3 in Q15*/ );
     246        3100 :     L_tmp = L_mac( L_tmp, voicing[2], 10923 /*1/3 in Q15*/ );
     247        3100 :     voicing_m = round_fx_sat( L_tmp );
     248             :     /**voicing_sm = 0.75f*(*voicing_sm) + 0.25f*voicing;*/
     249        3100 :     *voicing_sm = round_fx( L_mac( L_mult( *voicing_sm, 24576 /*0.75f Q15*/ ), voicing_m, 8192 /*0.25f Q15*/ ) );
     250        3100 :     move16();
     251             :     /* pitch_freq_point = (short)(L_FFT/(mult_fact*T_op[1])+0.5f);*/
     252        3100 :     Top = pitch[1];
     253        3100 :     move16();
     254        3100 :     exp = norm_s( Top );
     255        3100 :     tmp = div_s( shl( 1, sub( 14, exp ) ), Top );                                   /*Q(29 - exp)*/
     256        3100 :     L_tmp = L_mult0( tmp, L_FFT );                                                  /*Q(29 - exp)*/
     257        3100 :     pitch_freq_point = extract_h( L_add( L_shl( L_tmp, sub( exp, 13 ) ), 32768 ) ); /* Q0*/
     258        3100 :     diff = L_deposit_l( 0 );
     259        3100 :     sum_energy = L_deposit_l( 0 );
     260       29328 :     FOR( i = 1; i < 2 * pitch_freq_point; i++ )
     261             :     {
     262       26228 :         diff = L_add( diff, sub( EspecdB[pitch_freq_point], EspecdB[i] ) );
     263       26228 :         sum_energy = L_add( sum_energy, EspecdB[i] );
     264             :     }
     265             :     /*sum_energy /= (2*pitch_freq_point-1);*/
     266        3100 :     tmp = sub( shl( pitch_freq_point, 1 ), 1 );
     267        3100 :     exp = norm_s( tmp );
     268        3100 :     tmp1 = div_s( shl( 1, sub( 14, exp ) ), tmp ); /*Q(29-exp)*/
     269        3100 :     L_tmp = Mult_32_16( sum_energy, tmp1 );
     270        3100 :     sum_energy = L_shl( L_tmp, sub( exp, 14 ) );
     271             :     /**diff_sm = 0.2f * diff  + 0.8f * *diff_sm;*/
     272        3100 :     *diff_sm = L_add( Mult_32_16( diff, 6554 ), Mult_32_16( *diff_sm, 26214 ) );
     273        3100 :     move32();
     274             :     /**energy_sm = 0.2f * sum_energy + 0.8f * *energy_sm;*/
     275        3100 :     *energy_sm = L_add( Mult_32_16( sum_energy, 6554 ), Mult_32_16( *energy_sm, 26214 ) );
     276        3100 :     move32();
     277             :     /*diff /= sum_energy;*/
     278             : 
     279        3100 :     IF( sum_energy )
     280             :     {
     281        3100 :         exp = norm_l( sum_energy );
     282        3100 :         tmp = extract_h( L_shl( sum_energy, exp ) );
     283        3100 :         exp = sub( sub( 30, exp ), 7 );
     284        3100 :         IF( tmp < 0 )
     285             :         {
     286         193 :             tmp = abs_s( tmp );
     287         193 :             tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
     288             :             BASOP_SATURATE_WARNING_OFF_EVS
     289         193 :             diff = L_negate( L_shr_sat( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ) ) );
     290             :             BASOP_SATURATE_WARNING_ON_EVS
     291         193 :             diff16 = round_fx_sat( diff );
     292             :         }
     293             :         ELSE
     294             :         {
     295        2907 :             tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
     296             :             BASOP_SATURATE_WARNING_OFF_EVS
     297        2907 :             diff = L_shr_sat( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ) );
     298             :             BASOP_SATURATE_WARNING_ON_EVS
     299        2907 :             diff16 = round_fx_sat( diff );
     300             :         }
     301             :     }
     302             :     ELSE
     303             :     {
     304           0 :         diff16 = round_fx_sat( L_shl_sat( diff, 25 ) );
     305             :     }
     306        3100 :     test();
     307        3100 :     test();
     308        3100 :     if ( LT_32( *diff_sm, -1280 /*-10.0f Q7*/ ) && LT_32( *energy_sm, 4928 /*38.5f Q7*/ ) && LT_16( diff16, -26214 /*-.8f Q15*/ ) )
     309             :     {
     310         154 :         *predecision_flag = 1;
     311         154 :         move16();
     312             :     }
     313        3100 :     test();
     314        3100 :     test();
     315        3100 :     if ( GT_32( *diff_sm, 1280 /*10.0f Q7*/ ) && GT_32( *energy_sm, 10624 /*83.0f Q7*/ ) && GT_16( diff16, 16384 /*.5 Q15*/ ) )
     316             :     {
     317         133 :         *predecision_flag = 0;
     318         133 :         move16();
     319             :     }
     320             : 
     321             :     /* short pitch possiblity pre-decision */
     322        3100 :     maximum_fx( EspecdB, 7, &energy0_16 );
     323        3100 :     maximum_fx( EspecdB + 8, 7, &energy1_16 );
     324        3100 :     ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */
     325             :     /*ratio *= max(voicing,0);*/
     326        3100 :     tmp = s_max( voicing_m, 0 );
     327        3100 :     ratio = mult_r( ratio, tmp ); /*Q7*/
     328             :     /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/
     329        3100 :     L_tmp = L_mult( ratio, 2048 );
     330        3100 :     L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 );
     331        3100 :     *LF_EnergyRatio_sm = round_fx( L_tmp );
     332        3100 :     move16();
     333        3100 :     test();
     334        3100 :     if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) )
     335             :     {
     336           1 :         *predecision_flag = 1;
     337           1 :         move16();
     338             :     }
     339             : 
     340        3100 :     if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) )
     341             :     {
     342        2978 :         *predecision_flag = 0;
     343        2978 :         move16();
     344             :     }
     345             : 
     346             :     /* short pitch candidate detection */
     347        3100 :     Tp = pitch[1];
     348        3100 :     move16();
     349        3100 :     cor_max = 0;
     350        3100 :     move16();
     351        3100 :     pt_wsp = wsp + 3 * L_SUBFR;
     352        3100 :     pit_min = PIT_MIN_DOUBLEEXTEND;
     353        3100 :     move16();
     354        3100 :     pit_min_up = PIT_MIN;
     355        3100 :     move16();
     356       58900 :     FOR( T = pit_min; T <= pit_min_up; T++ )
     357             :     {
     358       55800 :         energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR );
     359       55800 :         test();
     360       55800 :         IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) )
     361             :         {
     362       20766 :             cor_max = L_add( energy1, 0 );
     363       20766 :             Tp = T;
     364       20766 :             move16();
     365             :         }
     366             :     }
     367        3100 :     energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 );
     368        3100 :     exp1 = sub( exp1, shl( Q_new, 1 ) );
     369        3100 :     energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 );
     370        3100 :     exp2 = sub( exp2, shl( Q_new, 1 ) );
     371             :     /* cor_max *= inv_sqrt( energy0*energy1 );*/
     372        3100 :     L_tmp = Mult_32_32( energy0, energy1 );
     373        3100 :     exp = norm_l( L_tmp );
     374        3100 :     L_tmp1 = L_shl( L_tmp, exp );
     375             : 
     376        3100 :     exp = 31 - exp - ( 31 - exp1 - exp2 );
     377        3100 :     move16();
     378        3100 :     L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/
     379        3100 :     cor_max = Mult_32_32( cor_max, L_tmp1 );
     380        3100 :     exp = 31 - ( shl( Q_new, 1 ) + 1 ) - ( 31 - exp ) + 31;
     381        3100 :     cor_max16 = round_fx_sat( L_shl_sat( cor_max, exp ) ); /*Q15*/
     382             :     /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/
     383        3100 :     *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) );
     384        3100 :     move16();
     385             : 
     386             :     /* final short pitch detection */
     387        3100 :     test();
     388        3100 :     test();
     389        3100 :     test();
     390        3100 :     *flag_spitch = 0;
     391        3100 :     move16();
     392        3100 :     IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) &&
     393             :         ( GT_16( *voicing0_sm, 16384 ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 21299 ) ) ) )
     394             :     {
     395           0 :         *flag_spitch = 1;
     396           0 :         move16();
     397           0 :         pitch[0] = Tp;
     398           0 :         move16();
     399           0 :         pitch[1] = Tp;
     400           0 :         move16();
     401           0 :         pitch[2] = Tp;
     402           0 :         move16();
     403             :     }
     404             : 
     405        3100 :     return;
     406             : }
     407             : 
     408             : 
     409             : /*-------------------------------------------------------------------*
     410             :  * pitch_ol2()
     411             :  *
     412             :  * Open-loop pitch precision improvement with 1/4 resolution
     413             :  * The pitch is searched in the interval <pitch_ol-delta, pitch_ol+delta),
     414             :  * i.e. the value pitch_ol + delta is not a part of the interval
     415             :  *-------------------------------------------------------------------*/
     416             : 
     417             : /*-------------------------------------------------------------------*
     418             :  * StableHighPitchDetect()
     419             :  *
     420             :  * Very short stable pitch detection
     421             :  *-------------------------------------------------------------------*/
     422     1154754 : void StableHighPitchDetect_ivas_fx(
     423             :     Word16 *flag_spitch,       /* o  : flag to indicate very short stable pitch */
     424             :     Word16 pitch[],            /* i/o: OL pitch buffer                         */
     425             :     const Word16 voicing[],    /* i  : OL pitch gains                         Q15 */
     426             :     const Word16 wsp[],        /* i  : weighted speech                        Qx */
     427             :     const Word16 localVAD,     /* i  : local VAD flag                          */
     428             :     Word16 *voicing_sm,        /* i/o: smoothed open-loop pitch gains          */
     429             :     Word16 *voicing0_sm,       /* i/o: smoothed high pitch gains               */
     430             :     Word16 *LF_EnergyRatio_sm, /* i/o: smoothed [0, 300Hz] relative peak energy Q7*/
     431             :     Word16 *predecision_flag,  /* i/o: predecision flag                        */
     432             :     Word32 *diff_sm,           /* i/o: smoothed pitch frequency difference     Q7*/
     433             :     Word32 *energy_sm,         /* i/o: smoothed energy around pitch frequency  Q7*/
     434             :     Word16 Q_new,
     435             :     Word16 EspecdB[] /*Q8*/
     436             : )
     437             : {
     438             :     Word16 i, pitch_freq_point;
     439             :     Word16 T, Tp, pit_min;
     440             :     Word16 energy0_16, energy1_16, ratio, voicing_m;
     441             :     Word32 energy0, energy1, cor_max, diff, sum_energy;
     442             :     const Word16 *pt_wsp;
     443             :     Word16 tmp, tmp1, exp, diff16, cor_max16, exp1, exp2, pit_min_up;
     444             :     Word32 L_tmp, L_tmp1;
     445             :     Word16 Top;
     446             : 
     447             :     /*voicing = (voicing[0] + voicing[1] + voicing[2] )/3;*/
     448     1154754 :     L_tmp = L_mult( voicing[0], 10923 /*1/3 in Q15*/ );
     449     1154754 :     L_tmp = L_mac( L_tmp, voicing[1], 10923 /*1/3 in Q15*/ );
     450     1154754 :     L_tmp = L_mac( L_tmp, voicing[2], 10923 /*1/3 in Q15*/ );
     451     1154754 :     voicing_m = round_fx_sat( L_tmp );
     452             :     /**voicing_sm = 0.75f*(*voicing_sm) + 0.25f*voicing;*/
     453     1154754 :     *voicing_sm = round_fx( L_mac( L_mult( *voicing_sm, 24576 /*0.75f Q15*/ ), voicing_m, 8192 /*0.25f Q15*/ ) );
     454     1154754 :     move16();
     455             : 
     456             :     /* pitch_freq_point = (short)(L_FFT/(mult_fact*T_op[1])+0.5f);*/
     457     1154754 :     Top = pitch[1];
     458     1154754 :     move16();
     459     1154754 :     pitch_freq_point = idiv1616( L_FFT, Top ); /* Q0*/
     460     1154754 :     sum_energy = L_deposit_l( 0 );
     461    10158988 :     FOR( i = 1; i < 2 * pitch_freq_point; i++ )
     462             :     {
     463     9004234 :         sum_energy = L_mac0( sum_energy, EspecdB[i], 1 ); // sum_energy
     464             :     }
     465     1154754 :     tmp = sub( shl( pitch_freq_point, 1 ), 1 );
     466             : 
     467             :     /*  for ( i = 1; i < 2 * pitch_freq_point; i++ )
     468             :         {
     469             :           diff += ( EspecdB[pitch_freq_point] - EspecdB[i] );
     470             :         }
     471             :         sum energy is the accumulated value of EspecdB over the loop and EspecdB[pitch_freq_point] is constant for the loop
     472             :         diff can be computed as (2 * pitch_freq_point - 1) * EspecdB[pitch_freq_point] - sum_energy     */
     473             : 
     474     1154754 :     diff = L_mac0( L_negate( sum_energy ), EspecdB[pitch_freq_point], tmp );
     475             : 
     476             :     /*sum_energy /= (2*pitch_freq_point-1);*/
     477             : 
     478     1154754 :     exp = norm_s( tmp );
     479     1154754 :     tmp1 = div_s( shl( 1, sub( 14, exp ) ), tmp ); /*Q(29-exp)*/
     480     1154754 :     L_tmp = Mult_32_16( sum_energy, tmp1 );
     481     1154754 :     sum_energy = L_shl( L_tmp, sub( exp, 14 ) );
     482             :     /**diff_sm = 0.2f * diff  + 0.8f * *diff_sm;*/
     483     1154754 :     *diff_sm = L_add( Mult_32_16( diff, 6554 /*.2f Q15*/ ), Mult_32_16( *diff_sm, 26214 /*.8f Q15*/ ) );
     484     1154754 :     move32();
     485             :     /**energy_sm = 0.2f * sum_energy + 0.8f * *energy_sm;*/
     486     1154754 :     *energy_sm = L_add( Mult_32_16( sum_energy, 6554 /*.2f Q15*/ ), Mult_32_16( *energy_sm, 26214 /*.8f Q15*/ ) );
     487     1154754 :     move32();
     488             :     /*diff /= sum_energy;*/
     489             : 
     490     1154754 :     IF( sum_energy )
     491             :     {
     492     1154708 :         exp = norm_l( sum_energy );
     493     1154708 :         tmp = extract_h( L_shl( sum_energy, exp ) );
     494     1154708 :         exp = sub( sub( 30, exp ), 7 );
     495     1154708 :         IF( tmp < 0 )
     496             :         {
     497      176627 :             tmp = abs_s( tmp );
     498      176627 :             tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
     499             :             BASOP_SATURATE_WARNING_OFF_EVS
     500      176627 :             diff = L_negate( L_shr_sat( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ) ) );
     501             :             BASOP_SATURATE_WARNING_ON_EVS
     502      176627 :             diff16 = round_fx_sat( diff );
     503             :         }
     504             :         ELSE
     505             :         {
     506      978081 :             tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
     507             :             BASOP_SATURATE_WARNING_OFF_EVS
     508      978081 :             diff = L_shr_sat( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ) );
     509             :             BASOP_SATURATE_WARNING_ON_EVS
     510      978081 :             diff16 = round_fx_sat( diff );
     511             :         }
     512             :     }
     513             :     ELSE
     514             :     {
     515          46 :         diff16 = round_fx_sat( L_shl_sat( diff, 25 ) );
     516             :     }
     517     1154754 :     test();
     518     1154754 :     test();
     519     1154754 :     IF( LT_32( *diff_sm, -1280 /*-10.0f Q7*/ ) && LT_32( *energy_sm, 4928 /*38.5f Q7*/ ) && LT_16( diff16, -26214 /*-.8f Q15*/ ) )
     520             :     {
     521       21677 :         *predecision_flag = 1;
     522       21677 :         move16();
     523             :     }
     524     1154754 :     test();
     525     1154754 :     test();
     526     1154754 :     if ( GT_32( *diff_sm, 1280 /*10.0f Q7*/ ) && GT_32( *energy_sm, 10624 /*83.0f Q7*/ ) && GT_16( diff16, 16384 /*.5 Q15*/ ) )
     527             :     {
     528       87846 :         *predecision_flag = 0;
     529       87846 :         move16();
     530             :     }
     531             : 
     532             :     /* short pitch possiblity pre-decision */
     533     1154754 :     maximum_fx( EspecdB, 7, &energy0_16 );
     534     1154754 :     maximum_fx( EspecdB + 8, 7, &energy1_16 );
     535     1154754 :     test();
     536     1154754 :     IF( energy1_16 < 0 && energy0_16 > 0 )
     537             :     {
     538       31466 :         ratio = 0;
     539       31466 :         move16();
     540             :     }
     541             :     ELSE
     542             :     {
     543     1123288 :         ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */
     544             :     }
     545             :     /*ratio *= max(voicing,0);*/
     546     1154754 :     tmp = s_max( voicing_m, 0 );
     547     1154754 :     ratio = mult_r( ratio, tmp ); /*Q7*/
     548             :     /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/
     549     1154754 :     L_tmp = L_mult( ratio, 2048 );
     550     1154754 :     L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 );
     551     1154754 :     *LF_EnergyRatio_sm = round_fx( L_tmp );
     552     1154754 :     move16();
     553     1154754 :     test();
     554     1154754 :     if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) )
     555             :     {
     556       28386 :         *predecision_flag = 1;
     557       28386 :         move16();
     558             :     }
     559             : 
     560     1154754 :     if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) )
     561             :     {
     562     1104988 :         *predecision_flag = 0;
     563     1104988 :         move16();
     564             :     }
     565             : 
     566             :     /* short pitch candidate detection */
     567     1154754 :     Tp = pitch[1];
     568     1154754 :     move16();
     569     1154754 :     cor_max = 0;
     570     1154754 :     move16();
     571     1154754 :     pt_wsp = wsp + 3 * L_SUBFR;
     572     1154754 :     pit_min = PIT_MIN_DOUBLEEXTEND;
     573     1154754 :     move16();
     574     1154754 :     pit_min_up = PIT_MIN;
     575     1154754 :     move16();
     576    21940326 :     FOR( T = pit_min; T <= pit_min_up; T++ )
     577             :     {
     578    20785572 :         energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR );
     579    20785572 :         test();
     580    20785572 :         IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) )
     581             :         {
     582     6128967 :             cor_max = L_add( energy1, 0 );
     583     6128967 :             Tp = T;
     584     6128967 :             move16();
     585             :         }
     586             :     }
     587     1154754 :     energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 );
     588     1154754 :     exp1 = sub( exp1, shl( Q_new, 1 ) );
     589     1154754 :     energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 );
     590     1154754 :     exp2 = sub( exp2, shl( Q_new, 1 ) );
     591             :     /* cor_max *= inv_sqrt( energy0*energy1 );*/
     592     1154754 :     L_tmp = Mult_32_32( energy0, energy1 );
     593     1154754 :     exp = norm_l( L_tmp );
     594     1154754 :     L_tmp1 = L_shl( L_tmp, exp );
     595             : 
     596     1154754 :     exp = sub( sub( 31, exp ), ( sub( sub( 31, exp1 ), exp2 ) ) );
     597     1154754 :     move16();
     598     1154754 :     L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/
     599     1154754 :     cor_max = Mult_32_32( cor_max, L_tmp1 );
     600     1154754 :     exp = add( sub( sub( 31, add( shl( Q_new, 1 ), 1 ) ), sub( 31, exp ) ), 31 );
     601     1154754 :     cor_max16 = round_fx_sat( L_shl_sat( cor_max, exp ) ); /*Q15*/
     602             :     /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/
     603     1154754 :     *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) );
     604     1154754 :     move16();
     605             : 
     606             :     /* final short pitch detection */
     607     1154754 :     test();
     608     1154754 :     test();
     609     1154754 :     test();
     610     1154754 :     *flag_spitch = 0;
     611     1154754 :     move16();
     612     1154754 :     IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) &&
     613             :         ( GT_16( *voicing0_sm, 21299 /*.65f in Q15*/ ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 22938 /*.7f in Q15*/ ) ) ) )
     614             :     {
     615       37364 :         *flag_spitch = 1;
     616       37364 :         move16();
     617       37364 :         pitch[0] = Tp;
     618       37364 :         move16();
     619       37364 :         pitch[1] = Tp;
     620       37364 :         move16();
     621       37364 :         pitch[2] = Tp;
     622       37364 :         move16();
     623             :     }
     624             : 
     625     1154754 :     return;
     626             : }

Generated by: LCOV version 1.14