LCOV - code coverage report
Current view: top level - lib_lc3plus - sns_compute_scf_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 87 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.5.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 "functions.h"
      11             : 
      12           0 : void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf,
      13             :                              Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping
      14             :                              )
      15             : {
      16             :     Dyn_Mem_Deluxe_In(
      17             :         Word16  i, s, s2, nf, tmp;
      18             :         Word32  L_mean, L_tmp;
      19             :         Word32 *d3_fx;
      20             :         Word16 *d3_fx_exp;
      21             :         Word16 *d4_fx;
      22             :         Word16 *scf_smooth;
      23             :     );
      24             : 
      25             :     UNUSED(attdec_damping_factor);
      26             : 
      27           0 :     d3_fx     = scratchAlign(scratchBuffer, 0);                         /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */
      28           0 :     d3_fx_exp = scratchAlign(d3_fx, sizeof(*d3_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
      29           0 :     d4_fx = scratchAlign(d3_fx_exp, sizeof(*d3_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128bytes */
      30           0 :     scf_smooth = scratchAlign(d4_fx, sizeof(*d4_fx) * MAX_BANDS_NUMBER);    /* Size = 2 * 16 */
      31             : 
      32             : /* Smoothing and Pre-emphasis */
      33           0 :     IF (sub(n_bands, 32) < 0)
      34             :     {
      35           0 :         L_tmp = sub(32, n_bands);
      36           0 :         FOR (i = sub(n_bands, 1); i >= L_tmp; i--)
      37             :         {
      38           0 :             d2_fx[(i + L_tmp) * 2 + 1] = d2_fx[i]; move32();
      39           0 :             d2_fx[(i + L_tmp) * 2 + 0] = d2_fx[i]; move32();
      40             :         }
      41           0 :         FOR (i = sub(L_tmp, 1); i >= 0; i--)
      42             :         {
      43           0 :             d2_fx[i * 4 + 3] = d2_fx[i]; move32();
      44           0 :             d2_fx[i * 4 + 2] = d2_fx[i]; move32();
      45           0 :             d2_fx[i * 4 + 1] = d2_fx[i]; move32();
      46           0 :             d2_fx[i * 4 + 0] = d2_fx[i]; move32();
      47             :         }
      48           0 :         n_bands = 64; move16();
      49             :     }
      50             :     ELSE
      51           0 :     IF (sub(n_bands, 64) < 0)
      52             :     {
      53           0 :         L_tmp = sub(64, n_bands);
      54           0 :         FOR (i = sub(n_bands, 1); i >= L_tmp; i--)
      55             :         {
      56           0 :             d2_fx[i + L_tmp] = d2_fx[i]; move32();
      57             :         }
      58           0 :         FOR (i = sub(L_tmp, 1); i >= 0; i--)
      59             :         {
      60           0 :             d2_fx[i * 2 + 1] = d2_fx[i]; move32();
      61           0 :             d2_fx[i * 2 + 0] = d2_fx[i]; move32();
      62             :         }
      63           0 :         n_bands = 64; move16();
      64             :     }
      65             :     
      66           0 :     L_tmp        = L_add(Mpy_32_16_lc3plus(d2_fx[0], 24576), L_shr_pos(d2_fx[1], 2));
      67           0 :     d3_fx[0]     = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][0]); move32();
      68           0 :     d3_fx_exp[0] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][0]); move16();
      69           0 :     FOR (i = 1; i < n_bands - 1; i++)
      70             :     {
      71           0 :         L_tmp        = L_add(L_shr_pos(d2_fx[i], 1), L_add(L_shr_pos(d2_fx[i - 1], 2), L_shr_pos(d2_fx[i + 1], 2)));
      72           0 :         d3_fx[i]     = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][i]); move32();
      73           0 :         d3_fx_exp[i] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][i]); move16();
      74             :     }
      75           0 :     L_tmp                  = L_add(Mpy_32_16_lc3plus(d2_fx[n_bands - 1], 24576), L_shr_pos(d2_fx[n_bands - 2], 2));
      76           0 :     d3_fx[n_bands - 1]     = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][n_bands - 1]); move32();
      77           0 :     d3_fx_exp[n_bands - 1] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][n_bands - 1]); move16();
      78             : 
      79             :     /* Mean */
      80           0 :     s  = d3_fx_exp[MAX_BANDS_NUMBER - 1];
      81           0 :     s2 = add(s, 6);
      82             : 
      83           0 :     L_mean = L_shr(d3_fx[0], sub(s2, d3_fx_exp[0]));
      84           0 :     FOR (i = 1; i < MAX_BANDS_NUMBER; i++)
      85             :     {
      86           0 :         L_mean = L_add(L_mean, L_shr(d3_fx[i], sub(s2, d3_fx_exp[i])));
      87             :     }
      88             : 
      89             :     /* Noise floor at -40dB */
      90           0 :     nf = BASOP_Util_Log2_16(L_mean, s);
      91           0 :     nf = sub(s_max(nf, -25965), 6803);
      92             : 
      93             : /* Log-domain */
      94           0 :     FOR (i = 0; i < MAX_BANDS_NUMBER; i++)
      95             :     {
      96           0 :         d4_fx[i] = s_max(nf, BASOP_Util_Log2_16(d3_fx[i], d3_fx_exp[i])); move16();
      97             :     }
      98             : 
      99             :     /* Downsampling */
     100           0 :     L_tmp    = L_mult(d4_fx[0], 8192);
     101           0 :     L_tmp    = L_mac(L_tmp, d4_fx[1], 8192);
     102           0 :     L_tmp    = L_mac(L_tmp, d4_fx[2], 8192);
     103           0 :     L_tmp    = L_mac(L_tmp, d4_fx[3], 5461);
     104           0 :     d3_fx[0] = L_mac(L_tmp, d4_fx[4], 2731); move32();
     105           0 :     FOR (i = 1; i < M - 1; i++)
     106             :     {
     107           0 :         L_tmp    = L_mult(d4_fx[i * 4 - 1], 2731);
     108           0 :         L_tmp    = L_mac(L_tmp, d4_fx[i * 4 + 0], 5461);
     109           0 :         L_tmp    = L_mac(L_tmp, d4_fx[i * 4 + 1], 8192);
     110           0 :         L_tmp    = L_mac(L_tmp, d4_fx[i * 4 + 2], 8192);
     111           0 :         L_tmp    = L_mac(L_tmp, d4_fx[i * 4 + 3], 5461);
     112           0 :         d3_fx[i] = L_mac(L_tmp, d4_fx[i * 4 + 4], 2731); move32();
     113             :     }
     114           0 :     L_tmp        = L_mult(d4_fx[59], 2731);
     115           0 :     L_tmp        = L_mac(L_tmp, d4_fx[60], 5461);
     116           0 :     L_tmp        = L_mac(L_tmp, d4_fx[61], 8192);
     117           0 :     L_tmp        = L_mac(L_tmp, d4_fx[62], 8192);
     118           0 :     d3_fx[M - 1] = L_mac(L_tmp, d4_fx[63], 8192); move32();
     119             : 
     120             : /* Remove mean and scaling */
     121           0 :     L_mean = L_shr_pos(d3_fx[0], 4);
     122           0 :     FOR (i = 1; i < M; i++)
     123             :     {
     124           0 :         L_mean = L_add(L_mean, L_shr_pos(d3_fx[i], 4));
     125             :     }
     126             : 
     127           0 :     FOR (i = 0; i < M; i++)
     128             :     {
     129           0 :         scf[i] = mult_r(sns_damping, round_fx(L_shl_pos(L_sub(d3_fx[i], L_mean), 1)));
     130           0 :         move16();
     131             :     }
     132             : 
     133             :     /* scale factor smoothing */
     134           0 :     IF (scf_smoothing_enabled)
     135             :     {
     136           0 :         scf_smooth[0] = L_shr(L_mult0(L_add(L_add(scf[0], scf[1]), scf[2]), 10923), 15);
     137           0 :         L_mean        = scf_smooth[0]; move16();
     138           0 :         scf_smooth[1] = L_shr(L_add(L_add(L_add(scf[0], scf[1]), scf[2]), scf[3]), 2);
     139           0 :         L_mean        = L_add(L_mean, scf_smooth[1]);
     140           0 :         FOR (i = 2; i < M - 2; i++)
     141             :         {
     142           0 :             L_tmp         = L_add(L_add(L_add(L_add(scf[i - 2], scf[i - 1]), scf[i]), scf[i + 1]), scf[i + 2]);
     143           0 :             tmp = norm_s(L_shr(L_abs(L_tmp), 15));
     144           0 :             if (tmp > 0) {
     145           0 :                 tmp = sub(16, tmp);
     146           0 :                 L_tmp = L_shr(L_tmp, tmp);
     147             :             }
     148           0 :             scf_smooth[i] = L_shr(L_mult0(L_tmp, 13107), sub(16, tmp));
     149           0 :             L_mean        = L_add(L_mean, scf_smooth[i]);
     150             :         }
     151           0 :         scf_smooth[M - 2] = L_shr(L_add(L_add(L_add(scf[M - 4], scf[M - 3]), scf[M - 2]), scf[M - 1]), 2);
     152           0 :         L_mean            = L_add(L_mean, scf_smooth[M - 2]);
     153           0 :         scf_smooth[M - 1] = L_shr(L_mult0(L_add(L_add(scf[M - 3], scf[M - 2]), scf[M - 1]), 10923), 15);
     154           0 :         L_mean            = L_add(L_mean, scf_smooth[M - 1]);
     155             : 
     156           0 :         L_mean = L_shr(L_mean, 4);
     157             :         
     158           0 :         FOR (i = 0; i < M; i++)
     159             :         {
     160           0 :             scf[i] = mult_r(attdec_damping_factor, sub(scf_smooth[i], L_mean));
     161             :         }
     162             :     }
     163             : 
     164             :     Dyn_Mem_Deluxe_Out();
     165           0 : }
     166             : 

Generated by: LCOV version 1.14