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

Generated by: LCOV version 1.14