LCOV - code coverage report
Current view: top level - lib_com - lpc_tools.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 78 88 88.6 %
Date: 2025-05-23 08:37:30 Functions: 5 5 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 <assert.h>
      38             : #include <stdint.h>
      39             : #include "options.h"
      40             : #ifdef DEBUGGING
      41             : #include "debug.h"
      42             : #endif
      43             : #include <math.h>
      44             : #include "cnst.h"
      45             : #include "prot.h"
      46             : #include "rom_com.h"
      47             : #include "wmc_auto.h"
      48             : 
      49             : /*-----------------------------------------------------------------*
      50             :  * Local constants
      51             :  *-----------------------------------------------------------------*/
      52             : 
      53             : #define MAX_LEN_LP 960
      54             : #define SCALE1_LPC 2037.1832275390625f /* LSP to LSF conversion factor */
      55             : 
      56             : 
      57             : /*---------------------------------------------------------------------*
      58             :  * autocorr()
      59             :  *
      60             :  * Compute autocorrelations of input signal
      61             :  *---------------------------------------------------------------------*/
      62             : 
      63     3281880 : void autocorr(
      64             :     const float *x,         /* i  : input signal               */
      65             :     float *r,               /* o  : autocorrelations vector    */
      66             :     const int16_t m,        /* i  : order of LP filter         */
      67             :     const int16_t len,      /* i  : window size                */
      68             :     const float *wind,      /* i  : window                     */
      69             :     const int16_t rev_flag, /* i  : flag to reverse window     */
      70             :     const int16_t sym_flag, /* i  : symmetric window flag      */
      71             :     const int16_t no_thr    /* i  : flag to avoid thresholding */
      72             : )
      73             : {
      74             :     float t[MAX_LEN_LP];
      75             :     float s;
      76             :     int16_t i, j;
      77             : 
      78             :     /* Windowing of signal */
      79     3281880 :     if ( rev_flag == 1 )
      80             :     {
      81             :         /* time reversed window */
      82           0 :         for ( i = 0; i < len; i++ )
      83             :         {
      84           0 :             t[i] = x[i] * wind[len - i - 1];
      85             :         }
      86             :     }
      87     3281880 :     else if ( sym_flag == 1 )
      88             :     {
      89             :         /* symmetric window of even length */
      90   107755322 :         for ( i = 0; i < len / 2; i++ )
      91             :         {
      92   107141730 :             t[i] = x[i] * wind[i];
      93             :         }
      94             : 
      95   107755322 :         for ( ; i < len; i++ )
      96             :         {
      97   107141730 :             t[i] = x[i] * wind[len - 1 - i];
      98             :         }
      99             :     }
     100             :     else /* assymetric window */
     101             :     {
     102   886243008 :         for ( i = 0; i < len; i++ )
     103             :         {
     104   883574720 :             t[i] = x[i] * wind[i];
     105             :         }
     106             :     }
     107             : 
     108             :     /* Compute r[1] to r[m] */
     109    52904004 :     for ( i = 0; i <= m; i++ )
     110             :     {
     111    49622124 :         s = t[0] * t[i];
     112 16278550336 :         for ( j = 1; j < len - i; j++ )
     113             :         {
     114 16228928212 :             s += t[j] * t[i + j];
     115             :         }
     116    49622124 :         r[i] = s;
     117             :     }
     118             : 
     119     3281880 :     if ( r[0] < 100.0f && no_thr == 0 )
     120             :     {
     121      233202 :         r[0] = 100.0f;
     122             :     }
     123             : 
     124     3281880 :     return;
     125             : }
     126             : 
     127             : /*---------------------------------------------------------------------*
     128             :  * lev_dur()
     129             :  *
     130             :  * Wiener-Levinson-Durbin algorithm to compute LP parameters from the autocorrelations
     131             :  * of input signal
     132             :  *---------------------------------------------------------------------*/
     133             : 
     134             : /*! r: stability flag */
     135     3583501 : int16_t lev_dur(
     136             :     float *a,        /* o  : LP coefficients (a[0] = 1.0) */
     137             :     const float *r,  /* i  : vector of autocorrelations   */
     138             :     const int16_t m, /* i  : order of LP filter           */
     139             :     float epsP[]     /* o  : prediction error energy      */
     140             : )
     141             : {
     142             :     int16_t i, j, l;
     143             :     float buf[TCXLTP_LTP_ORDER];
     144             :     float *rc; /* reflection coefficients  0,...,m-1 */
     145             :     float s, at, err;
     146     3583501 :     int16_t flag = 0;
     147             : 
     148     3583501 :     rc = &buf[0];
     149     3583501 :     rc[0] = ( -r[1] ) / r[0];
     150     3583501 :     a[0] = 1.0f;
     151     3583501 :     a[1] = rc[0];
     152     3583501 :     err = r[0] + r[1] * rc[0];
     153     3583501 :     if ( epsP != NULL )
     154             :     {
     155     3369638 :         epsP[0] = r[0];
     156     3369638 :         epsP[1] = err;
     157             :     }
     158             : 
     159    50478690 :     for ( i = 2; i <= m; i++ )
     160             :     {
     161    46895189 :         s = 0.0f;
     162   456588763 :         for ( j = 0; j < i; j++ )
     163             :         {
     164   409693574 :             s += r[i - j] * a[j];
     165             :         }
     166             : 
     167    46895189 :         rc[i - 1] = ( -s ) / err;
     168             : 
     169    46895189 :         if ( fabs( rc[i - 1] ) > 0.99945f )
     170             :         {
     171           0 :             flag = 1; /* Test for unstable filter. If unstable keep old A(z) */
     172             :         }
     173             : 
     174   240914054 :         for ( j = 1; j <= i / 2; j++ )
     175             :         {
     176   194018865 :             l = i - j;
     177   194018865 :             at = a[j] + rc[i - 1] * a[l];
     178   194018865 :             a[l] += rc[i - 1] * a[j];
     179   194018865 :             a[j] = at;
     180             :         }
     181             : 
     182    46895189 :         a[i] = rc[i - 1];
     183             : 
     184    46895189 :         err += rc[i - 1] * s;
     185    46895189 :         if ( err <= 0.0f )
     186             :         {
     187           0 :             err = 0.01f;
     188             :         }
     189             : 
     190    46895189 :         if ( epsP != NULL )
     191             :         {
     192    43775108 :             epsP[i] = err;
     193             :         }
     194             :     }
     195             : 
     196     3583501 :     return ( flag );
     197             : }
     198             : 
     199             : 
     200             : /*---------------------------------------------------------------------*
     201             :  * E_LPC_int_lpc_tcx()
     202             :  *
     203             :  *
     204             :  *---------------------------------------------------------------------*/
     205             : 
     206      458831 : void E_LPC_int_lpc_tcx(
     207             :     const float lsf_old[], /* i  : LSFs from past frame            */
     208             :     const float lsf_new[], /* i  : LSFs from present frame         */
     209             :     float a[]              /* o  : interpolated LP coefficients    */
     210             : )
     211             : {
     212             :     int16_t i;
     213             :     float lsf[M];
     214             : 
     215     7800127 :     for ( i = 0; i < M; i++ )
     216             :     {
     217     7341296 :         lsf[i] = lsf_old[i] * 0.125f + lsf_new[i] * 0.875f;
     218             :     }
     219             : 
     220      458831 :     lsp2a_stab( lsf, a, M );
     221             : 
     222      458831 :     return;
     223             : }
     224             : 
     225             : /*---------------------------------------------------------------------*
     226             :  * lsp_reorder()
     227             :  *
     228             :  *
     229             :  *---------------------------------------------------------------------*/
     230             : 
     231       68415 : static void lsp_reorder(
     232             :     float *lsp,            /* i/o: lsp vector (acos() domain)   */
     233             :     float min_dist,        /* i  : minimum required distance    */
     234             :     const int16_t lpcorder /* i  : LPC order                    */
     235             : )
     236             : {
     237             :     int16_t i;
     238             :     float lsp_min, lsp_max;
     239             : 
     240             :     /* Verify the LSF ordering and minimum GAP */
     241       68415 :     lsp_min = min_dist;
     242             : 
     243     1163055 :     for ( i = 0; i < lpcorder; ++i )
     244             :     {
     245     1094640 :         if ( lsp[i] < lsp_min )
     246             :         {
     247        2479 :             lsp[i] = lsp_min;
     248             :         }
     249     1094640 :         lsp_min = lsp[i] + min_dist;
     250             :     }
     251             : 
     252             :     /* Reverify the LSF ordering and minimum GAP in the reverse order (security) */
     253       68415 :     lsp_max = EVS_PI - min_dist;
     254             : 
     255             :     /* If danger of unstable filter in case of resonance in HF */
     256       68415 :     if ( lsp[lpcorder - 1] > lsp_max )
     257             :     {
     258             :         /* Reverify the minimum LSF gap in the reverse sense */
     259           0 :         for ( i = lpcorder - 1; i >= 0; --i )
     260             :         {
     261           0 :             if ( lsp[i] > lsp_max )
     262             :             {
     263           0 :                 lsp[i] = lsp_max;
     264             :             }
     265           0 :             lsp_max = lsp[i] - min_dist;
     266             :         }
     267             :     }
     268             : 
     269       68415 :     return;
     270             : }
     271             : 
     272             : 
     273             : /*---------------------------------------------------------------------*
     274             :  * E_LPC_lsp_unweight()
     275             :  *
     276             :  * Approximate unweighting
     277             :  *---------------------------------------------------------------------*/
     278             : 
     279       68415 : int16_t E_LPC_lsp_unweight(
     280             :     const float lsp_w[],  /* i  : weighted lsp             */
     281             :     float lsp_uw[],       /* o  : unweighted lsp           */
     282             :     float lsf_uw[],       /* o  : unweighted lsf           */
     283             :     const float inv_gamma /* i  : inverse weighting factor */
     284             : )
     285             : {
     286             :     float lsp_w_orig[M], lsp_w_diff[M], mean, step;
     287       68415 :     const lsp_unw_triplet *unw_coeffs = NULL;
     288             :     int16_t i;
     289             : 
     290             :     /* Table selection */
     291       68415 :     if ( (float) fabs( inv_gamma - 1.0f / 0.94f ) < 0.0001f )
     292             :     {
     293           0 :         unw_coeffs = p16_gamma0_94to1;
     294             :     }
     295       68415 :     else if ( (float) fabs( inv_gamma - 1.0f / 0.92f ) < 0.0001f )
     296             :     {
     297       68415 :         unw_coeffs = p16_gamma0_92to1;
     298             :     }
     299             :     else
     300             :     {
     301           0 :         assert( 0 );
     302             :     }
     303             : 
     304       68415 :     step = EVS_PI / (float) ( M + 1 );
     305       68415 :     mean = step;
     306             : 
     307             :     /* Apply acos() and get mean removed version */
     308     1163055 :     for ( i = 0; i < M; ++i )
     309             :     {
     310     1094640 :         lsp_w_orig[i] = (float) acos( lsp_w[i] );
     311     1094640 :         lsp_w_diff[i] = lsp_w_orig[i] - mean;
     312     1094640 :         mean += step;
     313             :     }
     314             : 
     315             :     /* Approximate unweighting by 3-tap FIR */
     316             : 
     317       68415 :     lsp_uw[0] = lsp_w_orig[0] + unw_coeffs[0][1] * lsp_w_diff[0] + unw_coeffs[0][2] * lsp_w_diff[1];
     318     1026225 :     for ( i = 1; i < M - 1; ++i )
     319             :     {
     320      957810 :         lsp_uw[i] = lsp_w_orig[i] + unw_coeffs[i][0] * lsp_w_diff[i - 1] + unw_coeffs[i][1] * lsp_w_diff[i] + unw_coeffs[i][2] * lsp_w_diff[i + 1];
     321             :     }
     322             : 
     323       68415 :     lsp_uw[M - 1] = lsp_w_orig[M - 1] + unw_coeffs[M - 1][0] * lsp_w_diff[M - 2] + unw_coeffs[M - 1][1] * lsp_w_diff[M - 1];
     324             : 
     325             :     /* Reorder */
     326       68415 :     lsp_reorder( lsp_uw, 50.0f / SCALE1_LPC, M );
     327             : 
     328             :     /* Convert to lsf, apply cos() */
     329     1163055 :     for ( i = 0; i < M; ++i )
     330             :     {
     331     1094640 :         lsf_uw[i] = lsp_uw[i] * SCALE1_LPC;
     332     1094640 :         lsp_uw[i] = (float) cos( lsp_uw[i] );
     333             :     }
     334             : 
     335       68415 :     return 0;
     336             : }

Generated by: LCOV version 1.14