LCOV - code coverage report
Current view: top level - lib_lc3plus - pvq_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 34 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 3 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 : Word16 pvq_dec_deidx_fx(                          /* out BER detected 1 , ok==0 */
      13             :                         Word16 *      y,          /* o:   decoded vector (non-scaled int)  */
      14             :                         const Word16  k_val,      /* i:   number of allocated pulses       */
      15             :                         const Word16  dim,        /* i:   Length of vector                 */
      16             :                         const Word16  LS_ind,     /* i; lS index              1 bit        */
      17             :                         const UWord32 UL_MPVQ_ind /* i; MPVQ  index                        */
      18             : )
      19             : {
      20             :     Dyn_Mem_Deluxe_In(
      21             :         Word16      BER_flag;
      22             :         UWord32     h_mem[1 + KMAX_FX + 1];
      23             :         PvqEntry_fx entry;
      24             :     );
      25             : 
      26           0 :     BER_flag = 0; move16();
      27             : 
      28             :     /* get_size will likely be called before this function,     as the range decoder needs the size to fetch the index
      29             :      */
      30           0 :     entry = get_size_mpvq_calc_offset_fx(dim, k_val, h_mem); /* TBD should be made into tables for N=16,10,6  */
      31             : 
      32           0 :     entry.lead_sign_ind = LS_ind;         move16();
      33           0 :     entry.index         = L_deposit_l(0); /* only  in case dim == 1 */
      34           0 :     IF (sub(dim, 1) != 0)
      35             :     {
      36           0 :         entry.index = UL_MPVQ_ind;
      37             : 
      38             :         /* safety check in case of bit errors */
      39           0 :         IF (L_sub(entry.index, entry.size) >= 0)
      40             :         {
      41           0 :             BER_flag    = 1;            move16();
      42           0 :             entry.index = 0; move16(); /* return something deterministic/valid, and LOW complex  */
      43             :         }
      44             :     }
      45           0 :     mpvq_deindex_fx(&entry, h_mem, y); /* actual deindexing  */
      46             : 
      47             :     Dyn_Mem_Deluxe_Out();
      48           0 :     return BER_flag;
      49             : }
      50             : 
      51             : 
      52             : 
      53             : #ifdef ENABLE_HR_MODE
      54           0 : void pvq_dec_scale_vec_fx(const Word32 *inQ29, Word16 adjGainQ13, Word32 *outQ)
      55             : #else
      56             : void pvq_dec_scale_vec_fx(const Word16 *inQ14, Word16 adjGainQ13, Word16 *outQ14)
      57             : #endif
      58             : {
      59             :     Dyn_Mem_Deluxe_In(
      60             :         Counter i;
      61             :     );
      62           0 :     FOR (i = 0; i < M; i++)
      63             :     {
      64             : #ifdef ENABLE_HR_MODE
      65           0 :         outQ[i] = L_shr(L_add(outQ[i], Mpy_32_16_lc3plus(inQ29[i], adjGainQ13)), 1);
      66           0 :         move16();
      67             : #else
      68             :         outQ14[i] = add(outQ14[i], mult_r(adjGainQ13, inQ14[i])); move16();
      69             : #endif
      70             :     }
      71             :     Dyn_Mem_Deluxe_Out();
      72           0 : }
      73             : 
      74             : 
      75           0 : void pvq_dec_en1_normQ14_fx(/*  Have to be used EXACTLY the same way in both  both encoder and decoder */
      76             : #ifdef ENABLE_HR_MODE
      77             :                             Word32 *      xq, /* o:   en1 normalized decoded vector (Q14)   */
      78             : #else
      79             :                             Word16 *      xq, /* o:   en1 normalized decoded vector (Q14)   */
      80             : #endif
      81             :                             const Word16 *y,  /* i:   decoded vector (non-scaled int)  */
      82             :                             const Word16  k_val_max,
      83             :                             /* i:   max possible K   in Q0 kO or kA   */ /* OPT:  not BE , use dynamic max  pulse
      84             :                                                                             amplitude */
      85             :                             const Word16 dim                             /* i:   Length of vector                 */
      86             : )
      87             : {
      88             : #ifdef ENABLE_HR_MODE
      89             :     Dyn_Mem_Deluxe_In(
      90             :         Counter i;
      91             :         Word32  L_tmp;
      92             :         Word16  shift_num, shift_tot;
      93             :         Word32  isqrtQ31_local; 
      94             :         Word16  tmp, exp, exp_shift;
      95             :         Word32  L_yy;
      96             :     );
      97             : #else
      98             :     Dyn_Mem_Deluxe_In(
      99             :         Counter i;
     100             :         Word32  L_tmp;
     101             :         Word16  shift_num, shift_tot;
     102             :         Word16  isqrtQ16_local, tmp, exp, exp_shift;
     103             :         Word32  L_yy;
     104             :     );
     105             : #endif
     106             : 
     107             : /* energy normalization starts here */
     108           0 :     L_yy = L_mult0(y[0], y[0]);
     109           0 :     FOR (i = 1; i < dim; i++)
     110             :     {
     111           0 :         L_yy = L_mac0(L_yy, y[i], y[i]); /* stay in Q0 */ /* OPT: reuse some energies from PVQ linear search */
     112             :     }
     113             :     /* 16 bit */
     114           0 :     IF (L_sub(L_yy, SQRT_EN_MAX_FX) < 0)
     115             :     {
     116           0 :         ASSERT(L_yy > 4);                               /* Q16 isqrt table lookup not valid below  5  */
     117             : #ifdef ENABLE_HR_MODE
     118           0 :         isqrtQ31_local = isqrt_Q31tab[L_yy]; move16(); /* 1 cycle */
     119             : #else
     120             :         isqrtQ16_local = isqrt_Q16tab[L_yy]; move16(); /* 1 cycle */
     121             : #endif
     122             :     }
     123             :     ELSE
     124             :     {
     125             :         /* about 8-9 cycles */
     126           0 :         exp            = 15; move16(); /* set ISqrt16() exp_in to get delta exp out near 0  when Lyy is in Q0  */
     127           0 :         tmp            = ISqrt16(extract_l(L_yy),
     128             :                       &exp); /* exp  out is now a delta shift with a later tmp Q15 multiplication in mind  */
     129             : #ifdef ENABLE_HR_MODE
     130           0 :         exp_shift      = add(exp, 16);   /*  up to Q16 */
     131           0 :         isqrtQ31_local = L_shl(L_deposit_l(tmp), exp_shift); /* new mantissa in a fixed  Q16  */
     132             : #else
     133             :         exp_shift      = add(exp, 16 - 15);   /*  up to Q16 */
     134             :         isqrtQ16_local = shl(tmp, exp_shift); /* new mantissa in a fixed  Q16  */
     135             : #endif
     136             :     }
     137             : 
     138           0 :     shift_num = norm_s(k_val_max);      /* simply account for the preknown fixed max possible pulseamp in y */
     139           0 :     shift_tot = sub(14 - 1, shift_num); /* upshift  to get  to Q14 */
     140           0 :     FOR (i = 0; i < dim; i++) /*  upshifted y[i]  used    */
     141             :     {
     142             : #ifdef ENABLE_HR_MODE
     143           0 :         L_tmp = Mpy_32_16_lc3plus(isqrtQ31_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1    =   shift_num+1  */
     144           0 :         xq[i] = L_shl(L_tmp, shift_tot + 1); move32();     /* Q30 ,      */
     145             : #else
     146             :         L_tmp = L_mult(isqrtQ16_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1    =   shift_num+1  */
     147             :         xq[i] = round_fx(L_shl(L_tmp, shift_tot)); move16();     /* Q14 ,      */
     148             : #endif
     149             :     }
     150             : 
     151             :     Dyn_Mem_Deluxe_Out();
     152           0 : }
     153             : 

Generated by: LCOV version 1.14