LCOV - code coverage report
Current view: top level - lib_enc - bass_psfilter_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 93 96 96.9 %
Date: 2025-05-23 08:37:30 Functions: 1 1 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 "prot.h"
      44             : #include "rom_com.h"
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /*---------------------------------------------------------------------*
      49             :  * bass_pf_enc()
      50             :  *
      51             :  * Low-frequency postfiltering, decoder parammeter estimation
      52             :  *---------------------------------------------------------------------*/
      53             : 
      54         596 : float bass_pf_enc(
      55             :     const float *orig,          /* i  : 12.8kHz original signal                     */
      56             :     const float *syn,           /* i  : 12.8kHz synthesis to postfilter             */
      57             :     const float pitch_buf[],    /* i  : Pitch gain for all subframes (gainT_sf[16]) */
      58             :     const float gainT_sf[],     /* i  : Pitch gain for all subframes (gainT_sf[16]) */
      59             :     const int16_t l_frame,      /* i  : frame length (should be multiple of l_subfr)*/
      60             :     const int16_t l_subfr_in,   /* i  : sub-frame length (80/64)                    */
      61             :     float mem_bpf[],            /* i/o: memory state [2*L_FILT16k]                  */
      62             :     float mem_error_bpf[],      /* i/o: memory state [2*L_FILT16k]                  */
      63             :     int16_t *gain_factor_param, /* o  : quantized gain factor                       */
      64             :     const int16_t mode,         /* i  : coding mode of adapt bpf                    */
      65             :     float *mem_deemph_err,      /* o  : Error deemphasis memory                     */
      66             :     float *lp_ener              /* o  : long_term error signal energy               */
      67             : )
      68             : {
      69             :     int16_t i, j, sf, i_subfr, T, lg, l_subfr, l_filt;
      70             :     float d, n, snr, nrg1, nrg2, gain, nrg, tmp;
      71             :     float noise_buf[L_FILT16k + ( 2 * L_SUBFR )], *noise, *noise_in;
      72             :     float error_buf[L_FILT16k + ( 2 * L_SUBFR )], *error, *error_in;
      73             :     float cross_n_d, nrg_n;
      74             :     const float *pFilt;
      75             :     float ener2;
      76             : 
      77         596 :     if ( l_frame != L_FRAME16k )
      78             :     {
      79           0 :         pFilt = filt_lp;
      80           0 :         l_filt = L_FILT;
      81             :     }
      82             :     else
      83             :     {
      84         596 :         pFilt = filt_lp_16kHz;
      85         596 :         l_filt = L_FILT16k;
      86             :     }
      87             : 
      88         596 :     noise = noise_buf + l_filt;
      89         596 :     noise_in = noise_buf + 2 * l_filt;
      90         596 :     error = error_buf + l_filt;
      91         596 :     error_in = error_buf + 2 * l_filt;
      92             : 
      93         596 :     sf = 0;
      94         596 :     snr = 0.f;
      95         596 :     nrg_n = 1e-6f;
      96         596 :     cross_n_d = 0.f;
      97         596 :     l_subfr = l_subfr_in;
      98        3576 :     for ( i_subfr = 0; i_subfr < l_frame; i_subfr += l_subfr, sf++ )
      99             :     {
     100        2980 :         T = (int16_t) pitch_buf[sf];
     101        2980 :         gain = gainT_sf[sf];
     102             : 
     103        2980 :         if ( gain > 1.0f )
     104             :         {
     105         399 :             gain = 1.0f;
     106             :         }
     107        2980 :         if ( gain < 0.0f )
     108             :         {
     109           0 :             gain = 0.0f;
     110             :         }
     111             : 
     112        2980 :         lg = l_frame - T - i_subfr;
     113        2980 :         if ( lg < 0 )
     114             :         {
     115         552 :             lg = 0;
     116             :         }
     117        2980 :         if ( lg > l_subfr )
     118             :         {
     119        1806 :             lg = l_subfr;
     120             :         }
     121             : 
     122        2980 :         if ( gain > 0 )
     123             :         {
     124        2977 :             tmp = 0.01f;
     125        2977 :             nrg = 0.01f;
     126      139473 :             for ( i = 0; i < lg; i++ )
     127             :             {
     128      136496 :                 tmp += syn[i + i_subfr] * ( 0.5f * syn[i + i_subfr - T] + 0.5f * syn[i + i_subfr + T] );
     129      136496 :                 nrg += ( 0.5f * syn[i + i_subfr - T] + 0.5f * syn[i + i_subfr + T] ) * ( 0.5f * syn[i + i_subfr - T] + 0.5f * syn[i + i_subfr + T] );
     130             :             }
     131       57009 :             for ( i = lg; i < l_subfr; i++ )
     132             :             {
     133       54032 :                 tmp += syn[i + i_subfr] * syn[i + i_subfr - T];
     134       54032 :                 nrg += syn[i + i_subfr - T] * syn[i + i_subfr - T];
     135             :             }
     136        2977 :             gain = tmp / nrg;
     137             : 
     138        2977 :             if ( gain > 1.0f )
     139             :             {
     140        1113 :                 gain = 1.0f;
     141             :             }
     142        1864 :             else if ( gain < 0.f )
     143             :             {
     144          76 :                 gain = 0.f;
     145             :             }
     146             : 
     147        2977 :             ener2 = 0.01f;
     148      139473 :             for ( i = 0; i < lg; i++ )
     149             :             {
     150      136496 :                 error[i] = gain * ( syn[i + i_subfr] - 0.5f * syn[i + i_subfr - T] - 0.5f * syn[i + i_subfr + T] );
     151      136496 :                 error[i] = error[i] + 0.9f * *mem_deemph_err;
     152      136496 :                 *mem_deemph_err = error[i];
     153      136496 :                 ener2 += error[i] * error[i];
     154             :             }
     155       57009 :             for ( i = lg; i < l_subfr; i++ )
     156             :             {
     157       54032 :                 error[i] = 0.5f * gain * ( syn[i + i_subfr] - syn[i + i_subfr - T] );
     158       54032 :                 error[i] = error[i] + 0.9f * *mem_deemph_err;
     159       54032 :                 *mem_deemph_err = error[i];
     160       54032 :                 ener2 += error[i] * error[i];
     161             :             }
     162             : 
     163        2977 :             ener2 = (float) ( 10.f * log10( ener2 ) );
     164        2977 :             *lp_ener = (float) ( 0.99f * *lp_ener + 0.01f * ener2 );
     165        2977 :             ener2 = (float) pow( 10.f, 0.1f * *lp_ener );
     166             : 
     167        2977 :             tmp = 0.5f * tmp / ( nrg + ener2 );
     168        2977 :             if ( tmp > 0.5f )
     169             :             {
     170         618 :                 tmp = 0.5f;
     171             :             }
     172        2359 :             else if ( tmp < 0.f )
     173             :             {
     174          76 :                 tmp = 0.0f;
     175             :             }
     176             : 
     177      139473 :             for ( i = 0; i < lg; i++ )
     178             :             {
     179      136496 :                 noise_in[i] = tmp * ( syn[i + i_subfr] - 0.5f * syn[i + i_subfr - T] - 0.5f * syn[i + i_subfr + T] );
     180      136496 :                 error_in[i] = ( orig[i + i_subfr] - syn[i + i_subfr] );
     181             :             }
     182       57009 :             for ( i = lg; i < l_subfr; i++ )
     183             :             {
     184       54032 :                 noise_in[i] = tmp * ( syn[i + i_subfr] - syn[i + i_subfr - T] );
     185       54032 :                 noise_in[i] *= 0.5f;
     186       54032 :                 error_in[i] = ( orig[i + i_subfr] - syn[i + i_subfr] );
     187             :             }
     188             :         }
     189             :         else
     190             :         {
     191           3 :             set_zero( noise_in, l_subfr );
     192           3 :             set_zero( error_in, l_subfr );
     193             :         }
     194             : 
     195        2980 :         mvr2r( mem_bpf, noise_buf, 2 * l_filt );
     196        2980 :         mvr2r( noise_buf + l_subfr, mem_bpf, 2 * l_filt );
     197             : 
     198        2980 :         mvr2r( mem_error_bpf, error_buf, 2 * l_filt );
     199        2980 :         mvr2r( error_buf + l_subfr, mem_error_bpf, 2 * l_filt );
     200             : 
     201        2980 :         nrg1 = 1e-6f;
     202        2980 :         nrg2 = 1e-6f;
     203             : 
     204             :         /* substract from voiced speech low-pass filtered noise */
     205      193700 :         for ( i = 0; i < l_subfr; i++ )
     206             :         {
     207      190720 :             n = pFilt[0] * noise[i];
     208      190720 :             d = error[i];
     209             : 
     210     3051520 :             for ( j = 1; j <= l_filt; j++ )
     211             :             {
     212     2860800 :                 n += pFilt[j] * ( noise[i - j] + noise[i + j] );
     213             :             }
     214             :             /*for optimal g*/
     215      190720 :             nrg_n += n * n;
     216      190720 :             cross_n_d += n * d;
     217             : 
     218             :             /*for evaluating SNR*/
     219      190720 :             nrg1 += ( d + n ) * ( d + n );
     220      190720 :             nrg2 += d * d;
     221             :         }
     222             : 
     223             :         /*SegSNR*/
     224        2980 :         snr += (float) log10( nrg2 / nrg1 );
     225             :     }
     226             : 
     227             :     /*Compute and quantize optimal gain*/
     228             :     /* optimal gain = -<n,d>/<n,n> */
     229         596 :     if ( mode == 2 )
     230             :     {
     231             :         int32_t gain32;
     232             : 
     233         570 :         gain32 = (int32_t) ( -2.f * ( cross_n_d / nrg_n ) + 0.5f );
     234         570 :         if ( gain32 > 3 )
     235             :         {
     236          20 :             *gain_factor_param = 3;
     237             :         }
     238         550 :         else if ( gain32 < 0 )
     239             :         {
     240         145 :             *gain_factor_param = 0;
     241             :         }
     242             :         else
     243             :         {
     244         405 :             *gain_factor_param = (int16_t) gain32;
     245             :         }
     246             : 
     247             :         /*If optimal gain negatif or zero but snr still positif->gain=0.5f*/
     248         570 :         if ( snr > 0.f && *gain_factor_param == 0 )
     249             :         {
     250           2 :             *gain_factor_param = 1;
     251             :         }
     252             :     }
     253             :     else
     254             :     {
     255          26 :         *gain_factor_param = 2;
     256             :     }
     257             : 
     258             : 
     259         596 :     return ( snr );
     260             : }

Generated by: LCOV version 1.14