LCOV - code coverage report
Current view: top level - lib_com - calc_st_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 78 84 92.9 %
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 <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             : /*----------------------------------------------------------------------------
      49             :  * calc_rc0_h()
      50             :  *
      51             :  * computes 1st parcor from composed filter impulse response
      52             :  *---------------------------------------------------------------------------*/
      53             : 
      54     3959070 : static void calc_rc0_h(
      55             :     const float *h, /* i  : impulse response of composed filter */
      56             :     float *rc0      /* o  : 1st parcor                          */
      57             : )
      58             : {
      59             :     float acf0, acf1;
      60             :     float temp, temp2;
      61             :     const float *ptrs;
      62             :     int16_t i;
      63             : 
      64             :     /* computation of the autocorrelation function acf */
      65     3959070 :     temp = 0.0f;
      66    83140470 :     for ( i = 0; i < LONG_H_ST; i++ )
      67             :     {
      68    79181400 :         temp += h[i] * h[i];
      69             :     }
      70     3959070 :     acf0 = temp;
      71             : 
      72     3959070 :     temp = 0.0f;
      73     3959070 :     ptrs = h;
      74    79181400 :     for ( i = 0; i < LONG_H_ST - 1; i++ )
      75             :     {
      76    75222330 :         temp2 = *ptrs++;
      77    75222330 :         temp += temp2 * ( *ptrs );
      78             :     }
      79     3959070 :     acf1 = temp;
      80             : 
      81             :     /* Initialisation of the calculation */
      82     3959070 :     if ( acf0 == 0.0f )
      83             :     {
      84           0 :         *rc0 = 0.0f;
      85           0 :         return;
      86             :     }
      87             : 
      88             :     /* Compute 1st parcor */
      89     3959070 :     if ( acf0 < (float) fabs( acf1 ) )
      90             :     {
      91           0 :         *rc0 = 0.0f;
      92           0 :         return;
      93             :     }
      94     3959070 :     *rc0 = -acf1 / acf0;
      95             : 
      96     3959070 :     return;
      97             : }
      98             : 
      99             : 
     100             : /*----------------------------------------------------------------------------
     101             :  * calc_st_filt()
     102             :  *
     103             :  * computes impulse response of A(gamma2) / A(gamma1)
     104             :  * controls gain : computation of energy impulse response as
     105             :  *                 SUMn  (abs (h[n])) and computes parcor0
     106             :  *---------------------------------------------------------------------------- */
     107             : 
     108     3959070 : void calc_st_filt(
     109             :     const float *apond2,   /* i  : coefficients of numerator               */
     110             :     const float *apond1,   /* i  : coefficients of denominator             */
     111             :     float *parcor0,        /* o  : 1st parcor calcul. on composed filter   */
     112             :     float *sig_ltp_ptr,    /* i/o: input of 1/A(gamma1) : scaled by 1/g0   */
     113             :     float *mem_zero,       /* i/o: All zero memory                         */
     114             :     const int16_t L_subfr, /* i  : the length of subframe                  */
     115             :     const int16_t extl     /* i  : extension layer info                    */
     116             : 
     117             : )
     118             : {
     119             :     float h[LONG_H_ST];
     120             :     float g0, temp;
     121             :     int16_t i;
     122             : 
     123             :     /* compute i.r. of composed filter apond2 / apond1 */
     124     3959070 :     if ( extl == SWB_TBE )
     125             :     {
     126     1783092 :         syn_filt( apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 );
     127             :     }
     128             :     else
     129             :     {
     130     2175978 :         syn_filt( apond1, M, apond2, h, LONG_H_ST, mem_zero, 0 );
     131             :     }
     132             : 
     133             :     /* compute 1st parcor */
     134     3959070 :     calc_rc0_h( h, parcor0 );
     135             : 
     136             :     /* compute g0 */
     137     3959070 :     g0 = 0.0f;
     138    83140470 :     for ( i = 0; i < LONG_H_ST; i++ )
     139             :     {
     140    79181400 :         g0 += (float) fabs( h[i] );
     141             :     }
     142             : 
     143             :     /* Scale signal input of 1/A(gamma1) */
     144     3959070 :     if ( g0 > 1.0f )
     145             :     {
     146     2851863 :         temp = 1.0f / g0;
     147             : 
     148   213900567 :         for ( i = 0; i < L_subfr; i++ )
     149             :         {
     150   211048704 :             sig_ltp_ptr[i] = sig_ltp_ptr[i] * temp;
     151             :         }
     152             :     }
     153             : 
     154     3959070 :     return;
     155             : }
     156             : 
     157             : 
     158             : /*----------------------------------------------------------------------------
     159             :  * filt_mu()
     160             :  *
     161             :  * tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
     162             :  *      computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
     163             :  *---------------------------------------------------------------------------*/
     164             : 
     165     3959070 : void filt_mu(
     166             :     const float *sig_in,   /* i  : signal (beginning at sample -1) */
     167             :     float *sig_out,        /* o  : output signal                   */
     168             :     const float parcor0,   /* i  : parcor0 (mu = parcor0 * gamma3) */
     169             :     const int16_t L_subfr, /* i  : the length of subframe          */
     170             :     const int16_t extl     /* i  : extension layer info            */
     171             : )
     172             : {
     173             :     int16_t n;
     174             :     float mu, ga, temp;
     175             :     const float *ptrs;
     176             : 
     177     3959070 :     if ( extl == SWB_TBE )
     178             :     {
     179     1783092 :         if ( parcor0 > 0.0f )
     180             :         {
     181     1501912 :             mu = parcor0 * GAMMA3_PLUS_WB;
     182             :         }
     183             :         else
     184             :         {
     185      281180 :             mu = parcor0 * GAMMA3_MINUS_WB;
     186             :         }
     187             :     }
     188             :     else
     189             :     {
     190     2175978 :         if ( parcor0 > 0.0f )
     191             :         {
     192      166872 :             mu = parcor0 * GAMMA3_PLUS;
     193             :         }
     194             :         else
     195             :         {
     196     2009106 :             mu = parcor0 * GAMMA3_MINUS;
     197             :         }
     198             :     }
     199             : 
     200     3959070 :     ga = (float) 1. / ( (float) 1. - (float) fabs( mu ) );
     201             : 
     202     3959070 :     ptrs = sig_in; /* points on sig_in(-1) */
     203             : 
     204   285869022 :     for ( n = 0; n < L_subfr; n++ )
     205             :     {
     206   281909952 :         temp = mu * ( *ptrs++ );
     207   281909952 :         temp += ( *ptrs );
     208   281909952 :         sig_out[n] = ga * temp;
     209             :     }
     210             : 
     211     3959070 :     return;
     212             : }
     213             : 
     214             : 
     215             : /*----------------------------------------------------------------------------
     216             :  * scale_st()
     217             :  *
     218             :  * control of the subframe gain
     219             :  * gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out
     220             :  *---------------------------------------------------------------------------*/
     221             : 
     222     3963510 : void scale_st(
     223             :     const float *sig_in,   /* i  : postfilter input signal         */
     224             :     float *sig_out,        /* i/o: postfilter output signal        */
     225             :     float *gain_prec,      /* i/o: last value of gain for subframe */
     226             :     const int16_t L_subfr, /* i  : the length of subframe          */
     227             :     const int16_t extl     /* i  : extension layer info            */
     228             : )
     229             : {
     230             :     int16_t i;
     231             :     float gain_in, gain_out;
     232             :     float g0, gain;
     233     3963510 :     float agc_fac1_para = 0.0f;
     234     3963510 :     float agc_fac_para = 0.0f;
     235             : 
     236     3963510 :     if ( extl == SWB_TBE )
     237             :     {
     238     1783092 :         agc_fac1_para = AGC_FAC1_WB;
     239     1783092 :         agc_fac_para = AGC_FAC_WB;
     240             :     }
     241             :     else
     242             :     {
     243     2180418 :         agc_fac1_para = AGC_FAC1;
     244     2180418 :         agc_fac_para = AGC_FAC;
     245             :     }
     246             : 
     247             :     /* compute input gain */
     248     3963510 :     gain_in = 0.0f;
     249   286203702 :     for ( i = 0; i < L_subfr; i++ )
     250             :     {
     251   282240192 :         gain_in += (float) fabs( sig_in[i] );
     252             :     }
     253             : 
     254     3963510 :     if ( gain_in == 0.0f )
     255             :     {
     256       79899 :         g0 = 0.0f;
     257             :     }
     258             :     else
     259             :     {
     260             :         /* Compute output gain */
     261     3883611 :         gain_out = 0.0f;
     262   281010267 :         for ( i = 0; i < L_subfr; i++ )
     263             :         {
     264   277126656 :             gain_out += (float) fabs( sig_out[i] );
     265             :         }
     266             : 
     267     3883611 :         if ( gain_out == 0.0f )
     268             :         {
     269           0 :             *gain_prec = 0.0f;
     270           0 :             return;
     271             :         }
     272             : 
     273     3883611 :         g0 = gain_in / gain_out;
     274     3883611 :         g0 *= agc_fac1_para;
     275             :     }
     276             : 
     277             :     /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
     278             :     /* sig_out(n) = gain(n) sig_out(n) */
     279     3963510 :     gain = *gain_prec;
     280   286203702 :     for ( i = 0; i < L_subfr; i++ )
     281             :     {
     282   282240192 :         gain *= agc_fac_para;
     283   282240192 :         gain += g0;
     284   282240192 :         sig_out[i] *= gain;
     285             :     }
     286             : 
     287     3963510 :     *gain_prec = gain;
     288             : 
     289     3963510 :     return;
     290             : }
     291             : 
     292        4440 : void blend_subfr2(
     293             :     float *sigIn1,
     294             :     float *sigIn2,
     295             :     float *sigOut )
     296             : {
     297        4440 :     float fac1 = 1.f - ( 1.f / L_SUBFR );
     298        4440 :     float fac2 = 0.f + ( 1.f / L_SUBFR );
     299        4440 :     float step = 1.f / ( L_SUBFR / 2 );
     300             :     int16_t i;
     301             : 
     302      146520 :     for ( i = 0; i < L_SUBFR / 2; i++ )
     303             :     {
     304      142080 :         sigOut[i] = fac1 * sigIn1[i] + fac2 * sigIn2[i];
     305      142080 :         fac1 -= step;
     306      142080 :         fac2 += step;
     307             :     }
     308             : 
     309        4440 :     return;
     310             : }

Generated by: LCOV version 1.14