LCOV - code coverage report
Current view: top level - lib_enc - multi_harm.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 96 100 96.0 %
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 "cnst.h"
      44             : #include "prot.h"
      45             : #include "wmc_auto.h"
      46             : 
      47             : /*-----------------------------------------------------------------*
      48             :  * Local constants
      49             :  *-----------------------------------------------------------------*/
      50             : 
      51             : #define THR_CORR_MAX  60   /* upper threshold of multi-harm. correlation */
      52             : #define THR_CORR_MIN  49   /* lower threshold of multi-harm. correlation */
      53             : #define THR_CORR_STEP 0.2f /* step for the threshold of multi-harm. correlation */
      54             : 
      55             : /*---------------------------------------------------------------------*
      56             :  * multi_harm()
      57             :  *
      58             :  * Perform multi-harmonic analysis, information used for UV and VAD decision
      59             :  *---------------------------------------------------------------------*/
      60             : 
      61             : /*! r: frame multi-harmonicity (1-harmonic, 0-not) */
      62     1153834 : int16_t multi_harm(
      63             :     const float Bin_E[],       /* i  : log-energy spectrum of the current frame       */
      64             :     float old_S[],             /* i/o: prev. log-energy spectrum w. subtracted floor  */
      65             :     float cor_map_LT[],        /* i/o: LT correlation map                             */
      66             :     float *multi_harm_limit,   /* i/o: multi harminic threshold                       */
      67             :     const int32_t total_brate, /* i  : total bitrate                                  */
      68             :     const int16_t bwidth,      /* i  : input signal bandwidth                         */
      69             :     int16_t *cor_strong_limit, /* i/o: HF correlation indicator                       */
      70             :     float *st_mean_avr_dyn,    /* i/o: long term average dynamic                      */
      71             :     float *st_last_sw_dyn,     /* i/o: last dynamic                                   */
      72             :     float *cor_map_sum,        /* i  : sum of correlation map                         */
      73             :     float *sp_floor,           /* o  : noise floor estimate                           */
      74             :     float S_map[]              /* o  : short-term correlation map                     */
      75             : )
      76             : {
      77             :     int16_t i, j, k, L, stemp, N_mins, ind_mins[L_FFT / 4], *pt_mins, harm;
      78             :     float ftemp, ftemp2, flor, step, corx2, cory2, corxy, cor, cor_map_LT_sum, cor_strong, S[L_FFT / 2];
      79             :     float mean_dyn;
      80             : 
      81             :     /*------------------------------------------------------------------*
      82             :      * initialization
      83             :      *------------------------------------------------------------------*/
      84             : 
      85     1153834 :     if ( bwidth == NB )
      86             :     {
      87             :         /* length of the useful part of the spectrum (up to 4kHz) */
      88           0 :         L = 76;
      89             :     }
      90             :     else
      91             :     {
      92             :         /* length of the useful part of the spectrum (up to 6.4kHz) */
      93     1153834 :         L = L_FFT / 2;
      94             :     }
      95             : 
      96     1153834 :     mvr2r( Bin_E, S, L );
      97             : 
      98             :     /*------------------------------------------------------------------*
      99             :      * searching of spectral maxima and minima
     100             :      *------------------------------------------------------------------*/
     101             : 
     102     1153834 :     pt_mins = ind_mins;
     103             : 
     104             :     /* index of the first minimum */
     105     1153834 :     if ( Bin_E[0] < Bin_E[1] )
     106             : 
     107             :     {
     108      559551 :         *pt_mins++ = 0;
     109             :     }
     110             : 
     111   146536918 :     for ( i = 1; i < L - 1; i++ )
     112             :     {
     113             :         /* minimum found */
     114   145383084 :         if ( Bin_E[i] < Bin_E[i - 1] && Bin_E[i] < Bin_E[i + 1] )
     115             :         {
     116    37159498 :             *pt_mins++ = i;
     117             :         }
     118             :     }
     119             : 
     120             :     /* index of the last minimum */
     121     1153834 :     if ( Bin_E[L - 1] < Bin_E[L - 2] )
     122             :     {
     123           0 :         *pt_mins++ = L - 1;
     124             :     }
     125             : 
     126             :     /* total number of minimas found */
     127     1153834 :     N_mins = (int16_t) ( pt_mins - ind_mins - 1 );
     128             : 
     129             :     /*------------------------------------------------------------------*
     130             :      * calculation of the spectral floor
     131             :      * subtraction of the spectral floor
     132             :      *------------------------------------------------------------------*/
     133             : 
     134     1153834 :     set_f( S, 0, L );
     135     1153834 :     if ( N_mins > 0 )
     136             :     {
     137     1089030 :         *sp_floor = 0;
     138    37719027 :         for ( i = 0; i < N_mins; ++i )
     139             :         {
     140    36629997 :             *sp_floor += Bin_E[ind_mins[i]];
     141             :         }
     142     1089030 :         *sp_floor /= (float) N_mins;
     143     1089030 :         set_f( S, 0, ind_mins[0] );
     144     1089030 :         set_f( &S[ind_mins[N_mins]], 0, L - ind_mins[N_mins] );
     145             : 
     146     1089030 :         pt_mins = ind_mins;
     147     1089030 :         flor = 0;
     148     1089030 :         step = 0;
     149             : 
     150   134524038 :         for ( i = ind_mins[0]; i < ind_mins[N_mins]; i++ )
     151             :         {
     152             :             /* we are at the end of the next minimum */
     153   133435008 :             if ( i == *pt_mins )
     154             :             {
     155    36629997 :                 pt_mins++;
     156    36629997 :                 flor = Bin_E[i];
     157             : 
     158             :                 /* calculate the new step */
     159    36629997 :                 step = ( Bin_E[*pt_mins] - Bin_E[i] ) / ( *pt_mins - i );
     160             :             }
     161             : 
     162             :             /* subtract the floor */
     163   133435008 :             if ( Bin_E[i] > flor )
     164             :             {
     165    94121745 :                 S[i] = Bin_E[i] - flor;
     166             :             }
     167             :             else
     168             :             {
     169    39313263 :                 S[i] = 0;
     170             :             }
     171             : 
     172             :             /* update the floor */
     173   133435008 :             flor += step;
     174             :         }
     175             :     }
     176             :     else
     177             :     {
     178       64804 :         *sp_floor = Bin_E[0];
     179             :     }
     180     1153834 :     *sp_floor *= 1.0f / logf( 10.0f );
     181             : 
     182             :     /* calculate the maximum dynamic per band */
     183     1153834 :     mean_dyn = mean( &S[L - 40], 40 );
     184     1153834 :     mean_dyn = 0.6f * *st_mean_avr_dyn + 0.4f * mean_dyn;
     185             : 
     186     1153834 :     if ( mean_dyn < 9.6f && *cor_strong_limit != 0 )
     187             :     {
     188      247196 :         *cor_strong_limit = 0;
     189      247196 :         *st_last_sw_dyn = mean_dyn;
     190             :     }
     191      906638 :     else if ( ( mean_dyn - *st_last_sw_dyn ) > 4.5f )
     192             :     {
     193       78774 :         *cor_strong_limit = 1;
     194             :     }
     195             : 
     196     1153834 :     if ( total_brate < ACELP_9k60 || total_brate > ACELP_16k40 )
     197             :     {
     198     1033053 :         *cor_strong_limit = 1;
     199             :     }
     200             : 
     201     1153834 :     *st_mean_avr_dyn = mean_dyn;
     202             : 
     203             :     /*------------------------------------------------------------------*
     204             :      * calculation of the correlation map
     205             :      *------------------------------------------------------------------*/
     206             : 
     207     1153834 :     if ( N_mins > 0 )
     208             :     {
     209     1089030 :         corx2 = 0;
     210     1089030 :         corxy = 0;
     211     1089030 :         stemp = ind_mins[0];
     212     1089030 :         ftemp = old_S[stemp];
     213     1089030 :         cory2 = ftemp * ftemp;
     214     1089030 :         k = 1;
     215   134524038 :         for ( i = stemp + 1; i <= ind_mins[N_mins]; i++ )
     216             :         {
     217   133435008 :             if ( i == ind_mins[k] )
     218             :             {
     219             :                 /* include the last peak point (new minimum) to the corr. sum */
     220    36629997 :                 ftemp = old_S[i];
     221    36629997 :                 cory2 += ftemp * ftemp;
     222             : 
     223             :                 /* calculation of the norm. peak correlation */
     224    36629997 :                 if ( ( corx2 == 0 ) || ( cory2 == 0 ) )
     225             :                 {
     226      213626 :                     cor = 0;
     227             :                 }
     228             :                 else
     229             :                 {
     230    36416371 :                     cor = corxy * corxy / ( corx2 * cory2 );
     231             :                 }
     232             : 
     233             :                 /* save the norm. peak correlation in the correlation map */
     234   170065005 :                 for ( j = ind_mins[k - 1]; j < ind_mins[k]; j++ )
     235             :                 {
     236   133435008 :                     old_S[j] = S[j];
     237   133435008 :                     S[j] = cor;
     238             :                 }
     239             : 
     240    36629997 :                 corx2 = 0;
     241    36629997 :                 cory2 = 0;
     242    36629997 :                 corxy = 0;
     243             : 
     244    36629997 :                 k++;
     245             :             }
     246             : 
     247   133435008 :             ftemp = S[i];
     248   133435008 :             ftemp2 = old_S[i];
     249   133435008 :             corx2 += ftemp * ftemp;
     250   133435008 :             cory2 += ftemp2 * ftemp2;
     251   133435008 :             corxy += ftemp * ftemp2;
     252             :         }
     253             : 
     254     1089030 :         mvr2r( S, old_S, ind_mins[0] );
     255     1089030 :         mvr2r( &S[ind_mins[N_mins]], &old_S[ind_mins[N_mins]], L - ind_mins[N_mins] );
     256             :     }
     257             : 
     258             :     /*------------------------------------------------------------------*
     259             :      * updating of the long-term correlation map
     260             :      * summation of the long-term correlation map
     261             :      *------------------------------------------------------------------*/
     262             : 
     263     1153834 :     cor_strong = 0;
     264     1153834 :     *cor_map_sum = 0;
     265             : 
     266   148844586 :     for ( i = 0; i < L; i++ )
     267             :     {
     268   147690752 :         *cor_map_sum += S[i];
     269   147690752 :         cor_map_LT[i] = M_ALPHA * cor_map_LT[i] + ( 1 - M_ALPHA ) * S[i];
     270   147690752 :         if ( cor_map_LT[i] > 0.95f )
     271             :         {
     272      338333 :             cor_strong = 1;
     273             :         }
     274             :     }
     275             : 
     276             :     /* summation of the LT correlation map */
     277     1153834 :     cor_map_LT_sum = sum_f( cor_map_LT, L );
     278             : 
     279     1153834 :     if ( bwidth == NB )
     280             :     {
     281           0 :         cor_map_LT_sum *= 1.53f;
     282           0 :         *cor_map_sum *= 1.53f;
     283             :     }
     284             : 
     285             :     /* final decision about multi-harmonicity */
     286     1153834 :     if ( ( cor_map_LT_sum > *multi_harm_limit ) || ( cor_strong == 1 ) )
     287             :     {
     288      549799 :         harm = 1;
     289             :     }
     290             :     else
     291             :     {
     292      604035 :         harm = 0;
     293             :     }
     294             : 
     295             :     /*------------------------------------------------------------------*
     296             :      * updating of the decision threshold
     297             :      *------------------------------------------------------------------*/
     298             : 
     299     1153834 :     if ( cor_map_LT_sum > THR_CORR )
     300             :     {
     301      542349 :         *multi_harm_limit -= THR_CORR_STEP;
     302             :     }
     303             :     else
     304             :     {
     305      611485 :         *multi_harm_limit += THR_CORR_STEP;
     306             :     }
     307             : 
     308     1153834 :     if ( *multi_harm_limit > THR_CORR_MAX )
     309             :     {
     310      336186 :         *multi_harm_limit = THR_CORR_MAX;
     311             :     }
     312             : 
     313     1153834 :     if ( *multi_harm_limit < THR_CORR_MIN )
     314             :     {
     315      309221 :         *multi_harm_limit = THR_CORR_MIN;
     316             :     }
     317             : 
     318     1153834 :     if ( N_mins <= 0 )
     319             :     {
     320       64804 :         set_f( old_S, 0, L );
     321             :     }
     322             : 
     323     1153834 :     if ( S_map != 0 )
     324             :     {
     325     1150734 :         mvr2r( S, S_map, L );
     326             :     }
     327             : 
     328     1153834 :     return harm;
     329             : }

Generated by: LCOV version 1.14