LCOV - code coverage report
Current view: top level - lib_enc - lp_exc_e.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 60 63 95.2 %
Date: 2025-05-23 08:37:30 Functions: 3 3 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             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include <math.h>
      43             : #include "cnst.h"
      44             : #include "prot.h"
      45             : #include "wmc_auto.h"
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * Local constants
      49             :  *-------------------------------------------------------------------*/
      50             : 
      51             : #define GAIN_PIT_MAX      1.2f
      52             : #define ACELP_GAINS_CONST 0.8f /* adaptive codebook gain constraint */
      53             : 
      54             : 
      55             : /*-------------------------------------------------------------------*
      56             :  * Local function prototypes
      57             :  *-------------------------------------------------------------------*/
      58             : 
      59             : static float adpt_enr( const int16_t codec_mode, const float *exc, const float *h1, float *y1, const int16_t L_subfr, float *gain, float *g_corr, const int16_t clip_gain, const float *xn, float *xn2, int16_t use_prev_sf_pit_gain );
      60             : 
      61             : 
      62             : /*-------------------------------------------------------------------*
      63             :  * lp_filt_exc_enc()
      64             :  *
      65             :  * Low-pass filtering of the adaptive excitation
      66             :  * Innovation target construction
      67             :  * Gain quantization limitation
      68             :  *-------------------------------------------------------------------*/
      69             : 
      70      600778 : int16_t lp_filt_exc_enc(
      71             :     const int16_t codec_mode, /* i  : codec mode                                  */
      72             :     const int16_t coder_type, /* i  : coding type                                 */
      73             :     const int16_t i_subfr,    /* i  : subframe index                              */
      74             :     float *exc,               /* i/o: pointer to excitation signal frame          */
      75             :     const float *h1,          /* i  : weighted filter input response              */
      76             :     const float *xn,          /* i  : target vector                               */
      77             :     float *y1,                /* o  : zero-memory filtered adaptive excitation    */
      78             :     float *xn2,               /* o  : target vector for innovation search         */
      79             :     const int16_t L_subfr,    /* i  : length of vectors for gain quantization     */
      80             :     const int16_t L_frame,    /* i  : frame size                                  */
      81             :     float *g_corr,            /* o  : ACELP correlation values                    */
      82             :     const int16_t clip_gain,  /* i  : adaptive gain clipping flag                 */
      83             :     float *gain_pit,          /* o  : adaptive excitation gain                    */
      84             :     int16_t *lp_flag          /* i/o: mode selection                              */
      85             : )
      86             : {
      87             :     float ener, ener_tmp, gain1, gain2, g_corr2[2], exc_tmp[L_FRAME16k], xn2_tmp[L_FRAME16k];
      88             :     float y1_tmp[L_FRAME16k];
      89             :     int16_t select, i;
      90             :     int16_t use_prev_sf_pit_gain;
      91             : 
      92      600778 :     gain1 = 0.0f;
      93      600778 :     gain2 = 0.0f;
      94      600778 :     ener = 0.0f;
      95      600778 :     ener_tmp = 0.0f;
      96      600778 :     use_prev_sf_pit_gain = 0;
      97             : 
      98             :     /*----------------------------------------------------------------*
      99             :      * Find energy of the fixed cb. target with respect to adaptive
     100             :      *   exc. filtering
     101             :      * Find flag about splitting the gain quantizer in half
     102             :      * - find the target energy if adaptive exc. is not filtered
     103             :      * - filter the adaptive excitation and find the target energy
     104             :      *   if the exc. is filtered.
     105             :      *----------------------------------------------------------------*/
     106             : 
     107      600778 :     if ( codec_mode == MODE2 && coder_type == 100 )
     108             :     {
     109           0 :         use_prev_sf_pit_gain = 1;
     110             :     }
     111             : 
     112      600778 :     if ( *lp_flag == FULL_BAND || *lp_flag == NORMAL_OPERATION )
     113             :     {
     114      559105 :         if ( use_prev_sf_pit_gain == 1 )
     115             :         {
     116           0 :             ener = adpt_enr( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, use_prev_sf_pit_gain );
     117             :         }
     118             :         else
     119             :         {
     120      559105 :             ener = adpt_enr( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, use_prev_sf_pit_gain );
     121             :         }
     122             :     }
     123             : 
     124             :     /*----------------------------------------------------------------*
     125             :      * Find energy of the fixed cb. target with respect to adaptive
     126             :      *   exc. filtering
     127             :      * filter the adaptive excitation and find the target energy
     128             :      *   if the exc. is filtered.
     129             :      *----------------------------------------------------------------*/
     130             : 
     131      600778 :     if ( *lp_flag == LOW_PASS || *lp_flag == NORMAL_OPERATION )
     132             :     {
     133      540866 :         if ( codec_mode == MODE2 && L_frame == L_FRAME16k )
     134             :         {
     135      196300 :             for ( i = 0; i < L_subfr; i++ )
     136             :             {
     137      193280 :                 exc_tmp[i] = (float) ( 0.21f * exc[i - 1 + i_subfr] + 0.58f * exc[i + i_subfr] + 0.21f * exc[i + 1 + i_subfr] );
     138             :             }
     139             :         }
     140             :         else
     141             :         {
     142    34959990 :             for ( i = 0; i < L_subfr; i++ )
     143             :             {
     144    34422144 :                 exc_tmp[i] = (float) ( 0.18f * exc[i - 1 + i_subfr] + 0.64f * exc[i + i_subfr] + 0.18f * exc[i + 1 + i_subfr] );
     145             :             }
     146             :         }
     147             : 
     148      540866 :         if ( use_prev_sf_pit_gain == 1 )
     149             :         {
     150           0 :             ener_tmp = adpt_enr( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, use_prev_sf_pit_gain );
     151             :         }
     152             :         else
     153             :         {
     154      540866 :             ener_tmp = adpt_enr( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, use_prev_sf_pit_gain );
     155             :         }
     156             :     }
     157             : 
     158             :     /*-----------------------------------------------------------------*
     159             :      * use the best prediction (minimize quadratic error)
     160             :      *-----------------------------------------------------------------*/
     161             : 
     162      600778 :     if ( ( ( ener_tmp < ener ) && ( *lp_flag == NORMAL_OPERATION ) ) || ( *lp_flag == LOW_PASS ) )
     163             :     {
     164             :         /* use the LP filter for pitch excitation prediction */
     165      375891 :         select = LOW_PASS;
     166      375891 :         mvr2r( exc_tmp, &exc[i_subfr], L_subfr );
     167      375891 :         mvr2r( y1_tmp, y1, L_subfr );
     168      375891 :         mvr2r( xn2_tmp, xn2, L_subfr );
     169             : 
     170      375891 :         if ( use_prev_sf_pit_gain == 0 )
     171             :         {
     172      375891 :             *gain_pit = gain2;
     173      375891 :             g_corr[0] = g_corr2[0];
     174      375891 :             g_corr[1] = g_corr2[1];
     175             :         }
     176             :     }
     177             :     else
     178             :     {
     179             :         /* no LP filter used for pitch excitation prediction */
     180      224887 :         select = FULL_BAND;
     181      224887 :         if ( use_prev_sf_pit_gain == 0 )
     182             :         {
     183      224887 :             *gain_pit = gain1;
     184             :         }
     185             :     }
     186             : 
     187      600778 :     return ( select );
     188             : }
     189             : 
     190             : /*-------------------------------------------------------------------*
     191             :  * adpt_enr()
     192             :  *
     193             :  * Find the adaptive excitation energy
     194             :  * This serves to decide about the filtering of the adaptive excitation
     195             :  *-------------------------------------------------------------------*/
     196             : 
     197     1099971 : static float adpt_enr(
     198             :     const int16_t codec_mode,    /* i  : codec mode                             */
     199             :     const float *exc,            /* i  : Excitation vector                      */
     200             :     const float *h1,             /* i  : impuls response                        */
     201             :     float *y1,                   /* o  : zero-memory filtered adpt. excitation  */
     202             :     const int16_t L_subfr,       /* i  : vector length                          */
     203             :     float *gain,                 /* o  : subframe adaptive gain                 */
     204             :     float *g_corr,               /* o  : correlations for adptive gain          */
     205             :     const int16_t clip_gain,     /* i  : adaptive gain clipping flag            */
     206             :     const float *xn,             /* i  : adaptive codebook target               */
     207             :     float *xn2,                  /* o  : algebraic codebook target              */
     208             :     int16_t use_prev_sf_pit_gain /* i  : flag to use prev sf pitch gain or not  */
     209             : )
     210             : {
     211             :     float ener;
     212             : 
     213     1099971 :     conv( exc, h1, y1, L_subfr );
     214     1099971 :     if ( use_prev_sf_pit_gain == 0 )
     215             :     {
     216     1099971 :         *gain = corr_xy1( xn, y1, g_corr, L_subfr, codec_mode == MODE2 );
     217             : 
     218             :         /* clip gain, if necessary to avoid problems at decoder */
     219     1099971 :         if ( clip_gain == 1 && *gain > 0.95f )
     220             :         {
     221        4273 :             *gain = 0.95f;
     222             :         }
     223             : 
     224     1099971 :         if ( clip_gain == 2 && *gain > 0.65f )
     225             :         {
     226        3031 :             *gain = 0.65f;
     227             :         }
     228             :     }
     229             : 
     230             :     /* find energy of new target xn2[] */
     231     1099971 :     updt_tar( xn, xn2, y1, *gain, L_subfr );
     232     1099971 :     ener = dotp( xn2, xn2, L_subfr );
     233             : 
     234     1099971 :     return ener;
     235             : }
     236             : 
     237             : /*-------------------------------------------------------------------*
     238             :  * corr_xy1()
     239             :  *
     240             :  * Find the correlations between the target xn[] and the filtered adaptive
     241             :  * codebook excitation y1[]. ( <y1,y1>  and -2<xn,y1> )
     242             :  *-------------------------------------------------------------------*/
     243             : 
     244             : /*! r: pitch gain  (0..GAIN_PIT_MAX) */
     245     1175242 : float corr_xy1(
     246             :     const float xn[],       /* i  : target signal                            */
     247             :     const float y1[],       /* i  : filtered adaptive codebook excitation    */
     248             :     float g_corr[],         /* o  : correlations <y1,y1>  and -2<xn,y1>      */
     249             :     const int16_t L_subfr,  /* i  : subframe length                          */
     250             :     const int16_t norm_flag /* i  : flag for constraining pitch contribution */
     251             : )
     252             : {
     253             :     float temp1, temp2, gain, gain_p_snr;
     254             : 
     255             :     /*-----------------------------------------------------------------*
     256             :      * Find the ACELP correlations and the pitch gain
     257             :      * (for current subframe)
     258             :      *-----------------------------------------------------------------*/
     259             : 
     260             :     /* Compute scalar product <xn[],y1[]> */
     261     1175242 :     temp1 = dotp( xn, y1, L_subfr );
     262             : 
     263             :     /* Compute scalar product <y1[],y1[]> */
     264     1175242 :     temp2 = dotp( y1, y1, L_subfr ) + 0.01f;
     265             : 
     266     1175242 :     g_corr[0] = temp2;
     267     1175242 :     g_corr[1] = -2.0f * temp1 + 0.01f;
     268             : 
     269             :     /* find pitch gain and bound it by [0,GAIN_PIT_MAX] */
     270     1175242 :     if ( norm_flag )
     271             :     {
     272        4360 :         gain = ( temp1 + 0.01f ) / temp2;
     273             :     }
     274             :     else
     275             :     {
     276     1170882 :         gain = temp1 / temp2;
     277             :     }
     278             : 
     279     1175242 :     if ( gain < 0.0f )
     280             :     {
     281       47021 :         gain = 0.0f;
     282             :     }
     283     1175242 :     if ( gain > GAIN_PIT_MAX )
     284             :     {
     285       75162 :         gain = GAIN_PIT_MAX;
     286             :     }
     287             : 
     288             :     /* Limit the energy of pitch contribution */
     289     1175242 :     if ( norm_flag )
     290             :     {
     291             :         /* Compute scalar product <xn[],xn[]> */
     292        4360 :         temp1 = dotp( xn, xn, L_subfr );
     293        4360 :         gain_p_snr = (float) ( ACELP_GAINS_CONST * sqrt( temp1 / temp2 ) );
     294             : 
     295        4360 :         if ( gain > gain_p_snr )
     296             :         {
     297        2288 :             gain = gain_p_snr;
     298             :         }
     299             :     }
     300             : 
     301     1175242 :     return gain;
     302             : }

Generated by: LCOV version 1.14