LCOV - code coverage report
Current view: top level - lib_com - ivas_sns_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 107 110 97.3 %
Date: 2025-05-23 08:37:30 Functions: 3 3 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             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "cnst.h"
      36             : #include "prot.h"
      37             : #include "ivas_prot.h"
      38             : #include "rom_com.h"
      39             : #include "ivas_rom_com.h"
      40             : #include <math.h>
      41             : #include <assert.h>
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------
      49             :  * sns_compute_scf()
      50             :  *
      51             :  *
      52             :  *-------------------------------------------------------------------*/
      53             : 
      54      663143 : void sns_compute_scf(
      55             :     float spectrum[],
      56             :     const PsychoacousticParameters *pPsychParams,
      57             :     const int16_t L_frame,
      58             :     float *scf )
      59             : {
      60             :     int16_t i, n, k;
      61             :     float x[FDNS_NPTS], xs[FDNS_NPTS], sum, mean, xl4[SNS_NPTS], nf, xl[FDNS_NPTS];
      62             :     float tilt;
      63      663143 :     const uint8_t nBands = pPsychParams->nBands;
      64      663143 :     const uint8_t *bandLengths = pPsychParams->bandLengths;
      65      663143 :     int8_t bw = 0;
      66             : 
      67             : 
      68      663143 :     const float w_0 = 1.0f / 12.0f;
      69      663143 :     const float w_1 = 2.0f / 12.0f;
      70      663143 :     const float w_2 = 0.25f; /* 3.0f / 12.0f */
      71      663143 :     const float w_3 = w_2;
      72      663143 :     const float w_4 = w_1;
      73      663143 :     const float w_5 = w_0;
      74             : 
      75      663143 :     const float scale_log = INV_LOG_2 * 0.5f;
      76             : 
      77      663143 :     assert( nBands == FDNS_NPTS );
      78             : 
      79      663143 :     set_f( x, 0.0f, FDNS_NPTS );
      80             : 
      81      663143 :     if ( bandLengths == NULL )
      82             :     {
      83        1391 :         bw = (int8_t) ( L_frame / nBands );
      84             :         /* Energy per band */
      85        1391 :         k = 0;
      86       90415 :         for ( i = 0; i < nBands; ++i )
      87             :         {
      88       89024 :             x[i] = 0.0f;
      89      838464 :             for ( n = 0; n < bw; ++n, ++k )
      90             :             {
      91      749440 :                 x[i] += spectrum[k];
      92             :             }
      93       89024 :             x[i] /= bw;
      94             :         }
      95             :     }
      96             :     else
      97             :     {
      98             :         /* Energy per band */
      99      661752 :         k = 0;
     100    43013880 :         for ( i = 0; i < nBands; ++i )
     101             :         {
     102    42352128 :             x[i] = 0.0f;
     103   403262688 :             for ( n = 0; n < bandLengths[i]; ++n, ++k )
     104             :             {
     105   360910560 :                 x[i] += spectrum[k];
     106             :             }
     107    42352128 :             x[i] /= bandLengths[i];
     108             :         }
     109             :     }
     110             : 
     111             :     /* Smoothing */
     112      663143 :     xs[0] = 0.75f * x[0] + 0.25f * x[1];
     113             : 
     114    41778009 :     for ( i = 1; i < FDNS_NPTS - 1; i++ )
     115             :     {
     116    41114866 :         xs[i] = 0.5f * x[i] + 0.25f * x[i - 1] + 0.25f * x[i + 1];
     117             :     }
     118             : 
     119      663143 :     xs[FDNS_NPTS - 1] = 0.75f * x[FDNS_NPTS - 1] + 0.25f * x[FDNS_NPTS - 2];
     120             : 
     121             :     /* Pre-emphasis */
     122      663143 :     switch ( L_frame )
     123             :     {
     124       64487 :         case L_FRAME16k:
     125       64487 :             tilt = 19.f;
     126       64487 :             break;
     127      265271 :         case L_FRAME25_6k:
     128      265271 :             tilt = 22.f;
     129      265271 :             break;
     130      333385 :         case L_FRAME32k:
     131      333385 :             tilt = 23.5f;
     132      333385 :             break;
     133           0 :         default:
     134           0 :             tilt = 0.f;
     135           0 :             assert( !"illegal frame length in sns_compute_scf" );
     136             :     }
     137             : 
     138    43104295 :     for ( i = 0; i < FDNS_NPTS; i++ )
     139             :     {
     140    42441152 :         xs[i] = xs[i] * powf( 10.0f, (float) i * (float) tilt / ( (float) FDNS_NPTS - 1.0f ) / 10.0f );
     141             :     }
     142             : 
     143             :     /* Noise floor at -40dB */
     144      663143 :     sum = sum_f( xs, FDNS_NPTS );
     145      663143 :     mean = sum / FDNS_NPTS;
     146             : 
     147      663143 :     nf = mean * powf( 10.0f, -4.0f );
     148      663143 :     nf = max( nf, powf( 2.0f, -32.0f ) );
     149             : 
     150             : 
     151    43104295 :     for ( i = 0; i < FDNS_NPTS; i++ )
     152             :     {
     153    42441152 :         if ( xs[i] < nf )
     154             :         {
     155      774077 :             xs[i] = nf;
     156             :         }
     157             :     }
     158             : 
     159             :     /* Log-domain */
     160    43104295 :     for ( i = 0; i < FDNS_NPTS; i++ )
     161             :     {
     162    42441152 :         xl[i] = logf( xs[i] ) * scale_log;
     163             :     }
     164             : 
     165             :     /* Downsampling */
     166      663143 :     xl4[0] = w_0 * xl[0] +
     167      663143 :              w_1 * xl[0] +
     168      663143 :              w_2 * xl[1] +
     169      663143 :              w_3 * xl[2] +
     170      663143 :              w_4 * xl[3] +
     171      663143 :              w_5 * xl[4];
     172             : 
     173             : 
     174     9947145 :     for ( n = 1; n < SNS_NPTS - 1; n++ )
     175             :     {
     176     9284002 :         int16_t n4 = 4 * n;
     177     9284002 :         xl4[n] = w_0 * xl[n4 - 1] +
     178     9284002 :                  w_1 * xl[n4] +
     179     9284002 :                  w_2 * xl[n4 + 1] +
     180     9284002 :                  w_3 * xl[n4 + 2] +
     181     9284002 :                  w_4 * xl[n4 + 3] +
     182     9284002 :                  w_5 * xl[n4 + 4];
     183             :     }
     184             : 
     185      663143 :     xl4[SNS_NPTS - 1] = w_0 * xl[FDNS_NPTS - 5] +
     186      663143 :                         w_1 * xl[FDNS_NPTS - 4] +
     187      663143 :                         w_2 * xl[FDNS_NPTS - 3] +
     188      663143 :                         w_3 * xl[FDNS_NPTS - 2] +
     189      663143 :                         w_4 * xl[FDNS_NPTS - 1] +
     190      663143 :                         w_5 * xl[FDNS_NPTS - 1];
     191             : 
     192             :     /* Remove mean and scaling */
     193      663143 :     sum = sum_f( xl4, SNS_NPTS );
     194      663143 :     mean = sum / SNS_NPTS;
     195             : 
     196    11273431 :     for ( i = 0; i < SNS_NPTS; i++ )
     197             :     {
     198    10610288 :         scf[i] = 0.85f * ( xl4[i] - mean );
     199             :     }
     200             : 
     201      663143 :     return;
     202             : }
     203             : 
     204             : /*-------------------------------------------------------------------
     205             :  * sns_interpolate_scalefactors()
     206             :  *
     207             :  *
     208             :  *-------------------------------------------------------------------*/
     209             : 
     210     3638492 : void sns_interpolate_scalefactors(
     211             :     float *scf_int,      /* o  : interpolated scalefactors for spectrum shaping*/
     212             :     const float *scf,    /* i  : sns scalefactors as derived from the signal or read from the bitstream */
     213             :     int16_t encoder_side /* i  : flag, if scalefactors have to be inverted */
     214             : )
     215             : {
     216             :     int16_t n;
     217             : 
     218             :     /* Interpolation */
     219     3638492 :     scf_int[0] = scf[0];
     220     3638492 :     scf_int[1] = scf[0];
     221             : 
     222    58215872 :     for ( n = 0; n <= M - 2; n++ )
     223             :     {
     224    54577380 :         scf_int[n * 4 + 2] = scf[n] + ( scf[n + 1] - scf[n] ) / 8.f;
     225    54577380 :         scf_int[n * 4 + 3] = scf[n] + 3.f * ( scf[n + 1] - scf[n] ) / 8.f;
     226    54577380 :         scf_int[n * 4 + 4] = scf[n] + 5.f * ( scf[n + 1] - scf[n] ) / 8.f;
     227    54577380 :         scf_int[n * 4 + 5] = scf[n] + 7.f * ( scf[n + 1] - scf[n] ) / 8.f;
     228             :     }
     229             : 
     230     3638492 :     scf_int[FDNS_NPTS - 2] = scf[M - 1] + ( scf[M - 1] - scf[M - 2] ) / 8.f;
     231     3638492 :     scf_int[FDNS_NPTS - 1] = scf[M - 1] + 3.f * ( scf[M - 1] - scf[M - 2] ) / 8.f;
     232             : 
     233             :     /* Inversion at encoder-side */
     234     3638492 :     if ( encoder_side == ENC )
     235             :     {
     236    80282020 :         for ( n = 0; n < FDNS_NPTS; n++ )
     237             :         {
     238    79046912 :             scf_int[n] = -scf_int[n];
     239             :         }
     240             :     }
     241             : 
     242             :     /* Linear domain */
     243   236501980 :     for ( n = 0; n < FDNS_NPTS; n++ )
     244             :     {
     245   232863488 :         scf_int[n] = powf( 2.f, scf_int[n] );
     246             :     }
     247             : 
     248     3638492 :     return;
     249             : }
     250             : 
     251             : 
     252             : /*-------------------------------------------------------------------
     253             :  * sns_shape_spectrum()
     254             :  *
     255             :  *
     256             :  *-------------------------------------------------------------------*/
     257             : 
     258     3176501 : void sns_shape_spectrum(
     259             :     float spectrum[],                             /* i/o: spectrum to be shaped                                     */
     260             :     const PsychoacousticParameters *pPsychParams, /* i  : psychoacoustic parameters used to get the frequency bands */
     261             :     const float *scf_int,                         /* i  : already interpolated SNS scalefactors                     */
     262             :     const int16_t L_frame                         /* i  : frame length                                              */
     263             : )
     264             : {
     265             :     int16_t i, n, k, bw;
     266     3176501 :     const uint8_t nBands = pPsychParams->nBands;
     267     3176501 :     const uint8_t *bandLengths = pPsychParams->bandLengths;
     268             : 
     269     3176501 :     if ( bandLengths == NULL )
     270             :     {
     271        6458 :         bw = L_frame / nBands;
     272             : 
     273             :         /* Shape spectrum */
     274        6458 :         k = 0;
     275      419770 :         for ( i = 0; i < nBands; ++i )
     276             :         {
     277     4700672 :             for ( n = 0; n < bw; ++n, ++k )
     278             :             {
     279     4287360 :                 spectrum[k] *= scf_int[i];
     280             :             }
     281             :         }
     282             :     }
     283             :     else
     284             :     {
     285             :         /* Shape spectrum */
     286     3170043 :         k = 0;
     287   206052795 :         for ( i = 0; i < nBands; ++i )
     288             :         {
     289  1934502624 :             for ( n = 0; n < bandLengths[i]; ++n, ++k )
     290             :             {
     291  1731619872 :                 spectrum[k] *= scf_int[i];
     292             :             }
     293             :         }
     294             :     }
     295             : 
     296     3176501 :     return;
     297             : }

Generated by: LCOV version 1.14