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

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <assert.h>
       6             : #include <stdint.h>
       7             : #include "options.h"
       8             : #include "cnst.h"
       9             : //#include "prot_fx.h"
      10             : #include "rom_com_fx.h"
      11             : #include "rom_com.h"
      12             : #include "rom_enc.h"
      13             : #include "basop_util.h"
      14             : #include "prot_fx.h"     /* Function prototypes                    */
      15             : #include "prot_fx_enc.h" /* Function prototypes                    */
      16             : 
      17             : void E_GAIN_norm_corr_fx( Word16 exc[] /*Q_new*/, Word16 xn[] /*(Q_new+shift-1)*/, Word16 h[] /*(Q14+shift)*/, Word16 t_min, Word16 t_max, Word16 corr_norm[] /*(Q15+(Q_new+shift-1)+scale)*/, Word16 L_subfr );
      18             : 
      19             : /*
      20             :  * E_GAIN_norm_corr
      21             :  *
      22             :  * Parameters:
      23             :  *    exc            I: excitation buffer (Q_new)
      24             :  *    xn             I: target signal (Q_new+shift-1)
      25             :  *    h              I: weighted synthesis filter impulse response (Q14+shift)
      26             :  *    t0_min         I: minimum value in the searched range
      27             :  *    t0_max         I: maximum value in the searched range
      28             :  *    corr_norm      O: normalized correlation (Q15+(Q_new+shift-1)+scale)
      29             :  *
      30             :  * Function:
      31             :  *    Find the normalized correlation between the target vector and the
      32             :  *    filtered past excitation (correlation between target and filtered
      33             :  *    excitation divided by the square root of energy of filtered excitation)
      34             :  *    Size of subframe = L_SUBFR.
      35             :  *
      36             :  * Returns:
      37             :  *    void
      38             :  */
      39        3020 : void E_GAIN_norm_corr_fx( Word16 exc[] /*Q_new*/, Word16 xn[] /*(Q_new+shift-1)*/, Word16 h[] /*(Q14+shift)*/, Word16 t_min, Word16 t_max, Word16 corr_norm[] /*(Q15+(Q_new+shift-1)+scale)*/, Word16 L_subfr )
      40             : {
      41             :     Word16 excf[L_SUBFR]; /* filtered past excitation (Q_new+shift-1) */
      42             :     Word16 ps, norm, exp_alp, exp_ps, scale, L_subfr2;
      43             :     Word16 t, j, k;
      44             :     Word32 L_tmp, L_tmp2;
      45             : 
      46             : 
      47        3020 :     k = negate( t_min );
      48        3020 :     L_subfr2 = shr( L_subfr, 1 );
      49             : 
      50             :     /* compute the filtered excitation for the first delay t_min */
      51        3020 :     E_UTIL_f_convolve( &exc[k], h, excf, L_subfr );
      52             : 
      53             :     /* Compute rounded down 1/sqrt(energy of xn[]) */
      54        3020 :     Dot_product12_offs( xn, xn, L_subfr, &scale, 1 );
      55             : 
      56        3020 :     scale = add( scale, 2 + 1 ); /* energy of xn[] x 2 + rounded up     */
      57        3020 :     move16();
      58        3020 :     scale = negate( shr( scale, 1 ) ); /* (1<<scale) < 1/sqrt(energy rounded) */
      59             : 
      60             :     /* loop for every possible period */
      61       81824 :     FOR( t = t_min; t < t_max; t++ )
      62             :     {
      63             :         /* Compute correlation between xn[] and excf[] */
      64             : 
      65             :         /*for (j = 0; j < L_subfr; j++)
      66             :         {
      67             :            ps  += xn[j] * excf[j];                                          MAC(1);
      68             :            alp += excf[j] * excf[j];                                        MAC(1);
      69             :         }*/
      70       78804 :         L_tmp = Dot_product12_offs( xn, excf, L_subfr, &exp_ps, 1 ); /*Q31 + 2x(Q_new+shift-1) - exp_ps*/
      71       78804 :         ps = extract_h( L_tmp );                                     /* Scaling of ps = 15 + 2x(Q_new+shift-1) - exp_ps */
      72             : 
      73             : 
      74             :         /* Compute 1/sqrt(energy of excf[]) */
      75       78804 :         L_tmp = Dot_product12_offs( excf, excf, L_subfr2, NULL, 1 );
      76       78804 :         L_tmp2 = Dot_product12_offs( excf + L_subfr2, excf + L_subfr2, L_subfr2, NULL, 1 );
      77       78804 :         exp_alp = sub( s_min( norm_l( L_tmp ), norm_l( L_tmp2 ) ), 1 );
      78       78804 :         L_tmp = L_add( L_shl( L_tmp, exp_alp ), L_shl( L_tmp2, exp_alp ) );
      79       78804 :         exp_alp = sub( 31 + 1, exp_alp );
      80             : 
      81             :         /*norm = (Float32)(1.0F / sqrt(alp));                                 SQRT(1);*/
      82       78804 :         L_tmp = ISqrt32( L_tmp, &exp_alp ); /*Q31 - (Q_new+shift-1) - exp_alp*/
      83       78804 :         norm = extract_h( L_tmp );          /* Scaling of norm = 15 - (Q_new+shift-1) - exp_alp */
      84             : 
      85             :         /* Normalize correlation = correlation * (1/sqrt(energy)) */
      86             :         /*corr_norm[t-t_min] = ps * norm;                                     MULT(1); STORE(1);*/
      87       78804 :         L_tmp = L_mult( ps, norm ); /*Q31 + (Q_new+shift-1) - (exp_ps + exp_alp)*/
      88       78804 :         L_tmp = L_shl( L_tmp, add( add( exp_ps, exp_alp ), scale ) );
      89             : 
      90       78804 :         corr_norm[t - t_min] = round_fx( L_tmp ); /* Scaling of corr_norm = 15 + (Q_new+shift-1) + scale */
      91             : 
      92             :         /* update the filtered excitation excf[] for the next iteration */
      93       78804 :         k = sub( k, 1 );
      94             : 
      95     5043456 :         FOR( j = L_subfr - 1; j > 0; j-- )
      96             :         {
      97             :             /*excf[j] = excf[j - 1] + exc[k] * h[j];                           MAC(1); STORE(1);*/
      98             :             /* saturation can occur in add() */
      99     4964652 :             excf[j] = add( mult_r( exc[k], h[j] ), excf[j - 1] ); /*Q_new + (Q14+shift) - 15*/
     100     4964652 :             move16();
     101             :         }
     102       78804 :         excf[0] = mult_r( exc[k], h[0] ); /*Q_new + (Q14+shift) - 15*/
     103       78804 :         move16();
     104             :     }
     105             :     /* Last reduced iteration for t=t_max */
     106        3020 :     L_tmp = Dot_product12_offs( xn, excf, L_subfr, &exp_ps, 1 ); /*Q31 + 2x(Q_new+shift-1) - exp_ps*/
     107        3020 :     ps = extract_h( L_tmp );                                     /*Q15 + 2x(Q_new+shift-1) - exp_ps*/
     108             : 
     109             : 
     110             :     /* Compute 1/sqrt(energy of excf[]) */
     111        3020 :     L_tmp = Dot_product12_offs( excf, excf, L_subfr2, NULL, 1 );
     112        3020 :     L_tmp2 = Dot_product12_offs( excf + L_subfr2, excf + L_subfr2, L_subfr2, NULL, 1 );
     113        3020 :     exp_alp = sub( s_min( norm_l( L_tmp ), norm_l( L_tmp2 ) ), 1 );
     114        3020 :     L_tmp = L_add( L_shl( L_tmp, exp_alp ), L_shl( L_tmp2, exp_alp ) );
     115        3020 :     exp_alp = sub( 31 + 1, exp_alp );
     116             : 
     117             : 
     118             :     /*norm = (Float32)(1.0F / sqrt(alp));                                 SQRT(1);*/
     119        3020 :     L_tmp = ISqrt32( L_tmp, &exp_alp ); /*Q31 - (Q_new+shift-1) - exp_alp*/
     120        3020 :     norm = extract_h( L_tmp );          /*15 - (Q_new+shift-1) - exp_alp */
     121             : 
     122             :     /* Normalize correlation = correlation * (1/sqrt(energy)) */
     123             :     /*corr_norm[t-t_min] = ps * norm;                                     MULT(1); STORE(1);*/
     124        3020 :     L_tmp = L_mult( ps, norm ); /*Q31 + (Q_new+shift-1) - (exp_ps + exp_alp)*/
     125        3020 :     L_tmp = L_shl( L_tmp, add( add( exp_ps, exp_alp ), scale ) );
     126        3020 :     corr_norm[t - t_min] = round_fx( L_tmp ); /* 15 + (Q_new+shift-1) + scale */
     127             : 
     128        3020 :     return;
     129             : }
     130             : 
     131             : 
     132             : /*
     133             :  * E_GAIN_norm_corr_interpolate
     134             :  *
     135             :  * Parameters:
     136             :  *    x           I: input vector
     137             :  *    frac        I: fraction (-4..+3)
     138             :  *
     139             :  * Function:
     140             :  *    Interpolating the normalized correlation
     141             :  *
     142             :  * Returns:
     143             :  *    interpolated value
     144             :  */
     145           0 : static Word16 E_GAIN_norm_corr_interpolate_fx( Word16 *x /*Qx*/, Word16 frac /*Q0*/ )
     146             : {
     147             :     Word16 *x1, *x2, i;
     148             :     const Word16 *c1, *c2;
     149             :     Word32 s;
     150             : 
     151           0 :     IF( frac < 0 )
     152             :     {
     153           0 :         frac = add( frac, 4 ); /*Q0*/
     154           0 :         x--;
     155             :     }
     156             : 
     157           0 :     x1 = &x[0];                        /*Qx*/
     158           0 :     x2 = &x[1];                        /*Qx*/
     159           0 :     c1 = &E_ROM_inter4_1_fx[frac];     /*Q14*/
     160           0 :     c2 = &E_ROM_inter4_1_fx[4 - frac]; /*Q14*/
     161             : 
     162             :     /*s = x1[0] * c1[0] + x2[0] * c2[0];
     163             :     s += x1[-1] * c1[4] + x2[1] * c2[4];
     164             :     s += x1[-2] * c1[8] + x2[2] * c2[8];
     165             :     s += x1[-3] * c1[12] + x2[3] * c2[12];*/
     166             : 
     167           0 :     s = L_deposit_l( 0 );
     168           0 :     FOR( i = 0; i < 4; i++ )
     169             :     {
     170           0 :         s = L_mac( s, *x1--, *c1 ); /* Qx + 15 */
     171           0 :         s = L_mac( s, *x2++, *c2 ); /* Qx + 15 */
     172           0 :         c1 += 4;
     173           0 :         c2 += 4;
     174             :     }
     175             : 
     176           0 :     return round_fx( L_shl( s, 1 ) ); /*Qx*/
     177             : }
     178             : 
     179       14390 : static Word16 E_GAIN_norm_corr_interpolate6_fx( Word16 *x /*Qx*/, Word16 frac /*Q0*/ )
     180             : {
     181             :     Word16 *x1, *x2, i;
     182             :     const Word16 *c1, *c2;
     183             :     Word32 s;
     184             : 
     185       14390 :     IF( frac < 0 )
     186             :     {
     187        5770 :         frac = add( frac, 6 ); /*Q0*/
     188        5770 :         x--;
     189             :     }
     190             : 
     191       14390 :     x1 = &x[0];                        /*Qx*/
     192       14390 :     x2 = &x[1];                        /*Qx*/
     193       14390 :     c1 = &E_ROM_inter6_1_fx[frac];     /*Q14*/
     194       14390 :     c2 = &E_ROM_inter6_1_fx[6 - frac]; /*Q14*/
     195             : 
     196             :     /*s = x1[0] * c1[0] + x2[0] * c2[0];
     197             :     s += x1[-1] * c1[6] + x2[1] * c2[6];
     198             :     s += x1[-2] * c1[12] + x2[2] * c2[12];
     199             :     s += x1[-3] * c1[18] + x2[3] * c2[18];*/
     200       14390 :     s = L_deposit_l( 0 );
     201       71950 :     FOR( i = 0; i < 4; i++ )
     202             :     {
     203       57560 :         s = L_mac( s, *x1--, *c1 ); /* Qx + 15 */
     204       57560 :         s = L_mac( s, *x2++, *c2 ); /* Qx + 15 */
     205       57560 :         c1 += 6;
     206       57560 :         c2 += 6;
     207             :     }
     208             : 
     209       14390 :     return round_fx( L_shl( s, 1 ) ); /*Qx*/
     210             : }
     211             : 
     212             : /*
     213             :  * E_GAIN_closed_loop_search_fx
     214             :  *
     215             :  * Parameters:
     216             :  *    exc            I: excitation buffer
     217             :  *    xn             I: target signal
     218             :  *    h              I: weighted synthesis filter impulse response
     219             :  *    dn             I: residual domain target signal
     220             :  *    t0_min         I: minimum value in the searched range
     221             :  *    t0_max         I: maximum value in the searched range
     222             :  *    pit_frac       O: chosen fraction
     223             :  *    i_subfr        I: flag to first subframe
     224             :  *    t0_fr2         I: minimum value for resolution 1/2
     225             :  *    t0_fr1         I: minimum value for resolution 1
     226             :  *
     227             :  * Function:
     228             :  *    Find the closed loop pitch period with 1/4 subsample resolution.
     229             :  *
     230             :  * Returns:
     231             :  *    chosen integer pitch lag
     232             :  */
     233        3020 : Word16 E_GAIN_closed_loop_search_fx( Word16 exc[],          /*Q_new*/
     234             :                                      Word16 xn[],           /*Q_xn*/
     235             :                                      Word16 h[],            /* Q14+shift */
     236             :                                      Word16 t0_min,         /*Q0*/
     237             :                                      Word16 t0_min_frac,    /*Q0*/
     238             :                                      Word16 t0_max,         /*Q0*/
     239             :                                      Word16 t0_max_frac,    /*Q0*/
     240             :                                      Word16 t0_min_max_res, /*Q0*/
     241             :                                      Word16 *pit_frac,      /*Q0*/
     242             :                                      Word16 *pit_res,       /*Q0*/
     243             :                                      Word16 pit_res_max,    /*Q0*/
     244             :                                      Word16 i_subfr,        /*Q0*/
     245             :                                      Word16 pit_min,        /*Q0*/
     246             :                                      Word16 pit_fr2,        /*Q0*/
     247             :                                      Word16 pit_fr1,        /*Q0*/
     248             :                                      Word16 L_subfr /*Q0*/ )
     249             : {
     250             :     Word16 corr_v[32 + 2 * L_INTERPOL1 + 1];
     251             :     Word16 cor_max, max, temp;
     252             :     Word16 *corr;
     253             :     Word16 i, fraction, frac1, frac2, step;
     254             :     Word16 t0, t_min, t_max;
     255             : 
     256        3020 :     set16_fx( corr_v, 0, 32 + 2 * L_INTERPOL1 + 1 );
     257             :     /* Find interval to compute normalized correlation */
     258        3020 :     if ( t0_min_frac > 0 )
     259             :     {
     260        2716 :         t0_min = add( t0_min, 1 );
     261        2716 :         move16();
     262             :     }
     263        3020 :     t_min = sub( t0_min, L_INTERPOL1 );
     264        3020 :     t_max = add( t0_max, L_INTERPOL1 );
     265        3020 :     move16();
     266        3020 :     move16();
     267             : 
     268             :     /* allocate memory to normalized correlation vector */
     269        3020 :     corr = &corr_v[negate( t_min )]; /* corr[t_min..t_max] */
     270             : 
     271             :     /* Compute normalized correlation between target and filtered excitation */
     272        3020 :     E_GAIN_norm_corr_fx( exc, xn, h, t_min, t_max, corr_v, L_subfr );
     273             : 
     274             :     /*  find integer pitch */
     275        3020 :     max = corr[t0_min]; /*(Q15+(Q_new+shift-1)+scale)*/
     276        3020 :     move16();
     277        3020 :     t0 = t0_min; /*Q0*/
     278        3020 :     move16();
     279             : 
     280       57664 :     FOR( i = t0_min + 1; i <= t0_max; i++ )
     281             :     {
     282             :         BASOP_SATURATE_WARNING_OFF_EVS;
     283       54644 :         if ( GE_16( corr[i], max ) )
     284             :         {
     285       19923 :             t0 = i;
     286       19923 :             move16();
     287             :         }
     288       54644 :         max = s_max( max, corr[i] );
     289             :         BASOP_SATURATE_WARNING_ON_EVS;
     290             :     }
     291             : 
     292             : 
     293             :     /* If first subframe and t0 >= pit_fr1, do not search fractionnal pitch */
     294        3020 :     test();
     295        3020 :     IF( ( i_subfr == 0 ) && GE_16( t0, pit_fr1 ) )
     296             :     {
     297         117 :         *pit_frac = 0;
     298         117 :         move16();
     299         117 :         *pit_res = 1;
     300         117 :         move16();
     301         117 :         return ( t0 );
     302             :     }
     303             : 
     304             : 
     305             :     /*
     306             :      * Search fractionnal pitch
     307             :      * Test the fractions around t0 and choose the one which maximizes
     308             :      * the interpolated normalized correlation.
     309             :      */
     310             : 
     311        2903 :     IF( EQ_16( t0_min_max_res, shr( pit_res_max, 1 ) ) )
     312             :     {
     313        2903 :         t0_min_frac = shl( t0_min_frac, 1 ); /*Q0*/
     314        2903 :         t0_max_frac = shl( t0_max_frac, 1 ); /*Q0*/
     315             :     }
     316             : 
     317        2903 :     step = 1;
     318        2903 :     move16();
     319        2903 :     frac1 = sub( 1, pit_res_max ); /*Q0*/
     320        2903 :     frac2 = sub( pit_res_max, 1 ); /*Q0*/
     321             : 
     322        2903 :     test();
     323        2903 :     test();
     324        2903 :     IF( ( ( i_subfr == 0 ) && GE_16( t0, pit_fr2 ) ) || LE_16( pit_fr2, pit_min ) )
     325             :     {
     326        2903 :         step = 2;
     327        2903 :         move16();
     328        2903 :         frac1 = sub( 2, pit_res_max ); /*Q0*/
     329        2903 :         frac2 = sub( pit_res_max, 2 ); /*Q0*/
     330             :     }
     331        2903 :     test();
     332        2903 :     IF( ( EQ_16( t0, t0_min ) ) && ( t0_min_frac == 0 ) )
     333             :     {
     334           8 :         frac1 = t0_min_frac; /*Q0*/
     335           8 :         move16();
     336             :     }
     337             :     ELSE
     338             :     {
     339        2895 :         test();
     340        2895 :         IF( ( EQ_16( t0, t0_min ) ) && ( LT_16( add( frac1, pit_res_max ), t0_min_frac ) ) )
     341             :         {
     342          20 :             frac1 = sub( t0_min_frac, pit_res_max ); /*Q0*/
     343             :         }
     344             :     }
     345             : 
     346        2903 :     if ( EQ_16( t0, t0_max ) )
     347             :     {
     348          71 :         frac2 = t0_max_frac; /*Q0*/
     349          71 :         move16();
     350             :     }
     351        2903 :     assert( frac1 <= 0 && frac2 >= 0 && frac2 > frac1 );
     352             : 
     353        2903 :     IF( EQ_16( pit_res_max, 6 ) )
     354             :     {
     355        2903 :         cor_max = E_GAIN_norm_corr_interpolate6_fx( &corr[t0], frac1 ); /*(Q15+(Q_new+shift-1)+scale)*/
     356        2903 :         fraction = frac1;                                               /*Q0*/
     357        2903 :         move16();
     358             : 
     359       14390 :         FOR( i = ( frac1 + step ); i <= frac2; i += step )
     360             :         {
     361       11487 :             temp = E_GAIN_norm_corr_interpolate6_fx( &corr[t0], i ); /*(Q15+(Q_new+shift-1)+scale)*/
     362       11487 :             IF( GT_16( temp, cor_max ) )
     363             :             {
     364        5787 :                 cor_max = temp; /*(Q15+(Q_new+shift-1)+scale)*/
     365        5787 :                 move16();
     366        5787 :                 fraction = i;
     367        5787 :                 move16();
     368             :             }
     369             :         }
     370             :     }
     371             :     ELSE
     372             :     {
     373           0 :         cor_max = E_GAIN_norm_corr_interpolate_fx( &corr[t0], frac1 ); /*(Q15+(Q_new+shift-1)+scale)*/
     374           0 :         fraction = frac1;                                              /*Q0*/
     375           0 :         move16();
     376             : 
     377           0 :         FOR( i = ( frac1 + step ); i <= frac2; i += step )
     378             :         {
     379           0 :             temp = E_GAIN_norm_corr_interpolate_fx( &corr[t0], i ); /*(Q15+(Q_new+shift-1)+scale)*/
     380           0 :             IF( GT_16( temp, cor_max ) )
     381             :             {
     382           0 :                 cor_max = temp; /*(Q15+(Q_new+shift-1)+scale)*/
     383           0 :                 move16();
     384           0 :                 fraction = i;
     385           0 :                 move16();
     386             :             }
     387             :         }
     388             :     }
     389             : 
     390             :     /* limit the fraction value */
     391        2903 :     IF( fraction < 0 )
     392             :     {
     393         757 :         fraction = add( fraction, pit_res_max ); /*Q0*/
     394         757 :         t0 = sub( t0, 1 );
     395             :     }
     396        2903 :     test();
     397        2903 :     test();
     398        2903 :     IF( ( ( i_subfr == 0 ) && GE_16( t0, pit_fr2 ) ) || LE_16( pit_fr2, pit_min ) )
     399             :     {
     400        2903 :         *pit_res = shr( pit_res_max, 1 ); /*Q0*/
     401        2903 :         move16();
     402        2903 :         *pit_frac = shr( fraction, 1 ); /*Q0*/
     403        2903 :         move16();
     404             :     }
     405             :     ELSE
     406             :     {
     407           0 :         *pit_res = pit_res_max; /*Q0*/
     408           0 :         move16();
     409           0 :         *pit_frac = fraction; /*Q0*/
     410           0 :         move16();
     411             :     }
     412        2903 :     return ( t0 );
     413             : }

Generated by: LCOV version 1.14