LCOV - code coverage report
Current view: top level - lib_enc - SNR_calc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 63 73 86.3 %
Date: 2025-05-23 08:37:30 Functions: 4 4 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             : #include <math.h>
      40             : #include "prot.h"
      41             : #include "rom_enc.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : 
      45             : /*-------------------------------------------------------------------*
      46             :  * SNR_calc()
      47             :  *
      48             :  *
      49             :  *-------------------------------------------------------------------*/
      50             : 
      51        3100 : void SNR_calc(
      52             :     const float frame_sb_energy[], /* i  : energy of sub-band divided non-uniformly   */
      53             :     const float sb_bg_energy[],    /* i  : sub-band background energy                 */
      54             :     const float t_bg_energy,       /* i  : time background energy of several frames   */
      55             :     float *snr,                    /* o  : frequency domain SNR                       */
      56             :     float *tsnr,                   /* o  : time domain SNR                            */
      57             :     const float frame_energy,      /* i  : current frame energy                       */
      58             :     const int16_t bwidth           /* i  : audio band width                           */
      59             : )
      60             : {
      61             :     int16_t i;
      62             :     float snr_tmp, tmp;
      63             :     int16_t SNR_sb_num;
      64        3100 :     SNR_sb_num = ENERGY_BAND_NUM[bwidth - CLDFBVAD_NB_ID];
      65             : 
      66        3100 :     snr_tmp = 0;
      67       40300 :     for ( i = 0; i < SNR_sb_num; i++ )
      68             :     {
      69       37200 :         tmp = ( frame_sb_energy[i] + 0.0001f ) / ( sb_bg_energy[i] + 0.0001f );
      70       37200 :         tmp = (float) log10( tmp );
      71       37200 :         if ( tmp > -0.1 )
      72             :         {
      73       29880 :             if ( bwidth == CLDFBVAD_SWB_ID )
      74             :             {
      75       29880 :                 tmp = tmp * 3.2f;
      76             :             }
      77           0 :             else if ( bwidth == CLDFBVAD_WB_ID )
      78             :             {
      79           0 :                 tmp = tmp * 3.31f;
      80             :             }
      81             :             else
      82             :             {
      83           0 :                 tmp = tmp * 3.0f;
      84             :             }
      85       29880 :             snr_tmp += tmp;
      86             :         }
      87             :     }
      88        3100 :     if ( snr_tmp < 0 )
      89             :     {
      90          18 :         snr_tmp = 0;
      91             :     }
      92        3100 :     *snr = snr_tmp / SNR_sb_num;
      93        3100 :     tmp = ( frame_energy + 0.0001f ) / ( t_bg_energy + 0.0001f );
      94        3100 :     tmp = (float) log10( tmp );
      95        3100 :     *tsnr = tmp * 3.0f;
      96        3100 :     if ( bwidth == CLDFBVAD_SWB_ID )
      97             :     {
      98        3100 :         tmp = ( frame_energy ) / ( t_bg_energy + FLT_MIN );
      99        3100 :         tmp = (float) log10( tmp + FLT_MIN );
     100        3100 :         *tsnr = tmp * 2.8f;
     101             :     }
     102             : 
     103        3100 :     return;
     104             : }
     105             : 
     106             : 
     107             : /*-------------------------------------------------------------------*
     108             :  * calc_snr_flux()
     109             :  *
     110             :  *
     111             :  *-------------------------------------------------------------------*/
     112             : 
     113        3100 : void calc_snr_flux(
     114             :     float tsnr,      /* i  : time-domain SNR            */
     115             :     float pre_snr[], /* i/o: time-domain SNR storage    */
     116             :     float *snr_flux  /* o  : average tsnr               */
     117             : )
     118             : {
     119             :     int16_t i;
     120        3100 :     float snr_sum = 0.0f;
     121             : 
     122        3100 :     if ( tsnr < 2.6f && tsnr > 0 )
     123             :     {
     124         107 :         pre_snr[0] = tsnr;
     125             :     }
     126        2993 :     else if ( tsnr <= 0 )
     127             :     {
     128         110 :         pre_snr[0] = 0;
     129             :     }
     130             :     else
     131             :     {
     132        2883 :         pre_snr[0] = 2.6f;
     133             :     }
     134             : 
     135        3100 :     snr_sum = 0;
     136      102300 :     for ( i = 0; i < PRE_SNR_NUM; i++ )
     137             :     {
     138       99200 :         snr_sum += pre_snr[i];
     139             :     }
     140        3100 :     *snr_flux = snr_sum / PRE_SNR_NUM;
     141       99200 :     for ( i = PRE_SNR_NUM - 1; i > 0; i-- )
     142             :     {
     143       96100 :         pre_snr[i] = pre_snr[i - 1];
     144             :     }
     145             : 
     146        3100 :     return;
     147             : }
     148             : 
     149             : 
     150             : /*-------------------------------------------------------------------*
     151             :  * calc_lt_snr()
     152             :  *
     153             :  *
     154             :  *-------------------------------------------------------------------*/
     155             : 
     156        3100 : void calc_lt_snr(
     157             :     float *lt_snr_org,              /* o  : original long time SNR                              */
     158             :     float *lt_snr,                  /* o  : long time SNR calculated by fg_energy and bg_energy */
     159             :     const float fg_energy,          /* i  : foreground energy sum                               */
     160             :     const int16_t fg_energy_count,  /* i  : number of the foreground energy frame               */
     161             :     const float bg_energy,          /* i  : background energy sum                               */
     162             :     const int16_t bg_energy_count,  /* i  : number of the background energy frame               */
     163             :     const int16_t bw_index,         /* i  : band width index                                    */
     164             :     const float lt_noise_sp_center0 /* i  : long time noise spectral center by 0                */
     165             : )
     166             : {
     167             :     float tmp_lt_noise_sp_center;
     168             :     float rtn_lt_snr;
     169             : 
     170        3100 :     const float offset = -0.00156247615814208984375f;
     171             : 
     172        3100 :     tmp_lt_noise_sp_center = lt_noise_sp_center0 - 1.4f;
     173        3100 :     if ( tmp_lt_noise_sp_center > 0.8 )
     174             :     {
     175           0 :         tmp_lt_noise_sp_center = 0.8f;
     176             :     }
     177        3100 :     if ( tmp_lt_noise_sp_center < 0 )
     178             :     {
     179          54 :         tmp_lt_noise_sp_center = 0.0f;
     180             :     }
     181        3100 :     rtn_lt_snr = (float) log10( ( fg_energy * bg_energy_count + FLT_MIN ) / ( bg_energy * fg_energy_count + FLT_MIN ) );
     182        3100 :     *lt_snr_org = rtn_lt_snr;
     183             : 
     184        3100 :     if ( bg_energy_count < 56 || fg_energy_count < 56 )
     185             :     {
     186        3100 :         rtn_lt_snr = 2.1f;
     187             :     }
     188             : 
     189        3100 :     if ( bw_index == CLDFBVAD_NB_ID )
     190             :     {
     191           0 :         rtn_lt_snr = ( rtn_lt_snr - 1.5f ) * 0.5f;
     192             :     }
     193        3100 :     else if ( bw_index == CLDFBVAD_WB_ID )
     194             :     {
     195           0 :         rtn_lt_snr = ( rtn_lt_snr - 1.5f ) * 0.50f;
     196             :     }
     197             :     else
     198             :     {
     199        3100 :         rtn_lt_snr = ( rtn_lt_snr - 1.5f ) * 0.46f;
     200             :     }
     201        3100 :     rtn_lt_snr = rtn_lt_snr + ( rtn_lt_snr * 0.4f + offset ) * tmp_lt_noise_sp_center * 0.4f;
     202        3100 :     if ( rtn_lt_snr < 0 )
     203             :     {
     204           0 :         rtn_lt_snr = 0.0f;
     205             :     }
     206             : 
     207        3100 :     if ( rtn_lt_snr > 2.0 )
     208             :     {
     209           0 :         rtn_lt_snr = 2.0f;
     210             :     }
     211             : 
     212        3100 :     *lt_snr = rtn_lt_snr;
     213             : 
     214        3100 :     return;
     215             : }
     216             : 
     217             : 
     218             : /*-------------------------------------------------------------------*
     219             :  * calc_lf_snr()
     220             :  *
     221             :  *
     222             :  *-------------------------------------------------------------------*/
     223             : 
     224        3100 : void calc_lf_snr(
     225             :     float *lf_snr_smooth,              /* o  : smoothed lf_snr                          */
     226             :     float *lf_snr,                     /* o  : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/
     227             :     const float l_speech_snr,          /* i  : sum of active frames snr                 */
     228             :     const int16_t l_speech_snr_count,  /* i  : number of the active frame               */
     229             :     const float l_silence_snr,         /* i  : sum of the nonactive frames snr          */
     230             :     const int16_t l_silence_snr_count, /* i  : number of the nonactive frame            */
     231             :     const int16_t fg_energy_count,     /* i  : number of the foreground energy frame    */
     232             :     const int16_t bg_energy_count,     /* i  : number of the background energy frame    */
     233             :     const int16_t bw_index             /* i  : band width index                         */
     234             : )
     235             : {
     236             :     float l_snr;
     237             : 
     238        3100 :     l_snr = l_speech_snr / l_speech_snr_count - l_silence_snr / l_silence_snr_count;
     239        3100 :     *lf_snr_smooth = *lf_snr_smooth * 0.9f + 0.1f * l_snr;
     240             : 
     241        3100 :     if ( bg_energy_count < 56 || fg_energy_count < 56 )
     242             :     {
     243        3100 :         l_snr = 4.8f;
     244             :     }
     245             : 
     246        3100 :     l_snr = ( l_snr - 3.0f ) * 0.12f;
     247             : 
     248        3100 :     if ( l_snr < 0 )
     249             :     {
     250           0 :         l_snr = 0;
     251             :     }
     252             : 
     253        3100 :     if ( l_snr > MAX_LF_SNR_TAB[bw_index] )
     254             :     {
     255           0 :         l_snr = MAX_LF_SNR_TAB[bw_index];
     256             :     }
     257             : 
     258        3100 :     *lf_snr = l_snr;
     259             : 
     260        3100 :     return;
     261             : }

Generated by: LCOV version 1.14