LCOV - code coverage report
Current view: top level - lib_lc3plus - noise_factor_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 122 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             : 
      13           0 : void processNoiseFactor_fx(Word16 *fac_ns_idx, Word16 x_e, Word32 x[],
      14             : #ifdef ENABLE_HR_MODE
      15             :                            Word32 xq[],
      16             : #else
      17             :                            Word16 xq[],
      18             : #endif
      19             :                            Word16 gg, Word16 gg_e, Word16 BW_cutoff_idx, Word16 frame_dms, Word16 target_bytes,
      20             :                            Word8 *scratchBuffer
      21             : #ifdef ENABLE_HR_MODE
      22             :                            ,Word16 hrmode
      23             : #endif
      24             : )
      25             : {
      26             :     Dyn_Mem_Deluxe_In(Counter k; Word16 nzeros, s1, s2, s3, c, idx, fac_unq, *ind;
      27             :                       Word16 noisefillwidth, noisefillstart, N; Word32 Lsum;);
      28             : 
      29             : 
      30             : 
      31           0 :     ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN bytes */
      32             : 
      33           0 :     noisefillwidth = 0;
      34           0 :     noisefillstart = 0;
      35           0 :     c              = 0;
      36           0 :     move16();
      37             :     
      38             : #ifdef ENABLE_HR_MODE
      39           0 :     if (hrmode)
      40             :     {
      41           0 :         N = BW_cutoff_bin_all_HR[BW_cutoff_idx];
      42           0 :         move16();    
      43             :     }
      44             :     else
      45             : #endif
      46             :     {
      47           0 :         N = BW_cutoff_bin_all[BW_cutoff_idx];
      48           0 :         move16();
      49             :     }
      50             : 
      51           0 :     SWITCH (frame_dms)
      52             :     {
      53           0 :     case 25:
      54           0 :         N              = shr_pos(N, 2);
      55           0 :         noisefillwidth = NOISEFILLWIDTH_2_5MS;
      56           0 :         noisefillstart = NOISEFILLSTART_2_5MS;
      57           0 :         BREAK;
      58           0 :     case 50:
      59           0 :         N              = shr_pos(N, 1);
      60           0 :         noisefillwidth = NOISEFILLWIDTH_5MS;
      61           0 :         noisefillstart = NOISEFILLSTART_5MS;
      62           0 :         BREAK;
      63           0 :     case 75:
      64           0 :         N              = add(shr_pos(N, 2), add(shr_pos(N, 2), shr_pos(N, 2)));
      65           0 :         noisefillwidth = NOISEFILLWIDTH_7_5MS;
      66           0 :         noisefillstart = NOISEFILLSTART_7_5MS;
      67           0 :         BREAK;
      68           0 :     case 100:
      69           0 :         noisefillwidth = NOISEFILLWIDTH;
      70           0 :         noisefillstart = NOISEFILLSTART;
      71           0 :         BREAK;
      72             :     }
      73             : 
      74           0 :     nzeros = -2 * noisefillwidth - 1;
      75           0 :     move16();
      76             : 
      77           0 :     FOR (k = noisefillstart - noisefillwidth; k < noisefillstart + noisefillwidth; k++)
      78             :     {
      79           0 :         if (xq[k] != 0)
      80             :         {
      81           0 :             nzeros = -2 * noisefillwidth - 1;
      82           0 :             move16();
      83             :         }
      84           0 :         if (xq[k] == 0)
      85             :         {
      86           0 :             nzeros = add(nzeros, 1);
      87             :         }
      88             :     }
      89             : 
      90           0 :     FOR (k = noisefillstart; k < N - noisefillwidth; k++)
      91             :     {
      92           0 :         if (xq[k + noisefillwidth] != 0)
      93             :         {
      94           0 :             nzeros = -2 * noisefillwidth - 1;
      95           0 :             move16();
      96             :         }
      97           0 :         if (xq[k + noisefillwidth] == 0)
      98             :         {
      99           0 :             nzeros = add(nzeros, 1);
     100             :         }
     101           0 :         if (nzeros >= 0)
     102             :         {
     103           0 :             ind[c++] = k;
     104           0 :             move16();
     105             :         }
     106             :     }
     107             : 
     108           0 :     FOR (k = N - noisefillwidth; k < N; k++)
     109             :     {
     110           0 :         nzeros = add(nzeros, 1);
     111           0 :         if (nzeros >= 0)
     112             :         {
     113           0 :             ind[c++] = k;
     114           0 :             move16();
     115             :         }
     116             :     }
     117             : 
     118           0 :     IF (c == 0)
     119             :     {
     120           0 :         fac_unq = 0;
     121           0 :         move16();
     122             :     }
     123             :     ELSE
     124             :     {
     125             : 
     126           0 :         IF (target_bytes <= 20 && frame_dms == 100)
     127           0 :         {
     128             :             Word32 ind_sum;
     129             :             Word16 mean_ind;
     130             : 
     131             :             Word16 fac_unq1, fac_unq2;
     132             : 
     133             :             /* calculate mean index */
     134           0 :             ind_sum = ind[0];
     135           0 :             move32();
     136           0 :             FOR (k = 1; k < c; k++)
     137             :             {
     138           0 :                 ind_sum = L_add(ind_sum, ind[k]);
     139             :             }
     140             : 
     141           0 :             mean_ind = BASOP_Util_Divide3216_Scale_lc3plus(ind_sum, c, &s2);
     142           0 :             mean_ind = shl(mean_ind, s2 + 1);
     143             : 
     144           0 :             assert(0 <= mean_ind && mean_ind <= ind[c - 1]);
     145             : 
     146             :             /* calculate noise filling gain for low frequencies */
     147           0 :             s2 = 0; move16();
     148           0 :             if (sub(mean_ind, ind[0]) > 0)
     149             :             {
     150             :                 /* calculate scale to ensure that Lsum does not overflow */
     151           0 :                 s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(mean_ind, ind[0]))), 0);
     152             :             }      
     153           0 :             Lsum = L_shr_pos_pos(L_abs(x[ind[0]]), s2);
     154             : 
     155           0 :             FOR (k = 1; k < c && ind[k] <= mean_ind; k++)
     156             :             {
     157             :                 /* scale before adding to Lsum */
     158           0 :                 Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2));
     159             :             }
     160           0 :             fac_unq1 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, k, &s1);
     161             :             /* add scale applied during summing */
     162           0 :             s1 = add(s1, s2);
     163           0 :             fac_unq1 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq1, gg, &s2);
     164           0 :             s3       = sub(15, add(x_e, add(s1, sub(s2, gg_e))));
     165           0 :             s2       = norm_s(fac_unq1);
     166           0 :             test();
     167           0 :             IF (fac_unq1 != 0 && add(s3, s2) < 0)
     168             :             {
     169           0 :                 fac_unq1 = MAX_16;
     170           0 :                 move16();
     171             :             }
     172             :             ELSE
     173             :             {
     174           0 :                 s3 = s_min(s_max(s3, -15), 15);
     175           0 :                 fac_unq1 = shr_r(fac_unq1, s3);
     176             :             }
     177             : 
     178             :             /* calculate noise filling gain for high frequencies */
     179           0 :             Lsum = 0;
     180           0 :             move16();
     181           0 :             idx = sub(c, k);
     182           0 :             FOR (; k < c; k++)
     183             :             {
     184           0 :                 Lsum = L_add(Lsum, L_abs(x[ind[k]]));
     185             :             }
     186           0 :             fac_unq2 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, idx, &s1);
     187           0 :             fac_unq2 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq2, gg, &s2);
     188           0 :             s3       = sub(15, add(x_e, add(s1, sub(s2, gg_e))));
     189           0 :             s2       = norm_s(fac_unq1);
     190           0 :             test();
     191           0 :             IF (fac_unq2 != 0 && add(s3, s2) < 0)
     192             :             {
     193           0 :                 fac_unq2 = MAX_16;
     194           0 :                 move16();
     195             :             }
     196             :             ELSE
     197             :             {
     198           0 :                 s3 = s_min(s_max(s3, -15), 15);
     199           0 :                 fac_unq2 = shr_r(fac_unq2, s3);
     200             :             }
     201             : 
     202             :             /* calculate noise filling gain as minimum over high and low frequencies */
     203           0 :             fac_unq = s_min(fac_unq1, fac_unq2);
     204             :         }
     205             :         ELSE
     206             :         {
     207             :             /* calculate scale to ensure that Lsum does not overflow */
     208           0 :             s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(N,ind[0]))), 0);
     209           0 :             Lsum = L_abs(x[ind[0]]);
     210           0 :             FOR (k = 1; k < c; k++)
     211             :             {
     212             :                 /* scale before adding to Lsum */
     213           0 :                 Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2));
     214             :             }
     215           0 :             fac_unq = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, c, &s1);
     216             :             /* add scale applied during summing */
     217           0 :             s1 = add(s1, s2);
     218           0 :             fac_unq = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq, gg, &s2);
     219           0 :             s3      = sub(15, add(x_e, add(s1, sub(s2, gg_e))));
     220           0 :             s2      = norm_s(fac_unq);
     221           0 :             test();
     222           0 :             IF (fac_unq != 0 && add(s3, s2) < 0)
     223             :             {
     224           0 :                 fac_unq = MAX_16;
     225           0 :                 move16();
     226             :             }
     227             :             ELSE
     228             :             {
     229           0 :                 fac_unq = shr_r(fac_unq, s_max(s_min(s3, 15), -15));
     230             :             }
     231             :         }
     232             :     }
     233             : 
     234           0 :     idx = round_fx(L_sub(0x80000, L_mult(fac_unq, 16)));
     235           0 :     if (sub(idx, 7) > 0)
     236             :     {
     237           0 :         idx = 7;
     238           0 :         move16();
     239             :     }
     240           0 :     if (idx < 0)
     241             :     {
     242           0 :         idx = 0;
     243           0 :         move16();
     244             :     }
     245           0 :     *fac_ns_idx = idx;
     246           0 :     move16();
     247             : 
     248             :     Dyn_Mem_Deluxe_Out();
     249           0 : }
     250             : 

Generated by: LCOV version 1.14