LCOV - code coverage report
Current view: top level - lib_enc - set_impulse_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 129 129 100.0 %
Date: 2025-09-14 03:13:15 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       14413 : 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             : #ifndef ISSUE_1867_replace_overflow_libenc
      69             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      70             :     Flag Overflow = 0;
      71             :     move32();
      72             : #endif
      73             : #endif
      74       14413 :     krit_max_fx = -32768;
      75       14413 :     move16();
      76             : 
      77             :     /* main loop */
      78             :     /*  impulse  */
      79      129717 :     FOR( m = 0; m < NUM_IMPULSE; m++ )
      80             :     {
      81             :         /* set searching ranges */
      82      115304 :         IF( LT_16( *imp_pos, L_SUBFR - INPOL ) )
      83             :         {
      84      111951 :             end1 = add( *imp_pos, INPOL ); // Q0
      85             :         }
      86             :         ELSE
      87             :         {
      88        3353 :             end1 = L_SUBFR;
      89        3353 :             move16();
      90             :         }
      91      115304 :         IF( GT_16( *imp_pos, INPOL ) )
      92             :         {
      93      101740 :             start1 = sub( *imp_pos, INPOL ); // Q0
      94             :         }
      95             :         ELSE
      96             :         {
      97       13564 :             start1 = 0;
      98       13564 :             move16();
      99             :         }
     100      115304 :         IF( GT_16( start1, L_IMPULSE2 ) )
     101             :         {
     102       83023 :             start2 = start1;
     103       83023 :             move16();
     104             :         }
     105             :         ELSE
     106             :         {
     107       32281 :             start2 = L_IMPULSE2;
     108       32281 :             move16();
     109             :         }
     110             : 
     111             :         /*-----------------------------------------------------------*
     112             :          *   nominator & DEnominator, gh=convolve(g,h)
     113             :          *-----------------------------------------------------------*/
     114      115304 :         IF( LT_16( start1, L_IMPULSE2 ) )
     115             :         {
     116       29073 :             Lrr = L_deposit_l( 0 );
     117       29073 :             Ldd = L_deposit_l( 0 );
     118       29073 :             convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - start1],
     119       29073 :                             &h_orig_fx[0], gh_fx, add( L_IMPULSE - L_IMPULSE2, start1 ), L_SUBFR );
     120             : 
     121             :             /* nominator & DEnominator row <0> */
     122     1889745 :             FOR( i = 0; i < L_SUBFR; i++ )
     123             :             {
     124             : #ifdef ISSUE_1867_replace_overflow_libenc
     125     1860672 :                 Lrr = L_mac_sat( Lrr, gh_fx[i], gh_fx[i] ); // Q27
     126     1860672 :                 Ldd = L_mac_sat( Ldd, gh_fx[i], xn_fx[i] ); // Q27
     127             : #else
     128             :                 Lrr = L_mac_o( Lrr, gh_fx[i], gh_fx[i], &Overflow );                                                                     // Q27
     129             :                 Ldd = L_mac_o( Ldd, gh_fx[i], xn_fx[i], &Overflow );                                                                     // Q27
     130             : #endif
     131             :             }
     132       29073 :             rr_fx[start1] = Lrr;
     133       29073 :             move32();
     134             : #ifdef ISSUE_1867_replace_overflow_libenc
     135       29073 :             dd_fx[start1] = round_fx_sat( Ldd ); // Q11
     136             : #else
     137             :             dd_fx[start1] = round_fx_o( Ldd, &Overflow );                                                                                // Q11
     138             : #endif
     139       29073 :             rr_fx[start1] = L_max( rr_fx[start1], 1 );
     140             : 
     141      169405 :             FOR( i = add( start1, 1 ); i < L_IMPULSE2; i++ )
     142             :             {
     143      140332 :                 Lrr = L_deposit_l( 0 );
     144      140332 :                 Ldd = L_deposit_l( 0 );
     145             :                 /* DEnominator rows <1,L_IMPULSE2-1> */
     146     8981248 :                 FOR( j = L_SUBFR - 1; j > 0; j-- )
     147             :                 {
     148             :                     /* gh_fx[j] = gh_fx[j-1] + glottal_cdbk[m*L_IMPULSE+L_IMPULSE2-i]*h_orig_fx[j] */
     149     8840916 :                     gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
     150     8840916 :                                       Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[j] ); // Q13
     151     8840916 :                     move16();
     152             : #ifdef ISSUE_1867_replace_overflow_libenc
     153     8840916 :                     Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); // Q27
     154     8840916 :                     Ldd = L_mac_sat( Ldd, gh_fx[j], xn_fx[j] ); // Q27
     155             : #else
     156             :                     Lrr = L_mac_o( Lrr, gh_fx[j], gh_fx[j], &Overflow );                                                                 // Q27
     157             :                     Ldd = L_mac_o( Ldd, gh_fx[j], xn_fx[j], &Overflow );                                                                 // Q27
     158             : #endif
     159             :                 }
     160             : 
     161      140332 :                 gh_fx[0] = mult_r( Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[0] ); // Q13
     162      140332 :                 move16();
     163             : #ifdef ISSUE_1867_replace_overflow_libenc
     164      140332 :                 Lrr = L_mac_sat( Lrr, gh_fx[0], gh_fx[0] ); // Q27
     165      140332 :                 Ldd = L_mac_sat( Ldd, gh_fx[0], xn_fx[0] ); // Q27
     166             : #else
     167             :                 Lrr = L_mac_o( Lrr, gh_fx[0], gh_fx[0], &Overflow );                                                                     // Q27
     168             :                 Ldd = L_mac_o( Ldd, gh_fx[0], xn_fx[0], &Overflow );                                                                     // Q27
     169             : #endif
     170      140332 :                 dd_fx[i] = round_fx_sat( Ldd ); // Q11
     171      140332 :                 rr_fx[i] = L_max( Lrr, 1 );
     172      140332 :                 move32();
     173             :                 /* move rr and dd into rr[i] and dd[i] */
     174             :             }
     175             : 
     176             :             /* complete convolution(excitation,h_orig) */
     177     1860672 :             FOR( j = L_SUBFR - 1; j > 0; j-- )
     178             :             {
     179     1831599 :                 gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
     180     1831599 :                                   Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx[j] ); // Q13
     181             :             }
     182             :         }
     183             :         ELSE
     184             :         {
     185       86231 :             convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx, gh_fx, L_IMPULSE, L_SUBFR );
     186             :         }
     187             : 
     188      115304 :         IF( GE_16( end1, start2 ) )
     189             :         {
     190             :             /* DEnominator row <L_SUBFR-1> */
     191      104567 :             Lrr = L_mult( gh_fx[0], gh_fx[0] ); // Q27
     192      941103 :             FOR( j = 1; j <= L_IMPULSE2; j++ )
     193             :             {
     194             :                 /*rr[L_SUBFR-1] += gh[j]*gh[j];*/
     195      836536 :                 Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); // Q27
     196             :             }
     197      104567 :             rr_fx[L_SUBFR - 1] = Lrr;
     198      104567 :             move32();
     199             :             /* DEnominator rows <L_IMPULSE2,L_SUBFR-2> */
     200     4050710 :             FOR( i = L_SUBFR - 2; i >= start2; i-- )
     201             :             {
     202             :                 /*rr[i] = rr[i+1] + gh[L_SUBFR+L_IMPULSE2-1-i]*gh[L_SUBFR+L_IMPULSE2-1-i];*/
     203             : #ifdef ISSUE_1867_replace_overflow_libenc
     204     3946143 :                 rr_fx[i] = L_mac_sat( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i] ); // Q27
     205             : #else
     206             :                 rr_fx[i] = L_mac_o( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], &Overflow ); // Q27
     207             : #endif
     208     3946143 :                 move32();
     209             :             }
     210             :             /* nominator rows <L_IMPULSE2,L_SUBFR-1> */
     211      104567 :             correlate_tc_fx( xn_fx, &dd_fx[L_IMPULSE2], gh_fx, sub( start2, L_IMPULSE2 ),
     212      104567 :                              L_SUBFR, sub( end1, L_IMPULSE2 ) );
     213             :         }
     214             :         /*------------------------------------------------------------*
     215             :          *    maxim. criterion
     216             :          *------------------------------------------------------------*/
     217     1004209 :         FOR( i = start1; i < end1; i++ )
     218             :         {
     219             :             /* krit = (float)(dd[i]*dd[i])/rr[i] */
     220      888905 :             exp_num = sub( norm_s( dd_fx[i] ), 1 );
     221      888905 :             num = shl( dd_fx[i], exp_num );
     222      888905 :             num = mult_r( num, num );
     223             : 
     224      888905 :             exp_den = norm_l( rr_fx[i] );
     225      888905 :             den = extract_h( L_shl( rr_fx[i], exp_den ) );
     226             : 
     227      888905 :             num = div_s( num, den );
     228             : 
     229      888905 :             krit_fx = shr_sat( num, sub( sub( shl_sat( exp_num, 1 ), exp_den ), 2 ) ); /* Q18 */
     230             : 
     231      888905 :             IF( GT_16( krit_fx, krit_max_fx ) )
     232             :             {
     233       95032 :                 krit_max_fx = krit_fx; // Q18
     234       95032 :                 move16();
     235       95032 :                 *imp_pos = i;
     236       95032 :                 move16();
     237       95032 :                 *imp_shape = m;
     238       95032 :                 move16();
     239             :             }
     240             :         }
     241             :     }
     242             : 
     243             :     /*---------------------------------------------------------------*
     244             :      *    Build the excitation using found codeword
     245             :      *---------------------------------------------------------------*/
     246             : 
     247       14413 :     set16_fx( exc_fx, 0, L_SUBFR );
     248       14413 :     set16_fx( yy1_fx, 0, L_SUBFR );
     249       14413 :     tmp16 = sub( extract_l( L_mac0( L_IMPULSE2, *imp_shape, L_IMPULSE ) ), *imp_pos );
     250       14413 :     pt_Glt = &Glottal_cdbk_fx[tmp16]; // Q13
     251       14413 :     move16();
     252       14413 :     j = add( *imp_pos, L_IMPULSE2 );
     253      259434 :     FOR( i = sub( *imp_pos, L_IMPULSE2 ); i <= j; i++ )
     254             :     {
     255      245021 :         test();
     256      245021 :         if ( i >= 0 && LT_16( i, L_SUBFR ) )
     257             :         {
     258      230230 :             exc_fx[i] = pt_Glt[i];
     259      230230 :             move16(); /*Q13*/
     260             :         }
     261             :     }
     262             : 
     263             :     /*---------------------------------------------------------------*
     264             :      *    Form filtered excitation, find gain_trans
     265             :      *---------------------------------------------------------------*/
     266       14413 :     convolve_tc2_fx( exc_fx, h_orig_fx, yy1_fx, *imp_pos );
     267             : 
     268             :     /* Find the ACELP correlations and the pitch gain (for current subframe) */
     269             :     /**gain_trans = dot_product( xn, yy1, L_SUBFR )/(dot_product( yy1, yy1, L_SUBFR ) + 0.01f);*/
     270             :     /* Compute scalar product <y1[],y1[]> */
     271       14413 :     Ltmp = Dot_product( yy1_fx, yy1_fx, L_SUBFR );
     272       14413 :     exp_den = norm_l( Ltmp );
     273       14413 :     den = extract_h( L_shl( Ltmp, exp_den ) );
     274             : 
     275             :     /* Compute scalar product <xn[],y1[]> */
     276       14413 :     Ltmp1 = Dot_product( xn_fx, yy1_fx, L_SUBFR );
     277       14413 :     exp_num = sub( norm_l( Ltmp1 ), 1 );
     278       14413 :     num = extract_h( L_shl( Ltmp1, exp_num ) );
     279       14413 :     tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
     280       14413 :     num = abs_s( num );
     281             : 
     282             :     /* compute gain = xy/yy */
     283       14413 :     gain16 = div_s( num, den );
     284             : 
     285       14413 :     i = add( exp_num, sub( Q_new, 1 + 1 + 3 ) );
     286       14413 :     i = sub( i, exp_den );                              /* Gain_trans in Q7 */
     287       14413 :     gain16 = i_mult2( gain16, tmp16 );                  /* apply sign */
     288       14413 :     *gain_trans_fx = L_shr( L_deposit_l( gain16 ), i ); // Q7
     289       14413 :     move32();
     290       14413 : }
     291             : /*-------------------------------------------------------------------*
     292             :  *    convolve_tc_fx:
     293             :  *
     294             :  *   convolution for different vectors' lengths
     295             :  *-------------------------------------------------------------------*/
     296      115304 : static void convolve_tc_fx(
     297             :     const Word16 g[], /* i  :  input vector                                Qx      */
     298             :     const Word16 h[], /* i  :  impulse response (or second input vector)   Q15     */
     299             :     Word16 y[],       /* o  :  output vector (result of convolution)        12 bits */
     300             :     const Word16 L_1, /* i  :  vector h size                                Q0      */
     301             :     const Word16 L_2  /* i  :  vector g size                                Q0      */
     302             : )
     303             : {
     304             :     Word16 i, n, len;
     305             :     Word32 L_sum;
     306             : 
     307     7494760 :     FOR( n = 0; n < L_2; n++ )
     308             :     {
     309     7379456 :         len = s_min( add( n, 1 ), L_1 );
     310     7379456 :         L_sum = L_mult( g[0], h[n] ); /* Qx */
     311   101134953 :         FOR( i = 1; i < len; i++ )
     312             :         {
     313    93755497 :             L_sum = L_mac_sat( L_sum, g[i], h[n - i] ); /* Qx + 16 */
     314             :         }
     315             : 
     316     7379456 :         y[n] = round_fx_sat( L_sum ); /* Qx */
     317             :     }
     318      115304 : }
     319             : /*-------------------------------------------------------------------*
     320             :  * convolve_tc2_fx:
     321             :  *
     322             :  *   convolution for one vector with only L_IMPULSE nonzero coefficients
     323             :  *-------------------------------------------------------------------*/
     324       14413 : static void convolve_tc2_fx(
     325             :     const Word16 g[],    /* i  : input vector                                Qx      */
     326             :     const Word16 h[],    /* i  : impulse response (or second input vector)   Q15     */
     327             :     Word16 y[],          /* o  : output vector (result of convolution)        12 bits */
     328             :     const Word16 pos_max /* o  : artificial impulse position                 Q0       */
     329             : )
     330             : {
     331             :     Word32 temp;
     332             :     Word16 i, n;
     333             :     Word16 i_start, i_end, i_end2;
     334             : 
     335       14413 :     i_start = sub( pos_max, L_IMPULSE2 ); // Q0
     336       14413 :     i_start = s_max( i_start, 0 );
     337             : 
     338       14413 :     i_end = add( pos_max, L_IMPULSE ); // Q0
     339       14413 :     i_end = s_min( i_end, L_SUBFR );
     340             : 
     341      671676 :     FOR( n = i_start; n < L_SUBFR; n++ )
     342             :     {
     343      657263 :         temp = L_mult( g[0], h[n] ); /* Qx + 16 */
     344      657263 :         i_end2 = s_min( add( n, 1 ), i_end );
     345             : 
     346    19959649 :         FOR( i = 1; i < i_end2; i++ )
     347             :         {
     348    19302386 :             temp = L_mac( temp, g[i], h[n - i] ); // Qx + 16
     349             :         }
     350      657263 :         y[n] = round_fx( temp ); // Qx
     351             :     }
     352       14413 : }
     353             : /*-------------------------------------------------------------------*
     354             :  * correlate_tc:
     355             :  *
     356             :  *   correlation for different vectors' lengths
     357             :  *-------------------------------------------------------------------*/
     358      104567 : static void correlate_tc_fx(
     359             :     const Word16 *x,    /* i: target signal                                                                             Qx*/
     360             :     Word16 *y,          /* o: correlation between x[] and h[]                                   -Q3*/
     361             :     const Word16 *h,    /* i: impulse response (of weighted synthesis filter)   Q15*/
     362             :     const Word16 start, /* i: index of iterest                                                                  Q0*/
     363             :     const Word16 L_1,   /* i: vector size                                                                               Q0*/
     364             :     const Word16 L_2    /* i: index of interest                                                                 Q0*/
     365             : )
     366             : {
     367             :     Word16 i, j;
     368             :     Word32 s;
     369             : 
     370      853175 :     FOR( i = start; i < L_2; i++ )
     371             :     {
     372      748608 :         s = L_deposit_l( 0 );
     373    31923383 :         FOR( j = i; j < L_1; j++ )
     374             :         {
     375    31174775 :             s = L_mac_sat( s, x[j], h[j - i] ); /* Qx + 16 */
     376             :         }
     377      748608 :         y[i] = round_fx_sat( s ); /* Qx */
     378             :     }
     379      104567 : }

Generated by: LCOV version 1.14