LCOV - code coverage report
Current view: top level - lib_enc - gaus_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 0 141 0.0 %
Date: 2025-05-23 08:37:30 Functions: 0 3 0.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 "rom_com.h"
      45             : #include "prot.h"
      46             : #include "wmc_auto.h"
      47             : 
      48             : /*-------------------------------------------------------------------*
      49             :  * Local constants
      50             :  *-------------------------------------------------------------------*/
      51             : 
      52             : #define NMAX      8 /* Control of the routine's complexity */
      53             : #define FAC_DELTA 16.0f
      54             : 
      55             : /*---------------------------------------------------------------------*
      56             :  * Prototypes
      57             :  *---------------------------------------------------------------------*/
      58             : 
      59             : static int16_t cod_2pos( const int16_t ind1, const int16_t ind2, const float sign1, const float sign2, const int16_t n );
      60             : 
      61             : static void gauss2v( BSTR_ENC_HANDLE hBstr, const float h[], const float xn[], const float dn[], float code[], float y1[], float *gain, const int16_t lg, const int16_t nb_bits );
      62             : 
      63             : /*-------------------------------------------------------------------*
      64             :  * Gaus_encode
      65             :  *
      66             :  * Encoder UnVoiced excitation coding using Gaussian codebooks
      67             :  * - ACELP quantized Gaussian excitation
      68             :  * - gain quantization
      69             :  * - Total excitation for UnVoiced coders
      70             :  * - Updates
      71             :  *-------------------------------------------------------------------*/
      72             : 
      73           0 : float gaus_encode(
      74             :     Encoder_State *st,     /* i/o: encoder state structure                    */
      75             :     const int16_t i_subfr, /* i  : subframe index                             */
      76             :     const float *h1,       /* i  : weighted filter input response             */
      77             :     const float *xn,       /* i  : target vector                              */
      78             :     float *exc,            /* o  : pointer to excitation signal frame         */
      79             :     float *mem_w0,         /* o  : weighting filter denominator memory        */
      80             :     float *gp_clip_mem,    /* o  : memory of gain of pitch clipping algorithm */
      81             :     float *tilt_code,      /* o  : synthesis excitation spectrum tilt         */
      82             :     float *code,           /* o  : algebraic excitation                       */
      83             :     float *gain_code,      /* o  : Code gain.                                 */
      84             :     float *y2,             /* o  : zero-memory filtered adaptive excitation   */
      85             :     float *gain_inov,      /* o  : innovation gain                            */
      86             :     float *voice_fac,      /* o  : voicing factor                             */
      87             :     float *gain_pit,       /* o  : adaptive excitation gain                   */
      88             :     float *norm_gain_code  /* o  : normalized innovative cb. gain             */
      89             : )
      90             : {
      91           0 :     int16_t i = 0, nb_bits, idx;
      92             :     float dn[L_SUBFR]; /* Correlation between xn and h1     */
      93           0 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
      94             : 
      95             :     /*----------------------------------------------------------------*
      96             :      *  Encode gaussian excitation
      97             :      *----------------------------------------------------------------*/
      98             : 
      99           0 :     corr_xh( xn, dn, h1, L_SUBFR ); /* Correlation between target xn[] and impulse response h1[] */
     100             : 
     101           0 :     nb_bits = st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR];
     102             : 
     103           0 :     gauss2v( hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, nb_bits >> 1 );
     104             : 
     105             :     /*----------------------------------------------------------------*
     106             :      *  Encode gaussian gain
     107             :      *----------------------------------------------------------------*/
     108             : 
     109             :     /* codeword energy computation */
     110           0 :     *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR );
     111             : 
     112           0 :     nb_bits = st->acelp_cfg.gains_mode[i_subfr / L_SUBFR];
     113             : 
     114           0 :     idx = gain_enc_gaus( gain_code, nb_bits, -30.0f, 190.0f );
     115           0 :     push_indice( hBstr, IND_GAIN, idx, nb_bits );
     116             : 
     117             :     /*-----------------------------------------------------------------*
     118             :      * Total excitation for Unvoiced coders
     119             :      *-----------------------------------------------------------------*/
     120             : 
     121           0 :     for ( i = 0; i < L_SUBFR; i++ )
     122             :     {
     123           0 :         exc[i + i_subfr] = *gain_code * code[i];
     124             :     }
     125             : 
     126             :     /*-----------------------------------------------------------------*
     127             :      * Updates: last value of new target is stored in mem_w0
     128             :      *-----------------------------------------------------------------*/
     129             : 
     130           0 :     *mem_w0 = xn[L_SUBFR - 1] - *gain_code * y2[L_SUBFR - 1];
     131             : 
     132           0 :     init_gp_clip( gp_clip_mem ); /* reset pitch clipping parameters  */
     133           0 :     *gain_pit = 0.0f;
     134           0 :     *tilt_code = 0.0f;  /* purely unvoiced  */
     135           0 :     *voice_fac = -1.0f; /* purely unvoiced  */
     136             : 
     137           0 :     *norm_gain_code = *gain_code / *gain_inov;
     138             : 
     139           0 :     return L_SUBFR;
     140             : }
     141             : 
     142             : /*-------------------------------------------------------------------*
     143             :  * gauss2v()
     144             :  *
     145             :  * encoder of Gaussian Codebook for unvoiced
     146             :  * consisting of addition of 2 Gaussian vectors
     147             :  *
     148             :  * One Gaussian vector of 192 values vectors delayed by 2
     149             :  *-------------------------------------------------------------------*/
     150             : 
     151           0 : static void gauss2v(
     152             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle                */
     153             :     const float h[],       /* i  : weighted LP filter impulse response     */
     154             :     const float xn[],      /* i  : target signal                           */
     155             :     const float dn[],      /* i  : backward filtered target                */
     156             :     float code[],          /* o  : gaussian excitation                     */
     157             :     float y11[],           /* o  : zero-memory filtered gauss. excitation  */
     158             :     float *gain,           /* o  : excitation gain                         */
     159             :     const int16_t lg,      /* i  : subframe size                           */
     160             :     const int16_t nb_bits  /* i  : nb ob bits per track (max 6)            */
     161             : )
     162             : {
     163             :     int16_t i, j, ind1, ind2, idx;
     164             :     int16_t nvec, step;
     165             :     float cor, cora, cor2, cor2w, eneri, enerw;
     166             :     float *pt1, *pt2;
     167             :     float max_val[NMAX + 1], *pos[NMAX + 1], sign[NMAX + 1];
     168             :     float ener[NMAX + 1], corr[NMAX + 1], ener1;
     169             :     float dico2[L_SUBFR * NMAX];
     170             :     float c1, c0;
     171             :     float gxx, gcc;
     172             :     float gaus_dico2[190];
     173             :     float hg[190];
     174             :     float delta;
     175             :     int16_t index_delta;
     176             : 
     177             :     /*-----------------------------------------------------------------*
     178             :      * Encode the tilt of gaussian excitation
     179             :      *-----------------------------------------------------------------*/
     180             : 
     181           0 :     c0 = 0.0f; /* Compute spectral tilt of target */
     182           0 :     c1 = 0.0f;
     183           0 :     for ( i = 1; i < L_SUBFR; i++ )
     184             :     {
     185           0 :         c0 += xn[i] * xn[i];
     186           0 :         c1 += xn[i] * xn[i - 1];
     187             :     }
     188           0 :     if ( c0 < FLT_MIN )
     189             :     {
     190           0 :         gxx = 0.f;
     191             :     }
     192             :     else
     193             :     {
     194           0 :         gxx = c1 / c0;
     195             :     }
     196             : 
     197           0 :     set_f( hg, 0, 190 ); /* Compute spectral tilt of filtered codebook */
     198           0 :     mvr2r( h, hg, L_SUBFR );
     199           0 :     conv( gaus_dico, hg, gaus_dico2, 190 );
     200             : 
     201           0 :     c0 = 0.0f;
     202           0 :     c1 = 0.0f;
     203           0 :     for ( i = 1; i < 190; i++ )
     204             :     {
     205           0 :         c0 += gaus_dico2[i] * gaus_dico2[i];
     206           0 :         c1 += gaus_dico2[i] * gaus_dico2[i - 1];
     207             :     }
     208           0 :     gcc = c1 / c0;
     209           0 :     delta = ( 1 - gcc * gxx ) / ( 2 * gcc + gxx ); /* Compute and quantize spectral tilt modification factor (3b) */
     210             : 
     211           0 :     index_delta = (int16_t) ( FAC_DELTA * delta );
     212           0 :     if ( index_delta < 0 )
     213             :     {
     214           0 :         index_delta = 0;
     215             :     }
     216           0 :     if ( index_delta > 7 )
     217             :     {
     218           0 :         index_delta = 7;
     219             :     }
     220             : 
     221           0 :     delta = STEP_DELTA * (float) index_delta;
     222           0 :     if ( delta > 0.0f ) /* Adapt spectral tilt of initial codebook */
     223             :     {
     224           0 :         gaus_dico2[0] = gaus_dico[0];
     225           0 :         for ( i = 1; i < 190; i++ )
     226             :         {
     227           0 :             gaus_dico2[i] = ( gaus_dico[i] - delta * gaus_dico[i - 1] ) / ( 1 + delta * delta );
     228             :         }
     229             :     }
     230             :     else
     231             :     {
     232           0 :         for ( i = 0; i < 190; i++ )
     233             :         {
     234           0 :             gaus_dico2[i] = gaus_dico[i];
     235             :         }
     236             :     }
     237             : 
     238             :     /*-----------------------------------------------------------------*
     239             :      * Codebook search initializations
     240             :      *-----------------------------------------------------------------*/
     241             : 
     242           0 :     ind1 = 0;
     243           0 :     ind2 = 0;
     244             : 
     245           0 :     nvec = 1 << nb_bits;
     246           0 :     step = 0x80 >> nb_bits;
     247             : 
     248             :     /*-----------------------------------------------------------------*
     249             :      * dot product between dn and gaussian codevectors,
     250             :      * keep NMAX best vectors
     251             :      *-----------------------------------------------------------------*/
     252             : 
     253           0 :     set_f( max_val, 0, NMAX + 1 );
     254           0 :     set_f( sign, 0, NMAX + 1 );
     255             : 
     256           0 :     for ( i = 0; i < NMAX + 1; i++ )
     257             :     {
     258           0 :         pos[i] = (float *) gaus_dico2;
     259             :     }
     260             : 
     261           0 :     pt1 = (float *) gaus_dico2;
     262             : 
     263           0 :     for ( i = 0; i < nvec; i++, pt1 += step )
     264             :     {
     265           0 :         cor = dotp( pt1, dn, lg );
     266           0 :         cora = (float) fabs( cor );
     267           0 :         j = NMAX - 1;
     268             :         do
     269             :         {
     270           0 :             if ( cora >= max_val[j] )
     271             :             {
     272           0 :                 max_val[j + 1] = max_val[j];
     273           0 :                 pos[j + 1] = pos[j];
     274           0 :                 sign[j + 1] = sign[j];
     275           0 :                 max_val[j] = cora;
     276           0 :                 pos[j] = pt1;
     277           0 :                 sign[j] = cor;
     278             :             }
     279             : 
     280           0 :             j--;
     281           0 :         } while ( j >= 0 );
     282             :     }
     283             : 
     284             :     /*-----------------------------------------------------------------*
     285             :      * filter selected vectors
     286             :      * put sign
     287             :      * compute energy
     288             :      *-----------------------------------------------------------------*/
     289             : 
     290           0 :     pt1 = dico2;
     291           0 :     for ( i = 0; i < NMAX; i++, pt1 += L_SUBFR )
     292             :     {
     293           0 :         conv( pos[i], h, pt1, lg );
     294             : 
     295             :         /* put sign and compute energy */
     296           0 :         if ( sign[i] < 0.0f )
     297             :         {
     298           0 :             for ( j = 0; j < lg; j++ )
     299             :             {
     300           0 :                 pt1[j] = -pt1[j]; /*Store into dico2*/
     301             :             }
     302             :         }
     303           0 :         ener[i] = dotp( pt1, pt1, lg );
     304           0 :         corr[i] = dotp( pt1, xn, lg ); /* must be equal to sign[i] */
     305             :     }
     306             : 
     307             :     /*-----------------------------------------------------------------*
     308             :      * try all combinations of NMAX best vectors
     309             :      *-----------------------------------------------------------------*/
     310             : 
     311           0 :     pt1 = dico2;
     312             : 
     313             :     /* Initial values for search algorithm */
     314           0 :     enerw = 1.0f;
     315           0 :     cor2w = -1.0f;
     316             : 
     317           0 :     for ( i = 0; i < NMAX; i++, pt1 += L_SUBFR )
     318             :     {
     319           0 :         pt2 = pt1;
     320           0 :         for ( j = i; j < NMAX; j++, pt2 += L_SUBFR )
     321             :         {
     322           0 :             cor = corr[i] + corr[j];
     323           0 :             eneri = ener[i] + ener[j] + 2.0f * dotp( pt1, pt2, lg );
     324           0 :             cor2 = cor * cor;
     325           0 :             if ( cor2 * enerw > cor2w * eneri )
     326             :             {
     327           0 :                 cor2w = cor2;
     328           0 :                 enerw = eneri;
     329           0 :                 ind1 = i;
     330           0 :                 ind2 = j;
     331             :             }
     332             :         }
     333             :     }
     334             : 
     335             :     /*-----------------------------------------------------------------*
     336             :      * Compute zero-memory filtered gauss. excitation y
     337             :      *-----------------------------------------------------------------*/
     338             : 
     339           0 :     pt1 = dico2 + ind1 * L_SUBFR;
     340           0 :     pt2 = dico2 + ind2 * L_SUBFR;
     341           0 :     for ( i = 0; i < lg; i++ )
     342             :     {
     343           0 :         y11[i] = pt1[i] + pt2[i];
     344             :     }
     345             : 
     346             :     /*-----------------------------------------------------------------*
     347             :      * Signs of vectors
     348             :      *-----------------------------------------------------------------*/
     349             : 
     350           0 :     if ( sign[ind1] >= 0.0f )
     351             :     {
     352           0 :         sign[ind1] = 1.0f;
     353             :     }
     354             :     else
     355             :     {
     356           0 :         sign[ind1] = -1.0f;
     357             :     }
     358             : 
     359           0 :     if ( sign[ind2] >= 0.0f )
     360             :     {
     361           0 :         sign[ind2] = 1.0f;
     362             :     }
     363             :     else
     364             :     {
     365           0 :         sign[ind2] = -1.0f;
     366             :     }
     367             : 
     368             :     /*-----------------------------------------------------------------*
     369             :      * Compute code
     370             :      *-----------------------------------------------------------------*/
     371             : 
     372           0 :     pt1 = pos[ind1];
     373           0 :     pt2 = pos[ind2];
     374           0 :     for ( i = 0; i < lg; i++ )
     375             :     {
     376           0 :         code[i] = pt1[i] * sign[ind1] + pt2[i] * sign[ind2];
     377             :     }
     378           0 :     cor = corr[ind1] + corr[ind2];
     379             : 
     380             :     /*-----------------------------------------------------------------*
     381             :      * Compute index
     382             :      *-----------------------------------------------------------------*/
     383             : 
     384           0 :     i = (int16_t) ( ( pos[ind1] - gaus_dico2 ) / step ); /* Division by step can be replaced by shift */
     385           0 :     j = (int16_t) ( ( pos[ind2] - gaus_dico2 ) / step ); /* Division by step can be replaced by shift */
     386             : 
     387           0 :     idx = cod_2pos( i, j, sign[ind1], sign[ind2], nvec );
     388             : 
     389           0 :     push_indice( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 );
     390           0 :     push_indice( hBstr, IND_TILT_FACTOR, index_delta, 3 );
     391             : 
     392             :     /*-----------------------------------------------------------------*
     393             :      * Find quantized gain
     394             :      *-----------------------------------------------------------------*/
     395             : 
     396           0 :     *gain = cor / enerw;
     397           0 :     ener1 = dotp( xn, xn, lg );
     398           0 :     ener1 = (float) sqrt( ener1 / enerw ); /* Minimize ebergy error */
     399           0 :     *gain = *gain * 0.6f + ener1 * 0.4f;
     400             : 
     401           0 :     return;
     402             : }
     403             : 
     404             : /*---------------------------------------------------------------------*
     405             :  * Put selected codevector positions and signs into quantization index
     406             :  *---------------------------------------------------------------------*/
     407             : 
     408             : /*! r: codebook quantization index */
     409           0 : static int16_t cod_2pos(
     410             :     const int16_t ind1, /* i  : index of 1st gaussian vector  */
     411             :     const int16_t ind2, /* i  : index of 2nd gaussian vector  */
     412             :     const float sign1,  /* i  : sign of 1st gaussian vector   */
     413             :     const float sign2,  /* i  : sign of 2nd gaussian vector   */
     414             :     const int16_t n     /* i  : nb. of codebook vectors       */
     415             : )
     416             : {
     417             :     int16_t i1, i2, index, s1, s2;
     418             : 
     419             : 
     420           0 :     s1 = 1;
     421           0 :     if ( sign1 > 0.0f )
     422             :     {
     423           0 :         s1 = 0;
     424             :     }
     425             : 
     426           0 :     s2 = 1;
     427           0 :     if ( sign2 > 0.0f )
     428             :     {
     429           0 :         s2 = 0;
     430             :     }
     431             : 
     432           0 :     if ( s1 == s2 )
     433             :     {
     434           0 :         if ( ind1 <= ind2 )
     435             :         {
     436           0 :             i1 = ind1;
     437           0 :             i2 = ind2;
     438             :         }
     439             :         else
     440             :         {
     441           0 :             i1 = ind2;
     442           0 :             i2 = ind1;
     443             :         }
     444             :     }
     445             :     else
     446             :     {
     447           0 :         if ( ind1 > ind2 )
     448             :         {
     449           0 :             i1 = ind1;
     450           0 :             i2 = ind2;
     451             :         }
     452             :         else
     453             :         {
     454           0 :             i1 = ind2;
     455           0 :             i2 = ind1;
     456           0 :             s1 = s2;
     457             :         }
     458             :     }
     459           0 :     index = i1 * n + i2;
     460           0 :     index = ( index << 1 ) + s1;
     461             : 
     462           0 :     return index;
     463             : }

Generated by: LCOV version 1.14