LCOV - code coverage report
Current view: top level - lib_lc3plus - tns_decoder_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 57 0.0 %
Date: 2025-08-23 01:22:27 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 "functions.h"
      11             : 
      12             : static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x);
      13             : 
      14             : /*************************************************************************/
      15             : 
      16           0 : void processTnsDecoder_fx(Word16 rc_idx[], Word32 x[], Word16 xLen, Word16 order[], Word16 *x_e, Word16 BW_stopband_idx,
      17             :                           Word16 frame_dms, Word8 *scratchBuffer
      18             : #ifdef ENABLE_HR_MODE
      19             :                           , Word16 hrmode
      20             : #endif
      21             : )
      22             : {
      23             :     Dyn_Mem_Deluxe_In(
      24             :         Word32 *state;
      25             :         Counter i, j;
      26             :         Word16  s1, s2, s, *rc, f, stopfreq, BW_stopband;
      27             :         Word16  numfilters, startfreq[TNS_NUMFILTERS_MAX];
      28             :     );
      29             : 
      30           0 :     state = (Word32 *)scratchAlign(scratchBuffer, 0);               /* Size = MAXLAG */
      31           0 :     rc    = (Word16 *)scratchAlign(state, sizeof(*state) * MAXLAG); /* Size = MAXLAG */
      32             : 
      33           0 :     numfilters  = 1;
      34             :     
      35             : #ifdef ENABLE_HR_MODE
      36           0 :     if (hrmode == 1)
      37             :     {
      38           0 :         BW_stopband = BW_cutoff_bin_all_HR[BW_stopband_idx];        move16();
      39             :     }
      40             :     else
      41             : #endif
      42             :     {
      43           0 :         BW_stopband = BW_cutoff_bin_all[BW_stopband_idx]; move16();
      44             :     }
      45             : 
      46           0 :     SWITCH (frame_dms)
      47             :     {
      48           0 :     case 25:
      49           0 :         startfreq[0] = 3; move16();
      50           0 :         BW_stopband  = shr_pos(BW_stopband, 2);
      51           0 :         BREAK;
      52           0 :     case 50:
      53           0 :         startfreq[0] = 6; move16();
      54           0 :         BW_stopband  = shr_pos(BW_stopband, 1);
      55           0 :         BREAK;
      56           0 :     case 75:
      57           0 :         startfreq[0] = 9; move16();
      58           0 :         BW_stopband = add(shr_pos(BW_stopband, 2), add(shr_pos(BW_stopband, 2), shr_pos(BW_stopband, 2)));
      59           0 :         BREAK;
      60           0 :     case 100: startfreq[0] = 12; BREAK;
      61             :     }
      62             : 
      63           0 :     IF (sub(BW_stopband_idx, 3) >= 0 && frame_dms >= 50)
      64             :     {
      65           0 :         numfilters   = 2;
      66           0 :         startfreq[1] = shr_pos(BW_stopband, 1);
      67             :     }
      68           0 :     stopfreq = 0;
      69             : 
      70           0 :     test(); test();
      71           0 :     IF (order[0] > 0 || (sub(numfilters, 2) == 0 && order[1] > 0))
      72             :     {
      73             :         /* Scaling */
      74           0 :         f = startfreq[0]; move16();
      75           0 :         test();
      76           0 :         IF (sub(numfilters, 2) == 0 && order[0] == 0)
      77             :         {
      78           0 :             f = startfreq[1]; move16();
      79             :         }
      80           0 :         s1   = getScaleFactor32_lc3plus(x, f);
      81           0 :         s2   = getScaleFactor32_lc3plus(x + f, sub(xLen, f));
      82           0 :         s    = s_min(s1, sub(s2, 7)); /* 7 bits of headroom for IIR filtering */
      83           0 :         *x_e = sub(*x_e, s);
      84             : 
      85             : /* Init Filter */
      86           0 :         basop_memset(state, 0, MAXLAG * sizeof(Word32));
      87           0 :         FOR (i = 0; i < f; i++)
      88             :         {
      89           0 :             x[i] = L_shl(x[i], s); move32();
      90             :         }
      91             : 
      92           0 :         FOR (j = 0; j < numfilters; j++)
      93             :         {
      94           0 :             IF (order[j] > 0)
      95             :             {
      96             :                 /* Unquantize coefficients */
      97           0 :                 FOR (i = 0; i < order[j]; i++)
      98             :                 {
      99           0 :                     rc[i] = tnsQuantPts[rc_idx[j * MAXLAG + i]]; move16();
     100             :                 }
     101             : 
     102             :                 /* Stop frequency */
     103           0 :                 stopfreq = BW_stopband; move16();
     104           0 :                 IF (sub(numfilters, 2) == 0 && j == 0)
     105             :                 {
     106           0 :                     stopfreq = startfreq[1];
     107             :                 }
     108             : 
     109             :                 /* Filter */
     110           0 :                 FOR (i = startfreq[j]; i < stopfreq; i++)
     111             :                 {
     112           0 :                     x[i] = IIRLattice(order[j], rc, state, L_shl(x[i], s)); move32();
     113             :                 }
     114             :             }
     115             :         }
     116           0 :         FOR (i = stopfreq; i < xLen; i++)
     117             :         {
     118           0 :             x[i] = L_shl(x[i], s); move32();
     119             :         }
     120             :     }
     121             :     Dyn_Mem_Deluxe_Out();
     122           0 : }
     123             : 
     124             : /*************************************************************************/
     125             : /*************************************************************************/
     126             : /*************************************************************************/
     127             : 
     128           0 : static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x)
     129             : {
     130             :     Dyn_Mem_Deluxe_In(
     131             :         Counter i;
     132             :     );
     133             : 
     134             :     /* first stage: no need to calculate state[order-1] */
     135           0 :     x = L_sub_sat(x, Mpy_32_16_lc3plus(state[order - 1], parCoeff[order - 1]));
     136             : 
     137           0 :     FOR (i = order - 2; i >= 0; i--)
     138             :     {
     139           0 :         x            = L_sub(x, Mpy_32_16_lc3plus(state[i], parCoeff[i]));
     140           0 :         state[i + 1] = L_add(state[i], Mpy_32_16_lc3plus(x, parCoeff[i])); move32();
     141             :     }
     142             : 
     143           0 :     state[0] = x; move32();
     144             : 
     145             :     Dyn_Mem_Deluxe_Out();
     146           0 :     return x;
     147             : }
     148             : 

Generated by: LCOV version 1.14