LCOV - code coverage report
Current view: top level - lib_lc3plus - levinson_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 52 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           0 : void processLevinson_fx(Word32 *lpc, Word32 *ac, Word16 N, Word16 *rc, Word32 *pred_err, Word8 *scratchBuffer)
      13             : {
      14             : 
      15             :     Word32 *lpc_tmp;
      16             :     Word32  rc32, err, sum;
      17             :     Word16  shift, s, inv;
      18             :     Counter n, m;
      19             : 
      20             : 
      21             : #ifdef DYNMEM_COUNT
      22             :     Dyn_Mem_In("processLevinson_fx", sizeof(struct {
      23             :                    Word32 *lpc_tmp;
      24             :                    Word32  rc32, err, sum;
      25             :                    Word16  shift, s, inv;
      26             :                    Counter n, m;
      27             :                    Word32  params[2];
      28             :                }));
      29             : #endif
      30             : 
      31           0 :     lpc_tmp = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * (M_LTPF + 1) = 100 bytes */
      32             : 
      33             :     /* Init Prediction Error */
      34           0 :     err   = ac[0]; move32();
      35           0 :     shift = 0;     move16();
      36             : 
      37             :     /* LPC Coefficient 0 */
      38           0 :     lpc[0] = 0x8000000; move32();
      39             : 
      40             :     /* Reflection Coefficient 0 */
      41           0 :     IF (ac[0] != 0)
      42             :     {
      43           0 :         inv  = div_s(16383, extract_h(ac[0]));
      44           0 :         rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(ac[1]), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(ac[0], inv)), inv)), 2);
      45             :     }
      46             :     ELSE
      47             :     {
      48           0 :         rc32 = 0; move32();
      49             :     }
      50           0 :     if (ac[1] > 0)
      51             :     {
      52           0 :         rc32 = L_negate(rc32);
      53             :     }
      54           0 :     if (rc != NULL)
      55             :     {
      56           0 :         rc[0] = round_fx(rc32); move16();
      57             :     }
      58             : 
      59             :     /* LPC Coefficient 1 */
      60           0 :     lpc[1] = L_shr_pos(rc32, 4); move32();
      61             : 
      62           0 :     FOR (n = 2; n <= N; n++)
      63             :     {
      64             :         /* Update Prediction Error */
      65           0 :         err   = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32)));
      66           0 :         s     = norm_l(err);
      67           0 :         err   = L_shl_pos(err, s);
      68           0 :         shift = add(shift, s);
      69             : 
      70             :         /* Reflection Coefficient n-1 */
      71           0 :         sum = Mpy_32_32_lc3plus(ac[1], lpc[n - 1]);
      72           0 :         FOR (m = 2; m < n; m++)
      73             :         {
      74           0 :             sum = L_add(sum, Mpy_32_32_lc3plus(ac[m], lpc[n - m]));
      75             :         }
      76             : 
      77           0 :         sum = L_add(L_shl_pos(sum, 4), ac[n]);
      78           0 :         IF (err != 0)
      79             :         {
      80           0 :             inv  = div_s(16383, extract_h(err));
      81           0 :             rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(sum), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(err, inv)), inv)), 2);
      82             :         }
      83             :         ELSE
      84             :         {
      85           0 :             rc32 = 0;
      86             :         }
      87           0 :         if (sum > 0)
      88             :         {
      89           0 :             rc32 = L_negate(rc32);
      90             :         }
      91           0 :         rc32 = L_shl(rc32, shift);
      92           0 :         if (rc != NULL)
      93             :         {
      94           0 :             rc[n - 1] = round_fx(rc32); move16();
      95             :         }
      96             : 
      97             : /* Recompute LPC Coefficients up to n-1 */
      98           0 :         FOR (m = 1; m < n; m++)
      99             :         {
     100           0 :             lpc_tmp[m] = L_add(lpc[m], Mpy_32_32_lc3plus(rc32, lpc[n - m])); move32();
     101             :         }
     102             : 
     103           0 :         basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32));
     104             : 
     105             :         /* LPC Coefficient n */
     106           0 :         lpc[n] = L_shr_pos(rc32, 4); move32();
     107             :     }
     108             : 
     109             :     /* Final Prediction Error */
     110           0 :     IF (pred_err != NULL)
     111             :     {
     112           0 :         err       = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32)));
     113           0 :         *pred_err = L_shr(err, shift);
     114             :     }
     115             : 
     116             : #ifdef DYNMEM_COUNT
     117             :     Dyn_Mem_Out();
     118             : #endif
     119           0 : }
     120             : 
     121             : 
     122           0 : void lpc2rc(Word32 *lpc, Word16 *rc, Word16 N)
     123             : {
     124             :     Word32  lpc_tmp[MAXLAG + 1];
     125             :     Word32  rc32, tmp0, tmp1;
     126             :     Word16  inv;
     127             :     Counter n, m;
     128             : 
     129             : #ifdef DYNMEM_COUNT
     130             :     Dyn_Mem_In("lpc2rc", sizeof(struct {
     131             :                    Word32  lpc_tmp[MAXLAG + 1];
     132             :                    Word32  rc32, tmp0, tmp1;
     133             :                    Word16  inv;
     134             :                    Counter n, m;
     135             :                }));
     136             : #endif
     137             : 
     138           0 :     FOR (n = N; n >= 2; n--)
     139             :     {
     140           0 :         rc32      = L_shl_pos(lpc[n], 4);
     141           0 :         rc[n - 1] = round_fx(rc32); move16();
     142             : 
     143           0 :         tmp0 = L_sub(MAX_32, L_abs(Mpy_32_32_lc3plus(rc32, rc32)));
     144           0 :         FOR (m = 1; m < n; m++)
     145             :         {
     146           0 :             tmp1       = L_sub(lpc[m], Mpy_32_32_lc3plus(lpc[n - m], rc32));
     147           0 :             inv        = div_s(16383, extract_h(tmp0));
     148           0 :             lpc_tmp[m] = L_shl_pos(Mpy_32_32_lc3plus(tmp1, Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(tmp0, inv)), inv)), 2); move32();
     149             :         }
     150             : 
     151           0 :         basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32));
     152             :     }
     153             : 
     154           0 :     rc[0] = round_fx(L_shl_pos(lpc[1], 4)); move32();
     155             : 
     156             : #ifdef DYNMEM_COUNT
     157             :     Dyn_Mem_Out();
     158             : #endif
     159           0 : }
     160             : 

Generated by: LCOV version 1.14