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

Generated by: LCOV version 1.14