LCOV - code coverage report
Current view: top level - lib_enc - set_impulse.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 81 81 100.0 %
Date: 2025-05-23 08:37:30 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #include "cnst.h"
      40             : #include "rom_com.h"
      41             : #include "prot.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : /*-----------------------------------------------------------------*
      45             :  * Local constant
      46             :  *-----------------------------------------------------------------*/
      47             : 
      48             : #define INPOL 4 /* +- range in samples for impulse position searching */
      49             : 
      50             : /*-----------------------------------------------------------------*
      51             :  * Local function prototypes
      52             :  *-----------------------------------------------------------------*/
      53             : 
      54             : static void convolve_tc( const float g[], const float h[], float y[], const int16_t L_1, const int16_t L_2 );
      55             : 
      56             : static void correlate_tc( const float *x, float *y, const float *h, const int16_t start, const int16_t L_1, const int16_t L_2 );
      57             : 
      58             : static void convolve_tc2( const float g[], const float h[], float y[], const int16_t pos_max );
      59             : 
      60             : 
      61             : /*---------------------------------------------------------------------------------------*
      62             :  * Function  set_impulse() for TC                                                        *
      63             :  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                        *
      64             :  * Builds glottal codebook contribution based on glottal impulses positions finding.     *
      65             :  *                                                                                       *
      66             :  * Returns a position of the glottal impulse center and                                  *
      67             :  * a number of the glottal impulse shape.                                                *
      68             :  *                                                                                       *
      69             :  *               |----|              |----|                                   xn         *
      70             :  *     imp_pos-> ||   |  imp_shape-> | g1 |                                   |          *
      71             :  *               | |  |              | g2 |  exc    |---|    y1  ----         |          *
      72             :  *               |  | |--------------|    |---------| h |-------|gain|-------(-)---> xn2 *
      73             :  *               |   ||              | gn |         |---|        ----                    *
      74             :  *               |----|              |----|                                              *
      75             :  *              codebook           excitation       h_orig       gain                    *
      76             :  *                                                                                       *
      77             :  *                                                                                       *
      78             :  *                                 nominator      dd    <xn,y1>*<xn,y1>                  *
      79             :  * Searching criterion: maximize ------------- = ---- = -----------------                *
      80             :  *                                denominator     rr        <y1,y1>                      *
      81             :  *                                                                                       *
      82             :  * Notice: gain = gain_trans * gain_pit (computed in trans_enc() function)               *
      83             :  *                                                                                       *
      84             :  *---------------------------------------------------------------------------------------*/
      85             : 
      86       14366 : void set_impulse(
      87             :     const float xn[],     /* i  : target signal                                   */
      88             :     const float h_orig[], /* i  : impulse response of weighted synthesis filter   */
      89             :     float exc[],          /* o  : adaptive codebook excitation                    */
      90             :     float y1[],           /* o  : filtered adaptive codebook excitation           */
      91             :     int16_t *imp_shape,   /* o  : adaptive codebook index                         */
      92             :     int16_t *imp_pos,     /* o  : position of the glottal impulse center index    */
      93             :     float *gain_trans     /* o  : transition gain                                 */
      94             : )
      95             : {
      96             :     float rr[L_SUBFR]; /*  criterion: nominator coeficients   */
      97             :     float dd[L_SUBFR]; /*  criterion: denominator coeficients */
      98             :     float gh[L_SUBFR]; /*  convolution of 'g' and 'h' filters */
      99             :     float krit, krit_max;
     100             :     int16_t i, j, m;
     101             :     int16_t start1, start2, end1;
     102             : 
     103             : 
     104       14366 :     krit_max = -1.0e+12f;
     105             : 
     106             :     /* main loop */
     107             :     /*  impulse  */
     108      129294 :     for ( m = 0; m < NUM_IMPULSE; m++ )
     109             :     {
     110             :         /* set searching ranges */
     111      114928 :         if ( *imp_pos < L_SUBFR - INPOL )
     112             :         {
     113      110893 :             end1 = *imp_pos + INPOL;
     114             :         }
     115             :         else
     116             :         {
     117        4035 :             end1 = L_SUBFR;
     118             :         }
     119      114928 :         if ( *imp_pos > INPOL )
     120             :         {
     121      101973 :             start1 = *imp_pos - INPOL;
     122             :         }
     123             :         else
     124             :         {
     125       12955 :             start1 = 0;
     126             :         }
     127      114928 :         if ( start1 > L_IMPULSE2 )
     128             :         {
     129       83532 :             start2 = start1;
     130             :         }
     131             :         else
     132             :         {
     133       31396 :             start2 = L_IMPULSE2;
     134             :         }
     135             : 
     136             :         /*-----------------------------------------------------*
     137             :          *   nominator & DEnominator, gh=conv(g,h)
     138             :          *-----------------------------------------------------*/
     139      114928 :         if ( start1 < L_IMPULSE2 )
     140             :         {
     141       28203 :             rr[start1] = 0;
     142       28203 :             dd[start1] = 0;
     143       28203 :             convolve_tc( &glottal_cdbk[m * L_IMPULSE + L_IMPULSE2 - start1], &h_orig[0], gh, (int16_t) ( L_IMPULSE - L_IMPULSE2 + start1 ), L_SUBFR );
     144             : 
     145             :             /* nominator & Denominator row <0> */
     146     1833195 :             for ( i = 0; i < L_SUBFR; i++ )
     147             :             {
     148     1804992 :                 rr[start1] += gh[i] * gh[i];
     149     1804992 :                 dd[start1] += gh[i] * xn[i];
     150             :             }
     151      163607 :             for ( i = start1 + 1; i < L_IMPULSE2; i++ )
     152             :             {
     153      135404 :                 rr[i] = 0;
     154      135404 :                 dd[i] = 0;
     155             :                 /* Denominator rows <1,L_IMPULSE2-1> */
     156     8665856 :                 for ( j = L_SUBFR - 1; j > 0; j-- )
     157             :                 {
     158     8530452 :                     gh[j] = gh[j - 1] + glottal_cdbk[m * L_IMPULSE + L_IMPULSE2 - i] * h_orig[j];
     159     8530452 :                     rr[i] += gh[j] * gh[j];
     160     8530452 :                     dd[i] += gh[j] * xn[j];
     161             :                 }
     162      135404 :                 gh[0] = glottal_cdbk[m * L_IMPULSE + L_IMPULSE2 - i] * h_orig[0];
     163      135404 :                 rr[i] += gh[0] * gh[0];
     164      135404 :                 dd[i] += gh[0] * xn[0];
     165             :                 /* move rr and dd into rr[i] and dd[i] */
     166             :             }
     167             :             /* complete convolution(excitation,h_orig) */
     168     1804992 :             for ( j = L_SUBFR - 1; j > 0; j-- )
     169             :             {
     170     1776789 :                 gh[j] = gh[j - 1] + glottal_cdbk[m * L_IMPULSE] * h_orig[j];
     171             :             }
     172             :         }
     173             :         else
     174             :         {
     175       86725 :             convolve_tc( &glottal_cdbk[m * L_IMPULSE], &h_orig[0], gh, L_IMPULSE, L_SUBFR );
     176             :         }
     177      114928 :         if ( end1 >= start2 )
     178             :         {
     179             :             /* Denominator row <L_SUBFR-1> */
     180      104871 :             rr[L_SUBFR - 1] = 0;
     181     1048710 :             for ( j = 0; j <= L_IMPULSE2; j++ )
     182             :             {
     183      943839 :                 rr[L_SUBFR - 1] += gh[j] * gh[j];
     184             :             }
     185             :             /* move rr into rr[L_SUBFFR-1 */
     186             :             /* Denominator rows <L_IMPULSE2,L_SUBFR-2> */
     187     4035154 :             for ( i = L_SUBFR - 2; i >= start2; i-- )
     188             :             {
     189     3930283 :                 rr[i] = rr[i + 1] + gh[L_SUBFR + L_IMPULSE2 - 1 - i] * gh[L_SUBFR + L_IMPULSE2 - 1 - i];
     190             :             }
     191             : 
     192             :             /* nominator rows <L_IMPULSE2,L_SUBFR-1> */
     193      104871 :             correlate_tc( xn, &dd[L_IMPULSE2], gh, (int16_t) ( start2 - L_IMPULSE2 ), L_SUBFR, (int16_t) ( end1 - L_IMPULSE2 ) );
     194             :         }
     195             : 
     196             :         /*------------------------------------------------------*
     197             :          *    maxim. criterion
     198             :          *------------------------------------------------------*/
     199     1002216 :         for ( i = start1; i < end1; i++ )
     200             :         {
     201      887288 :             krit = (float) ( dd[i] * dd[i] ) / rr[i];
     202      887288 :             if ( krit > krit_max )
     203             :             {
     204       98917 :                 krit_max = krit;
     205       98917 :                 *imp_pos = i;
     206       98917 :                 *imp_shape = m;
     207             :             }
     208             :         }
     209             :     }
     210             : 
     211             :     /*--------------------------------------------------------*
     212             :      *    Build the excitation using found codeword
     213             :      *--------------------------------------------------------*/
     214             : 
     215       14366 :     set_f( exc, 0, L_SUBFR );
     216       14366 :     set_f( y1, 0, L_SUBFR );
     217      258588 :     for ( i = ( *imp_pos - L_IMPULSE2 ); i <= ( *imp_pos + L_IMPULSE2 ); i++ )
     218             :     {
     219      244222 :         if ( ( i >= 0 ) && ( i < L_SUBFR ) )
     220             :         {
     221      229596 :             exc[i] = glottal_cdbk[( *imp_shape ) * L_IMPULSE + i - ( *imp_pos ) + L_IMPULSE2];
     222             :         }
     223             :     }
     224             : 
     225             :     /*------------------------------------------------------*
     226             :      *    Form filtered excitation, find gain_trans
     227             :      *------------------------------------------------------*/
     228             : 
     229       14366 :     convolve_tc2( exc, h_orig, y1, *imp_pos );
     230             : 
     231             :     /* Find the ACELP correlations and the pitch gain (for current subframe) */
     232       14366 :     *gain_trans = dotp( xn, y1, L_SUBFR ) / ( dotp( y1, y1, L_SUBFR ) + 0.01f );
     233             : 
     234       14366 :     return;
     235             : }
     236             : 
     237             : /*-------------------------------------------------------------------*
     238             :  * convolve_tc:
     239             :  *
     240             :  *   convolution for different vectors' lengths
     241             :  *-------------------------------------------------------------------*/
     242      114928 : static void convolve_tc(
     243             :     const float g[],   /* i  : input vector                              */
     244             :     const float h[],   /* i  : impulse response (or second input vector) */
     245             :     float y[],         /* o  : output vetor (result of convolution)      */
     246             :     const int16_t L_1, /* i  : vector h size                             */
     247             :     const int16_t L_2  /* i  : vector g size                             */
     248             : )
     249             : {
     250             :     float temp;
     251             :     int16_t i, n;
     252             : 
     253             : 
     254     7470320 :     for ( n = 0; n < L_2; n++ )
     255             :     {
     256     7355392 :         temp = g[0] * h[n];
     257   101074590 :         for ( i = 1; i < ( ( n < L_1 ) ? ( n + 1 ) : L_1 ); i++ )
     258             :         {
     259    93719198 :             temp += g[i] * h[n - i];
     260             :         }
     261     7355392 :         y[n] = temp;
     262             :     }
     263             : 
     264      114928 :     return;
     265             : }
     266             : 
     267             : /*-------------------------------------------------------------------*
     268             :  * convolve_tc2:
     269             :  *
     270             :  *   convolution for one vector with only L_IMPULSE nonzero coefficients
     271             :  *-------------------------------------------------------------------*/
     272       14366 : static void convolve_tc2(
     273             :     const float g[],      /* i  : input vector                              */
     274             :     const float h[],      /* i  : impulse response (or second input vector) */
     275             :     float y[],            /* o  : output vetor (result of convolution)      */
     276             :     const int16_t pos_max /* o  : artificial impulse position               */
     277             : )
     278             : 
     279             : {
     280             :     float temp;
     281             :     int16_t i, n;
     282             :     int16_t i_start, i_end;
     283             :     int16_t i_end2;
     284             : 
     285             : 
     286       14366 :     i_start = pos_max - L_IMPULSE2;
     287             : 
     288       14366 :     if ( i_start < 0 )
     289             :     {
     290        2341 :         i_start = 0;
     291             :     }
     292             : 
     293       14366 :     i_end = pos_max + L_IMPULSE;
     294       14366 :     if ( i_end > L_SUBFR )
     295             :     {
     296        2167 :         i_end = L_SUBFR;
     297             :     }
     298      664042 :     for ( n = i_start; n < L_SUBFR; n++ )
     299             :     {
     300      649676 :         temp = g[0] * h[n];
     301      649676 :         i_end2 = ( ( n <= i_end ) ? ( n + 1 ) : i_end );
     302    19891682 :         for ( i = 1; i < i_end2; i++ )
     303             :         {
     304    19242006 :             temp += g[i] * h[n - i];
     305             :         }
     306      649676 :         y[n] = temp;
     307             :     }
     308             : 
     309       14366 :     return;
     310             : }
     311             : 
     312             : /*-------------------------------------------------------------------*
     313             :  * correlate_tc:
     314             :  *
     315             :  *   correlation for different vectors' lengths
     316             :  *-------------------------------------------------------------------*/
     317             : 
     318      104871 : static void correlate_tc(
     319             :     const float *x,      /* i  : target signal                                   */
     320             :     float *y,            /* o  : correlation between x[] and h[]                 */
     321             :     const float *h,      /* i  : impulse response (of weighted synthesis filter) */
     322             :     const int16_t start, /* i  : index of iterest                                */
     323             :     const int16_t L_1,   /* i  : vector size                                     */
     324             :     const int16_t L_2    /* i  : index of interest                               */
     325             : )
     326             : {
     327             :     int16_t i, j;
     328             :     float s;
     329             : 
     330             : 
     331      855018 :     for ( i = start; i < L_2; i++ )
     332             :     {
     333      750147 :         s = 0.0f;
     334    31822846 :         for ( j = i; j < L_1; j++ )
     335             :         {
     336    31072699 :             s += x[j] * h[j - i];
     337             :         }
     338      750147 :         y[i] = s;
     339             :     }
     340             : 
     341      104871 :     return;
     342             : }

Generated by: LCOV version 1.14