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

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h"
       6             : #include "cnst.h"       /* Common constants                       */
       7             : #include "rom_com_fx.h" /* Static table prototypes                */
       8             : #include "rom_com.h"    /* Static table prototypes                */
       9             : //#include "prot_fx.h"       /* Function prototypes                    */
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "prot_fx_enc.h" /* Function prototypes                    */
      12             : 
      13             : /*-----------------------------------------------------------------*
      14             :  * Local constant
      15             :  *-----------------------------------------------------------------*/
      16             : #define INPOL 4 /* +- range in samples for impulse position searching */
      17             : 
      18             : /*-----------------------------------------------------------------*
      19             :  * Local function prototypes
      20             :  *-----------------------------------------------------------------*/
      21             : static void convolve_tc_fx( const Word16 g[], const Word16 h[], Word16 y[], const Word16 L_1, const Word16 L_2 );
      22             : static void correlate_tc_fx( const Word16 *x, Word16 *y, const Word16 *h, const Word16 start, const Word16 L_1, const Word16 L_2 );
      23             : static void convolve_tc2_fx( const Word16 g[], const Word16 h[], Word16 y[], const Word16 pos_max );
      24             : 
      25             : /*---------------------------------------------------------------------------------------*
      26             :  * Function  set_impulse() for TC                                                        *
      27             :  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                        *
      28             :  * Builds glottal codebook contribution based on glotal impulses positions finding.      *
      29             :  *                                                                                       *
      30             :  * Returns a position of the glotal impulse center and                                   *
      31             :  * a number of the glotal impulse shape.                                                 *
      32             :  *                                                                                       *
      33             :  *               |----|              |----|                                   xn         *
      34             :  *     imp_pos-> ||   |  imp_shape-> | g1 |                                   |          *
      35             :  *               | |  |              | g2 |  exc    |---|    y1  ----         |          *
      36             :  *               |  | |--------------|    |---------| h |-------|gain|-------(-)---> xn2 *
      37             :  *               |   ||              | gn |         |---|        ----                    *
      38             :  *               |----|              |----|                                              *
      39             :  *              codebook           excitation       h_orig       gain                    *
      40             :  *                                                                                       *
      41             :  *                                                                                       *
      42             :  *                                 nominator      dd    <xn,y1>*<xn,y1>                  *
      43             :  * Searching criterion: maximize ------------- = ---- = -----------------                *
      44             :  *                                denominator     rr        <y1,y1>                      *
      45             :  *                                                                                       *
      46             :  * Notice: gain = gain_trans * gain_pit (computed in trans_enc() function)               *
      47             :  *                                                                                       *
      48             :  *---------------------------------------------------------------------------------------*/
      49       14181 : void set_impulse_fx(
      50             :     const Word16 xn_fx[],     /* i  :  target signal                                                                    Q_new-1+shift*/
      51             :     const Word16 h_orig_fx[], /* i  :  impulse response of weighted synthesis filter    Q(14+shift)*/
      52             :     Word16 exc_fx[],          /* o  :  adaptive codebook excitation                                             Q_new*/
      53             :     Word16 yy1_fx[],          /* o  :  filtered adaptive codebook excitation                    Q_new*/
      54             :     Word16 *imp_shape,        /* o  :  adaptive codebook index                                                  Q0*/
      55             :     Word16 *imp_pos,          /* o  :  position of the glottal impulse center index             Q0*/
      56             :     Word32 *gain_trans_fx,    /* o  :  transition gain                                                                  Q7*/
      57             :     Word16 Q_new              /* i  :  Current scaling                                                                  */
      58             : )
      59             : {
      60             :     Word16 i, j, m;
      61             :     Word16 start1, start2, end1;
      62             :     Word32 rr_fx[L_SUBFR];                             /*  criterion:  nominator coefficients  */
      63             :     Word16 dd_fx[L_SUBFR], tmp16;                      /*  criterion: denominator coefficients */
      64             :     Word16 gh_fx[L_SUBFR], num, den, exp_num, exp_den; /*  convolution of 'g' and 'h' filters */
      65             :     Word16 krit_fx, krit_max_fx, gain16;
      66             :     Word32 Lrr, Ldd, Ltmp, Ltmp1;
      67             :     const Word16 *pt_Glt;
      68             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      69       14181 :     Flag Overflow = 0;
      70       14181 :     move32();
      71             : #endif
      72       14181 :     krit_max_fx = -32768;
      73       14181 :     move16();
      74             : 
      75             :     /* main loop */
      76             :     /*  impulse  */
      77      127629 :     FOR( m = 0; m < NUM_IMPULSE; m++ )
      78             :     {
      79             :         /* set searching ranges */
      80      113448 :         IF( LT_16( *imp_pos, L_SUBFR - INPOL ) )
      81             :         {
      82      110104 :             end1 = add( *imp_pos, INPOL ); // Q0
      83             :         }
      84             :         ELSE
      85             :         {
      86        3344 :             end1 = L_SUBFR;
      87        3344 :             move16();
      88             :         }
      89      113448 :         IF( GT_16( *imp_pos, INPOL ) )
      90             :         {
      91       99878 :             start1 = sub( *imp_pos, INPOL ); // Q0
      92             :         }
      93             :         ELSE
      94             :         {
      95       13570 :             start1 = 0;
      96       13570 :             move16();
      97             :         }
      98      113448 :         IF( GT_16( start1, L_IMPULSE2 ) )
      99             :         {
     100       81869 :             start2 = start1;
     101       81869 :             move16();
     102             :         }
     103             :         ELSE
     104             :         {
     105       31579 :             start2 = L_IMPULSE2;
     106       31579 :             move16();
     107             :         }
     108             : 
     109             :         /*-----------------------------------------------------------*
     110             :          *   nominator & DEnominator, gh=convolve(g,h)
     111             :          *-----------------------------------------------------------*/
     112      113448 :         IF( LT_16( start1, L_IMPULSE2 ) )
     113             :         {
     114       28526 :             Lrr = L_deposit_l( 0 );
     115       28526 :             Ldd = L_deposit_l( 0 );
     116       28526 :             convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - start1],
     117       28526 :                             &h_orig_fx[0], gh_fx, add( L_IMPULSE - L_IMPULSE2, start1 ), L_SUBFR );
     118             : 
     119             :             /* nominator & DEnominator row <0> */
     120     1854190 :             FOR( i = 0; i < L_SUBFR; i++ )
     121             :             {
     122     1825664 :                 Lrr = L_mac_o( Lrr, gh_fx[i], gh_fx[i], &Overflow ); // Q27
     123     1825664 :                 Ldd = L_mac_o( Ldd, gh_fx[i], xn_fx[i], &Overflow ); // Q27
     124             :             }
     125       28526 :             rr_fx[start1] = Lrr;
     126       28526 :             move32();
     127       28526 :             dd_fx[start1] = round_fx_o( Ldd, &Overflow ); // Q11
     128       28526 :             rr_fx[start1] = L_max( rr_fx[start1], 1 );
     129             : 
     130      167034 :             FOR( i = add( start1, 1 ); i < L_IMPULSE2; i++ )
     131             :             {
     132      138508 :                 Lrr = L_deposit_l( 0 );
     133      138508 :                 Ldd = L_deposit_l( 0 );
     134             :                 /* DEnominator rows <1,L_IMPULSE2-1> */
     135     8864512 :                 FOR( j = L_SUBFR - 1; j > 0; j-- )
     136             :                 {
     137             :                     /* gh_fx[j] = gh_fx[j-1] + glottal_cdbk[m*L_IMPULSE+L_IMPULSE2-i]*h_orig_fx[j] */
     138     8726004 :                     gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
     139     8726004 :                                       Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[j] ); // Q13
     140     8726004 :                     move16();
     141     8726004 :                     Lrr = L_mac_o( Lrr, gh_fx[j], gh_fx[j], &Overflow ); // Q27
     142     8726004 :                     Ldd = L_mac_o( Ldd, gh_fx[j], xn_fx[j], &Overflow ); // Q27
     143             :                 }
     144             : 
     145      138508 :                 gh_fx[0] = mult_r( Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[0] ); // Q13
     146      138508 :                 move16();
     147      138508 :                 Lrr = L_mac_o( Lrr, gh_fx[0], gh_fx[0], &Overflow ); // Q27
     148      138508 :                 Ldd = L_mac_o( Ldd, gh_fx[0], xn_fx[0], &Overflow ); // Q27
     149      138508 :                 dd_fx[i] = round_fx_sat( Ldd );                      // Q11
     150      138508 :                 rr_fx[i] = L_max( Lrr, 1 );
     151      138508 :                 move32();
     152             :                 /* move rr and dd into rr[i] and dd[i] */
     153             :             }
     154             : 
     155             :             /* complete convolution(excitation,h_orig) */
     156     1825664 :             FOR( j = L_SUBFR - 1; j > 0; j-- )
     157             :             {
     158     1797138 :                 gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
     159     1797138 :                                   Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx[j] ); // Q13
     160             :             }
     161             :         }
     162             :         ELSE
     163             :         {
     164       84922 :             convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx, gh_fx, L_IMPULSE, L_SUBFR );
     165             :         }
     166             : 
     167      113448 :         IF( GE_16( end1, start2 ) )
     168             :         {
     169             :             /* DEnominator row <L_SUBFR-1> */
     170      102745 :             Lrr = L_mult( gh_fx[0], gh_fx[0] ); // Q27
     171      924705 :             FOR( j = 1; j <= L_IMPULSE2; j++ )
     172             :             {
     173             :                 /*rr[L_SUBFR-1] += gh[j]*gh[j];*/
     174      821960 :                 Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); // Q27
     175             :             }
     176      102745 :             rr_fx[L_SUBFR - 1] = Lrr;
     177      102745 :             move32();
     178             :             /* DEnominator rows <L_IMPULSE2,L_SUBFR-2> */
     179     3981396 :             FOR( i = L_SUBFR - 2; i >= start2; i-- )
     180             :             {
     181             :                 /*rr[i] = rr[i+1] + gh[L_SUBFR+L_IMPULSE2-1-i]*gh[L_SUBFR+L_IMPULSE2-1-i];*/
     182     7757302 :                 rr_fx[i] = L_mac_o( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i],
     183     3878651 :                                     gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], &Overflow ); // Q27
     184     3878651 :                 move32();
     185             :             }
     186             :             /* nominator rows <L_IMPULSE2,L_SUBFR-1> */
     187      102745 :             correlate_tc_fx( xn_fx, &dd_fx[L_IMPULSE2], gh_fx, sub( start2, L_IMPULSE2 ),
     188      102745 :                              L_SUBFR, sub( end1, L_IMPULSE2 ) );
     189             :         }
     190             :         /*------------------------------------------------------------*
     191             :          *    maxim. criterion
     192             :          *------------------------------------------------------------*/
     193      987808 :         FOR( i = start1; i < end1; i++ )
     194             :         {
     195             :             /* krit = (float)(dd[i]*dd[i])/rr[i] */
     196      874360 :             exp_num = sub( norm_s( dd_fx[i] ), 1 );
     197      874360 :             num = shl( dd_fx[i], exp_num );
     198      874360 :             num = mult_r( num, num );
     199             : 
     200      874360 :             exp_den = norm_l( rr_fx[i] );
     201      874360 :             den = extract_h( L_shl( rr_fx[i], exp_den ) );
     202             : 
     203      874360 :             num = div_s( num, den );
     204      874360 :             krit_fx = shr_o( num, sub( sub( shl_o( exp_num, 1, &Overflow ), exp_den ), 2 ), &Overflow ); /* Q18 */
     205             : 
     206      874360 :             IF( GT_16( krit_fx, krit_max_fx ) )
     207             :             {
     208       93218 :                 krit_max_fx = krit_fx; // Q18
     209       93218 :                 move16();
     210       93218 :                 *imp_pos = i;
     211       93218 :                 move16();
     212       93218 :                 *imp_shape = m;
     213       93218 :                 move16();
     214             :             }
     215             :         }
     216             :     }
     217             : 
     218             :     /*---------------------------------------------------------------*
     219             :      *    Build the excitation using found codeword
     220             :      *---------------------------------------------------------------*/
     221             : 
     222       14181 :     set16_fx( exc_fx, 0, L_SUBFR );
     223       14181 :     set16_fx( yy1_fx, 0, L_SUBFR );
     224       14181 :     tmp16 = sub( extract_l( L_mac0( L_IMPULSE2, *imp_shape, L_IMPULSE ) ), *imp_pos );
     225       14181 :     pt_Glt = &Glottal_cdbk_fx[tmp16]; // Q13
     226       14181 :     move16();
     227       14181 :     j = add( *imp_pos, L_IMPULSE2 );
     228      255258 :     FOR( i = sub( *imp_pos, L_IMPULSE2 ); i <= j; i++ )
     229             :     {
     230      241077 :         test();
     231      241077 :         if ( i >= 0 && LT_16( i, L_SUBFR ) )
     232             :         {
     233      226405 :             exc_fx[i] = pt_Glt[i];
     234      226405 :             move16(); /*Q13*/
     235             :         }
     236             :     }
     237             : 
     238             :     /*---------------------------------------------------------------*
     239             :      *    Form filtered excitation, find gain_trans
     240             :      *---------------------------------------------------------------*/
     241       14181 :     convolve_tc2_fx( exc_fx, h_orig_fx, yy1_fx, *imp_pos );
     242             : 
     243             :     /* Find the ACELP correlations and the pitch gain (for current subframe) */
     244             :     /**gain_trans = dot_product( xn, yy1, L_SUBFR )/(dot_product( yy1, yy1, L_SUBFR ) + 0.01f);*/
     245             :     /* Compute scalar product <y1[],y1[]> */
     246       14181 :     Ltmp = Dot_product( yy1_fx, yy1_fx, L_SUBFR );
     247       14181 :     exp_den = norm_l( Ltmp );
     248       14181 :     den = extract_h( L_shl( Ltmp, exp_den ) );
     249             : 
     250             :     /* Compute scalar product <xn[],y1[]> */
     251       14181 :     Ltmp1 = Dot_product( xn_fx, yy1_fx, L_SUBFR );
     252       14181 :     exp_num = sub( norm_l( Ltmp1 ), 1 );
     253       14181 :     num = extract_h( L_shl( Ltmp1, exp_num ) );
     254       14181 :     tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
     255       14181 :     num = abs_s( num );
     256             : 
     257             :     /* compute gain = xy/yy */
     258       14181 :     gain16 = div_s( num, den );
     259             : 
     260       14181 :     i = add( exp_num, sub( Q_new, 1 + 1 + 3 ) );
     261       14181 :     i = sub( i, exp_den );                              /* Gain_trans in Q7 */
     262       14181 :     gain16 = i_mult2( gain16, tmp16 );                  /* apply sign */
     263       14181 :     *gain_trans_fx = L_shr( L_deposit_l( gain16 ), i ); // Q7
     264       14181 :     move32();
     265       14181 : }
     266             : /*-------------------------------------------------------------------*
     267             :  *    convolve_tc_fx:
     268             :  *
     269             :  *   convolution for different vectors' lengths
     270             :  *-------------------------------------------------------------------*/
     271      113448 : static void convolve_tc_fx(
     272             :     const Word16 g[], /* i  :  input vector                                Qx      */
     273             :     const Word16 h[], /* i  :  impulse response (or second input vector)   Q15     */
     274             :     Word16 y[],       /* o  :  output vector (result of convolution)        12 bits */
     275             :     const Word16 L_1, /* i  :  vector h size                                Q0      */
     276             :     const Word16 L_2  /* i  :  vector g size                                Q0      */
     277             : )
     278             : {
     279             :     Word16 i, n, len;
     280             :     Word32 L_sum;
     281             : 
     282     7374120 :     FOR( n = 0; n < L_2; n++ )
     283             :     {
     284     7260672 :         len = s_min( add( n, 1 ), L_1 );
     285     7260672 :         L_sum = L_mult( g[0], h[n] ); /* Qx */
     286    99487383 :         FOR( i = 1; i < len; i++ )
     287             :         {
     288    92226711 :             L_sum = L_mac( L_sum, g[i], h[n - i] ); /* Qx + 16 */
     289             :         }
     290             : 
     291     7260672 :         y[n] = round_fx( L_sum ); /* Qx */
     292             :     }
     293      113448 : }
     294             : /*-------------------------------------------------------------------*
     295             :  * convolve_tc2_fx:
     296             :  *
     297             :  *   convolution for one vector with only L_IMPULSE nonzero coefficients
     298             :  *-------------------------------------------------------------------*/
     299       14181 : static void convolve_tc2_fx(
     300             :     const Word16 g[],    /* i  : input vector                                Qx      */
     301             :     const Word16 h[],    /* i  : impulse response (or second input vector)   Q15     */
     302             :     Word16 y[],          /* o  : output vector (result of convolution)        12 bits */
     303             :     const Word16 pos_max /* o  : artificial impulse position                 Q0       */
     304             : )
     305             : {
     306             :     Word32 temp;
     307             :     Word16 i, n;
     308             :     Word16 i_start, i_end, i_end2;
     309             : 
     310       14181 :     i_start = sub( pos_max, L_IMPULSE2 ); // Q0
     311       14181 :     i_start = s_max( i_start, 0 );
     312             : 
     313       14181 :     i_end = add( pos_max, L_IMPULSE ); // Q0
     314       14181 :     i_end = s_min( i_end, L_SUBFR );
     315             : 
     316      661436 :     FOR( n = i_start; n < L_SUBFR; n++ )
     317             :     {
     318      647255 :         temp = L_mult( g[0], h[n] ); /* Qx + 16 */
     319      647255 :         i_end2 = s_min( add( n, 1 ), i_end );
     320             : 
     321    19640165 :         FOR( i = 1; i < i_end2; i++ )
     322             :         {
     323    18992910 :             temp = L_mac( temp, g[i], h[n - i] ); // Qx + 16
     324             :         }
     325      647255 :         y[n] = round_fx( temp ); // Qx
     326             :     }
     327       14181 : }
     328             : /*-------------------------------------------------------------------*
     329             :  * correlate_tc:
     330             :  *
     331             :  *   correlation for different vectors' lengths
     332             :  *-------------------------------------------------------------------*/
     333      102745 : static void correlate_tc_fx(
     334             :     const Word16 *x,    /* i: target signal                                                                             Qx*/
     335             :     Word16 *y,          /* o: correlation between x[] and h[]                                   -Q3*/
     336             :     const Word16 *h,    /* i: impulse response (of weighted synthesis filter)   Q15*/
     337             :     const Word16 start, /* i: index of iterest                                                                  Q0*/
     338             :     const Word16 L_1,   /* i: vector size                                                                               Q0*/
     339             :     const Word16 L_2    /* i: index of interest                                                                 Q0*/
     340             : )
     341             : {
     342             :     Word16 i, j;
     343             :     Word32 s;
     344             : 
     345      838875 :     FOR( i = start; i < L_2; i++ )
     346             :     {
     347      736130 :         s = L_deposit_l( 0 );
     348    31415050 :         FOR( j = i; j < L_1; j++ )
     349             :         {
     350    30678920 :             s = L_mac_sat( s, x[j], h[j - i] ); /* Qx + 16 */
     351             :         }
     352      736130 :         y[i] = round_fx_sat( s ); /* Qx */
     353             :     }
     354      102745 : }

Generated by: LCOV version 1.14