LCOV - code coverage report
Current view: top level - lib_lc3plus - sns_compute_scf.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 867217ee32c8e8cd2cf5aae69e60c58e00160b49 Lines: 69 115 60.0 %
Date: 2025-12-13 06:47:12 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.6.1                               *
       3             : *              Low Complexity Communication Codec Plus (LC3plus)              *
       4             : *                                                                             *
       5             : * Copyright licence is solely granted through ETSI Intellectual Property      *
       6             : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
       7             : * estoppel or otherwise.                                                      *
       8             : ******************************************************************************/
       9             : 
      10             : #include "options.h"
      11             : #include "wmc_auto.h"
      12             : #include "functions.h"
      13             : 
      14             : #ifdef CR9_C_ADD_1p25MS
      15           0 : static float limitShaping (LC3_FLOAT* xl4 ) {
      16             :     LC3_FLOAT fac;
      17             :     LC3_FLOAT score;
      18             :     LC3_FLOAT min_fac;
      19             :     LC3_FLOAT max_fac;
      20             :     LC3_FLOAT start;
      21             :     LC3_FLOAT stop;
      22             :     
      23           0 :     min_fac = 1.f;
      24           0 :     max_fac = 0.3f;
      25           0 :     start   = 5.f;
      26           0 :     stop    = 8.f;
      27             : 
      28           0 :     score = ((2.f*(xl4[0]-xl4[1])) + (xl4[0]-xl4[2])) / 2.f;
      29           0 :     score = fmin(fmax(score, start), stop);
      30             : 
      31           0 :     fac = (stop-score)/(stop-start);
      32           0 :     return ((min_fac - max_fac) * fac + max_fac);
      33             : }
      34             : #endif
      35             : 
      36     1189311 : void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx
      37             : #ifdef CR9_C_ADD_1p25MS
      38             :                             , LC3PLUS_FrameDuration frame_dms, LC3_FLOAT *LT_normcorr, LC3_FLOAT normcorr
      39             : #endif
      40             :                             )
      41             : {
      42             :     LC3_INT   bands_number, d, i, j, n, n2, n4, mapping[64];
      43     1189311 :     LC3_FLOAT x_tmp1[MAX_LEN], sum = 0, mean, nf, gains_smooth[M], ratio;
      44     1189311 :     LC3_FLOAT sum_gains_smooth = 0;
      45             : #ifdef CR9_C_ADD_1p25MS
      46             :     LC3_FLOAT fac;
      47             :     LC3_FLOAT start;
      48             :     LC3_FLOAT limiterGain;
      49             : #endif
      50             :     const LC3_FLOAT *sns_preemph_adapt, *sns_preemph;
      51     1189311 :     bands_number = xLen;
      52             :     
      53     1189311 :     sns_preemph = sns_preemph_all[fs_idx];
      54             :     
      55             : #ifdef CR9_C_ADD_1p25MS
      56     1189311 :     limiterGain = 1.f;
      57     1189311 :     sns_preemph_adapt = sns_preemph_adaptMaxTilt_all[fs_idx];
      58             : #else
      59             :     (void) sns_preemph_adapt;
      60             : #endif
      61             : 
      62             :     /* 5 ms */
      63     1189311 :     if (bands_number < 64) {
      64     1139339 :         d = 64 - bands_number;
      65             : 
      66     1139339 :         if (d < xLen)
      67             :         {
      68     1139339 :             j = 0;
      69    11393566 :             for (i = 0; i < 2 * d; i = i + 2) {
      70    10254227 :                 x_tmp1[i]     = x[j];
      71    10254227 :                 x_tmp1[i + 1] = x[j];
      72    10254227 :                 j++;
      73             :             }
      74             : 
      75     1139339 :             move_float(&x_tmp1[2 * d], &x[d], 64 - 2 * d);
      76             :         }
      77           0 :         else if (bands_number < 32)
      78             :         {
      79           0 :             ratio = LC3_FABS((LC3_FLOAT) (1.0 - 32.0 / (LC3_FLOAT) xLen));
      80           0 :             n4 = round(ratio * xLen);
      81           0 :             n2 = xLen - n4;
      82             :             
      83           0 :             j = 0;
      84           0 :             for(i = 1; i <= n4; i++)
      85             :             {
      86           0 :                 mapping[j] = i;
      87           0 :                 mapping[j + 1] = i;
      88           0 :                 mapping[j + 2] = i;
      89           0 :                 mapping[j + 3] = i;
      90           0 :                 j += 4;
      91             :             }
      92             :             
      93           0 :             for (i = n4 + 1; i <= n4 + n2; i++)
      94             :             {
      95           0 :                 mapping[j] = i;
      96           0 :                 mapping[j + 1] = i;
      97           0 :                 j += 2;
      98             :             }
      99             :             
     100             :             
     101           0 :             for (i = 0; i < 64; i++)
     102             :             {
     103           0 :                 x_tmp1[i] = x[mapping[i] - 1];
     104             :             }
     105             :         } else {
     106           0 :             assert(0 && "Unsupported number of bands!");
     107             :         }
     108             : 
     109     1139339 :         move_float(x, x_tmp1, 64);
     110             : 
     111     1139339 :         bands_number = 64;
     112     1139339 :         xLen         = bands_number;
     113             :     }
     114             : 
     115             : 
     116             :     /* Smoothing */
     117             : 
     118     1189311 :     x_tmp1[0] = x[0];
     119     1189311 :     move_float(&x_tmp1[1], &x[0], 63);
     120             : 
     121    76115904 :     for (i = 0; i < 63; i++) {
     122    74926593 :         x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x[i + 1]);
     123             :     }
     124             :     
     125     1189311 :     x[63] = 0.5 * x[63] + 0.25 * (x_tmp1[63] + x[63]);
     126             : 
     127             :     /* Pre-emphasis */
     128             : #ifdef CR9_C_ADD_1p25MS
     129     1189311 :     if (sns_preemph_adapt != NULL && frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
     130             :     {
     131           0 :         *LT_normcorr = normcorr * 0.125f + *LT_normcorr * 0.875f;
     132             : 
     133           0 :         start = 0.8f;   /* adaptive preemphasis active from start to 1.0 */
     134           0 :         fac = (fmax(*LT_normcorr - start, 0) * (1. / (1.-start)));
     135             : 
     136           0 :         for (i = 0; i < 64; i++) {
     137           0 :             x[i] = x[i] * (sns_preemph[i] + fac*sns_preemph_adapt[i]);
     138             :         }
     139             :     } 
     140             :     else
     141             :     {
     142    77305215 :         for (i = 0; i < 64; i++) {
     143    76115904 :             x[i] = x[i] * sns_preemph[i];
     144             :         }
     145             :     }
     146             : #else 
     147             :     for (i = 0; i < 64; i++) {
     148             :         x[i] = x[i] * sns_preemph[i];
     149             :     }
     150             : #endif
     151             : 
     152             :     /* Noise floor at -40dB */
     153    77305215 :     for (i = 0; i < 64; i++) {
     154    76115904 :         sum += x[i];
     155             :     }
     156             : 
     157     1189311 :     mean = sum * 0.015625; /* 1/64 */
     158             : 
     159     1189311 :     nf = mean * 1.00e-04;
     160     1189311 :     nf = MAX(nf, 2.328306436538696e-10);
     161             : 
     162    77305215 :     for (i = 0; i < 64; i++) {
     163    76115904 :         if (x[i] < nf) {
     164    10928254 :             x[i] = nf;
     165             :         }
     166             :     }
     167             : 
     168             :     /* Log-domain */
     169    77305215 :     for (i = 0; i < 64; i++) {
     170    76115904 :         x[i] = LC3_LOGTWO(x[i]) * 0.5;
     171             :     }
     172             : 
     173             :     /* Downsampling */
     174    20218287 :     for (n = 0; n < 16; n++) {
     175    19028976 :         if (n == 0) {
     176     1189311 :             x_tmp1[0] = x[0];
     177             : 
     178     1189311 :             move_float(&x_tmp1[1], &x[0], 5);
     179             : 
     180    17839665 :         } else if (n == 15) {
     181     1189311 :             move_float(x_tmp1, &x[59], 5);
     182             : 
     183     1189311 :             x_tmp1[5] = x[63];
     184             : 
     185             :         } else {
     186    16650354 :             move_float(x_tmp1, &x[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1));
     187             :         }
     188             : 
     189    19028976 :         sum = 0;
     190   133202832 :         for (i = 0; i < 6; i++) {
     191   114173856 :             sum += x_tmp1[i] * sns_W[i];
     192             :         }
     193             : 
     194    19028976 :         gains_smooth[n] = sum;
     195    19028976 :         sum_gains_smooth += sum;
     196             :     }
     197             : #ifdef CR9_C_ADD_1p25MS
     198             :     /* limit shaping */
     199     1189311 :     if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) {
     200           0 :         limiterGain *= limitShaping(gains_smooth);
     201             :     }
     202             : #endif
     203             :     /* Remove mean and scaling */
     204     1189311 :     mean = sum_gains_smooth / 16.0;
     205             : 
     206    20218287 :     for (i = 0; i < 16; i++) {
     207             : #ifdef CR9_C_ADD_1p25MS
     208    19028976 :         gains[i] = limiterGain * sns_damping * (gains_smooth[i] - mean);
     209             : #else
     210             :         gains[i] = sns_damping * (gains_smooth[i] - mean);
     211             : #endif
     212             :     }
     213             : 
     214             :     /* Smoothing */
     215             : #ifdef CR9_C_ADD_1p25MS_LRSNS 
     216     1189311 :      if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS)
     217             :     {   /* smoothing loop for 1.25 ms  */
     218             : 
     219           0 :         const LC3_FLOAT A0 = 3.0 / 16.0;  /* 2/16= 0.125,   3/16 = 0.1875  */
     220           0 :         const LC3_FLOAT A1 = (1.0 - 2 * A0);
     221           0 :         const LC3_FLOAT A2 = A0;
     222             : 
     223           0 :         gains_smooth[0] = A0 * (gains[0] + gains[1]) * 0.5 + A1 * gains[0] + A2 * gains[1];
     224             :         /* BASOP-loop:: preload gains[-1] with  0.5*(gains[0]+gains[1]) */
     225           0 :         for (i = 1; i < (M - 1); i++)
     226             :         {
     227           0 :             gains_smooth[i] = A0 * gains[i - 1] + A1 * gains[i] + A2 * gains[i + 1];
     228             :         }
     229           0 :         gains_smooth[M - 1] = A0 * gains[M - 2] + A1 * gains[M - 1] + A2 * 0.5 * (gains[M - 2] + gains[M - 1]);
     230             :         /* BASOP-loop :: preload gains[M] with  0.5*(gains[M-2]+gains[M-1]) */
     231           0 :         sum = 0;
     232           0 :         for (i = 0; i < M; i++)
     233             :         {
     234           0 :             sum += gains_smooth[i];
     235             :         }
     236             : 
     237           0 :         mean = sum / (LC3_FLOAT)M;
     238           0 :         for (i = 0; i < M; i++)
     239             :         {
     240           0 :             gains[i] = attdec_damping_factor * (gains_smooth[i] - mean);
     241             :         }
     242             :     }
     243     1189311 :     else if (smooth == 1) /* original attack smoothing */
     244             : #else
     245             :     if (smooth)
     246             : #endif
     247             :     {
     248        5139 :         gains_smooth[0] = (gains[0] + gains[1] + gains[2]) / 3.0;
     249        5139 :         gains_smooth[1] = (gains[0] + gains[1] + gains[2] + gains[3]) / 4.0;
     250             : 
     251       66807 :         for (i = 2; i < 14; i++) {
     252       61668 :             gains_smooth[i] = (gains[i - 2] + gains[i - 1] + gains[i] + gains[i + 1] + gains[i + 2]) / 5.0;
     253             :         }
     254             : 
     255        5139 :         gains_smooth[M - 2] = (gains[M - 4] + gains[M - 3] + gains[M - 2] + gains[M - 1]) / 4.0;
     256        5139 :         gains_smooth[M - 1] = (gains[M - 3] + gains[M - 2] + gains[M - 1]) / 3.0;
     257             : 
     258        5139 :         sum = 0;
     259       87363 :         for (i = 0; i < M; i++) {
     260       82224 :             sum += gains_smooth[i];
     261             :         }
     262             : 
     263        5139 :         mean = sum / (LC3_FLOAT)M;
     264             : 
     265       87363 :         for (i = 0; i < M; i++) {
     266       82224 :             gains[i] = attdec_damping_factor * (gains_smooth[i] - mean);
     267             :         }
     268             :     }
     269     1189311 : }

Generated by: LCOV version 1.14