LCOV - code coverage report
Current view: top level - lib_lc3plus - pc_classify.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 0 69 0.0 %
Date: 2025-05-23 08:37:30 Functions: 0 2 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 "options.h"
      11             : #include "wmc_auto.h"
      12             : #include "functions.h"
      13             : 
      14             : LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen);
      15             : 
      16           0 : void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi)
      17             : {
      18             :         LC3_INT32 maxPitchBin, xover, i;
      19             :         LC3_FLOAT part_nrg, full_nrg;
      20             :     
      21           0 :     part_nrg = 0; full_nrg = 0;
      22             :     
      23           0 :     if (spec_inv_idx < (4 * frame_dms / 10))
      24             :     {
      25           0 :         if (stab_fac < 0.5)
      26             :         {
      27           0 :             *bfi = 1;
      28           0 :         } else if (pitch_present == 1)
      29             :         {
      30           0 :             maxPitchBin = 8;
      31           0 :             if (frame_dms == 50)
      32             :             {
      33           0 :                 maxPitchBin = 4;
      34             :             }
      35           0 :             xover = pc_peak_detector(q_d_prev, yLen);
      36           0 :             if (spec_inv_idx < xover || spec_inv_idx < maxPitchBin)
      37             :             {
      38           0 :                 *bfi = 1;
      39             :             }
      40             :         } else {
      41           0 :             for (i = 0; i < spec_inv_idx; i++)
      42             :             {
      43           0 :                 part_nrg += LC3_POW(q_old_res[i], 2);
      44             :             }
      45             :             
      46           0 :             for (i = 0; i < yLen; i++)
      47             :             {
      48           0 :                 full_nrg += LC3_POW(q_old_res[i], 2);
      49             :             }
      50             : 
      51           0 :             if (part_nrg < (0.3 * full_nrg))
      52             :             {
      53           0 :                 *bfi = 1;
      54             :             }
      55             :         }
      56             :     }
      57           0 : }
      58             : 
      59           0 : LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen)
      60             : {
      61             :         LC3_INT32 block_size, thresh1, i, peak, j, k;
      62             :         LC3_FLOAT fac, mean_block_nrg, cur_max, block_cent, maxPeak, next_max, prev_max;
      63             :     
      64           0 :     mean_block_nrg = 0;
      65             :     
      66           0 :     block_size = 3;
      67           0 :     thresh1 = 8;
      68           0 :     fac = 0.3;
      69             :     
      70           0 :     for (i = 0; i < yLen; i++)
      71             :     {
      72           0 :         mean_block_nrg += LC3_POW(q_d_prev[i], 2);
      73             :     }
      74             :     
      75           0 :     mean_block_nrg /= yLen;
      76             :     
      77           0 :     maxPeak = 0;
      78           0 :     peak = 0;
      79             :     
      80           0 :     if (LC3_FABS(q_d_prev[0]) > LC3_FABS(q_d_prev[1]))
      81             :     {
      82           0 :         block_cent = LC3_POW(q_d_prev[0], 2) + LC3_POW(q_d_prev[1], 2);
      83             :         
      84           0 :         if ((block_cent / block_size) > (thresh1 * mean_block_nrg))
      85             :         {
      86           0 :             cur_max = MAX(LC3_FABS(q_d_prev[0]), LC3_FABS(q_d_prev[1]));
      87           0 :             next_max = array_max_abs(&q_d_prev[2], 3);
      88             :             
      89           0 :             if (cur_max > next_max)
      90             :             {
      91           0 :                 maxPeak = block_cent;
      92           0 :                 peak = 1;
      93             :             }
      94             :         }
      95             :     }
      96             :     
      97           0 :     for (i = 0; i < block_size; i++)
      98             :     {
      99           0 :         if ((LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i])) && LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i + 2]))
     100             :         {
     101           0 :             block_cent = 0;
     102           0 :             for (j = i; j < i + block_size; j++)
     103             :             {
     104           0 :                 block_cent += LC3_POW(q_d_prev[j], 2);
     105             :             }
     106             :             
     107           0 :             if ((block_cent / block_size) > (thresh1 * mean_block_nrg))
     108             :             {
     109           0 :                 cur_max = array_max_abs(&q_d_prev[i], block_size);
     110           0 :                 prev_max = 0;
     111             :                 
     112           0 :                 for (k = i - block_size; k < i; k++)
     113             :                 {
     114           0 :                     if (k > 0)
     115             :                     {
     116           0 :                         prev_max = MAX(LC3_FABS(q_d_prev[k]), prev_max);
     117             :                     }
     118             :                 }
     119           0 :                 next_max = array_max_abs(&q_d_prev[i + block_size], block_size);
     120             :                 
     121           0 :                 if ((cur_max >= prev_max) && (cur_max > next_max))
     122             :                 {
     123           0 :                     if (block_cent > (fac * maxPeak))
     124             :                     {
     125           0 :                         peak = i + block_size - 1;
     126           0 :                         if (block_cent >= maxPeak)
     127             :                         {
     128           0 :                             maxPeak = block_cent;
     129             :                         }
     130             :                     }
     131             :                 }
     132             :             }
     133             :         }
     134             :     }
     135             :     
     136           0 :     for (i = block_size; i < yLen - (2 * block_size); i++)
     137             :     {
     138           0 :         if ((LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i])) && LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i + 2]))
     139             :         {
     140           0 :             block_cent = 0;
     141           0 :             for (j = i; j < i + block_size; j++)
     142             :             {
     143           0 :                 block_cent += LC3_POW(q_d_prev[j], 2);
     144             :             }
     145             :             
     146           0 :             if ((block_cent / block_size) > (thresh1 * mean_block_nrg))
     147             :             {
     148           0 :                 cur_max = array_max_abs(&q_d_prev[i], block_size);
     149           0 :                 prev_max = array_max_abs(&q_d_prev[i - block_size], block_size);
     150           0 :                 next_max = array_max_abs(&q_d_prev[i + block_size], block_size);
     151             :                 
     152           0 :                 if ((cur_max >= prev_max) && (cur_max > next_max))
     153             :                 {
     154           0 :                     if (block_cent > (fac * maxPeak))
     155             :                     {
     156           0 :                         peak = i + block_size - 1;
     157           0 :                         if (block_cent >= maxPeak)
     158             :                         {
     159           0 :                             maxPeak = block_cent;
     160             :                         }
     161             :                     }
     162             :                 }
     163             :             }
     164             :         }
     165             :     }
     166             :     
     167           0 :     return peak;
     168             : }
     169             : 

Generated by: LCOV version 1.14