LCOV - code coverage report
Current view: top level - lib_lc3plus - residual_coding_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 61 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             : #ifdef ENABLE_HR_MODE
      13             : 
      14           0 : void processResidualCoding_fx(Word16 x_e, Word32 x[], 
      15             :                               Word32 xq[], Word32 gain,
      16             :                               Word16 gain_e, Word16 L_spec,
      17             :                               Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits
      18             :                               , Word16 hrmode
      19             : )
      20             : {
      21             : 
      22             :     Counter i;
      23             :     Word16  s, n, m;
      24             :     Word32  L_tmp;
      25           0 :     Word16  iter = 0;
      26             :     Counter idx;
      27           0 :     Word16 N_nz = 0;
      28             :     Word16 n1, n2;
      29             : 
      30             : #ifdef DYNMEM_COUNT
      31             :     Dyn_Mem_In("processResidualCoding_fx", sizeof(struct {
      32             :                    Counter i;
      33             :                    Word16  s, n, m;
      34             :                    Word32  L_tmp;
      35             :                    Word16  iter;
      36             :                    Counter idx;
      37             :                    Word16 N_nz;
      38             :                    Word16 *nz_idx;
      39             :                    Word16 n1, n2;
      40             :                }));
      41             : #endif
      42             : 
      43           0 :     n = 0;
      44           0 :     move16();
      45             :     
      46           0 :     IF (hrmode)
      47             :     {
      48           0 :         m = add(sub(targetBits, nBits), 14);
      49           0 :         assert(m <= (MAX_RESBITS_LEN << RESBITS_PACK_SHIFT));
      50             :     }
      51             :     ELSE
      52             :     {
      53           0 :         m = add(sub(targetBits, nBits), 4);
      54           0 :         if (m > L_spec)
      55             :         {
      56           0 :             m = L_spec;
      57             :         }
      58             :     }
      59             : 
      60           0 :     basop_memset(resBits, 0, sizeof(*resBits)*((m + RESBITS_PACK_MASK) >> RESBITS_PACK_SHIFT));
      61             : 
      62           0 :     s = sub(add(15, gain_e), x_e);
      63             : 
      64           0 :     IF(hrmode)
      65             :     {
      66             :         /* 
      67             :         x = xval * 2^(31 - x_e)
      68             :         gain = gainval * 2^(15 - gain_e)
      69             : 
      70             :         To bring gain to the same q of x :
      71             : 
      72             :         gain (in_Qx_e) = gain * 2^(16 + gain_e - x_e)
      73             : 
      74             :         gain*offset (in Qx_e) = gain (in_Qx_e) * 0.25 = gain (in_Qx_e) / 4 = gain * 2^(16 - 2 + gain_e - x_e)
      75             :         */
      76             :         Word16 shift_val;
      77           0 :             shift_val = sub(sub(gain_e, x_e), 2);
      78             : 
      79             :         Word32 gain_offset;
      80             : 
      81           0 :         IF (shift_val <= -32)
      82           0 :             gain_offset = 0;
      83             :         ELSE
      84             :         {
      85           0 :             gain_offset = L_shl_sat(gain, shift_val);
      86             :         }
      87             :         
      88           0 :         Word16 exit_iter   = 0;
      89             :         
      90             :         Word16 nz_idx[MAX_LEN];
      91             : 
      92             :         /* enumerate non-zero coefficients */
      93           0 :         FOR (i = 0; i < L_spec; i++)
      94             :         {
      95           0 :             IF (xq[i])
      96             :             {
      97           0 :                 nz_idx[N_nz] = i; move16();
      98           0 :                 N_nz = add(N_nz, 1);
      99             :             }
     100             :         }
     101             : 
     102           0 :         s = sub(31, sub(x_e, gain_e));
     103           0 :         FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++)
     104             :         {
     105           0 :             FOR (i = 0; i < N_nz; i++)
     106             :             {
     107           0 :                 idx = nz_idx[i];
     108             : 
     109           0 :                 L_tmp = L_sub(x[idx], Mpy_32_32_lc3plus(L_shl(xq[idx], s), gain));
     110             : 
     111           0 :                 IF (L_tmp >= 0)
     112             :                 {
     113           0 :                     n1          = shr(n, RESBITS_PACK_SHIFT);
     114           0 :                     n2          = s_and(n, RESBITS_PACK_MASK);
     115           0 :                     resBits[n1] = (UWord8)s_or(resBits[n1], shl(1, n2));
     116           0 :                     move16();
     117           0 :                     x[idx] = L_sub(x[idx], gain_offset);
     118           0 :                     move16();
     119             :                 }
     120             :                 ELSE
     121             :                 {
     122           0 :                     move16();
     123           0 :                     x[idx] = L_add(x[idx], gain_offset);
     124           0 :                     move16();
     125             :                 }
     126           0 :                 n = add(n, 1);
     127           0 :                 IF (sub(n, m) == 0)
     128             :                 {
     129           0 :                     exit_iter = 1;
     130           0 :                     BREAK;
     131             :                 }
     132             :             }
     133           0 :             gain_offset = L_shr(gain_offset, 1); /* offset *= 0.5 */
     134             : 
     135           0 :             IF (exit_iter)
     136             :             {
     137           0 :                 BREAK;
     138             :             }
     139             :         }
     140             :     }
     141             :     ELSE
     142             :     {
     143           0 :         s = add(s, 16);
     144           0 :         gain = round_fx(gain);
     145             : 
     146           0 :         FOR (i = 0; i < L_spec; i++)
     147             :         {
     148           0 :             IF (xq[i] != 0)
     149             :             {
     150           0 :                 L_tmp = L_sub(x[i], Mpy_32_16_lc3plus(L_shl(xq[i], s), gain));
     151           0 :                 if (L_tmp >= 0)
     152             :                 {
     153           0 :                     n1 = shr(n, RESBITS_PACK_SHIFT);
     154           0 :                     n2 = s_and(n, RESBITS_PACK_MASK);
     155           0 :                     resBits[n1] = (UWord8) s_or(resBits[n1], shl(1, n2));
     156           0 :                     move16();
     157             :                 }
     158           0 :                 n = add(n, 1);
     159           0 :                 IF (sub(n, m) == 0)
     160             :                 {
     161           0 :                     BREAK;
     162             :                 }
     163             :             }
     164             :         }
     165             :     }
     166           0 :     *numResBits = n;
     167           0 :     move16();
     168             : 
     169             : #ifdef DYNMEM_COUNT
     170             :     Dyn_Mem_Out();
     171             : #endif
     172           0 : }
     173             : 
     174             : #else
     175             : 
     176             : void processResidualCoding_fx(Word16 x_e, Word32 x[], 
     177             :                               Word16 xq[], 
     178             :                               Word16 gain, Word16 gain_e, Word16 L_spec,
     179             :                               Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits
     180             : )
     181             : {
     182             : 
     183             :     Counter i;
     184             :     Word16  s, n, m;
     185             :     Word32  L_tmp;
     186             : #ifdef DYNMEM_COUNT
     187             :     Dyn_Mem_In("processResidualCoding_fx", sizeof(struct {
     188             :                    Counter i;
     189             :                    Word16  s, n, m;
     190             :                    Word32  L_tmp;
     191             :                }));
     192             : #endif
     193             : 
     194             :     n = 0;
     195             :     move16();
     196             :     {
     197             :         m = add(sub(targetBits, nBits), 4);
     198             :         if (m > L_spec)
     199             :         {
     200             :             m = L_spec;
     201             :         }
     202             :     }
     203             : 
     204             : 
     205             :     s = sub(add(15, gain_e), x_e);
     206             :     {
     207             :         FOR (i = 0; i < L_spec; i++)
     208             :         {
     209             :             IF (xq[i] != 0)
     210             :             {
     211             :                 L_tmp = L_sub(x[i], L_shl(L_mult(xq[i], gain), s));
     212             :                 if (L_tmp < 0)
     213             :                 {
     214             :                     resBits[n] = 0;
     215             :                     move16();
     216             :                 }
     217             :                 if (L_tmp >= 0)
     218             :                 {
     219             :                     resBits[n] = 1;
     220             :                     move16();
     221             :                 }
     222             :                 n = add(n, 1);
     223             :                 IF (sub(n, m) == 0)
     224             :                 {
     225             :                     BREAK;
     226             :                 }
     227             :             }
     228             :         }
     229             :     }
     230             :     *numResBits = n;
     231             :     move16();
     232             : 
     233             : #ifdef DYNMEM_COUNT
     234             :     Dyn_Mem_Out();
     235             : #endif
     236             : }
     237             : 
     238             : #endif

Generated by: LCOV version 1.14