LCOV - code coverage report
Current view: top level - lib_dec - pvq_decode_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 35 41 85.4 %
Date: 2025-08-23 01:22:27 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "prot_fx.h"
       8             : #include "rom_com.h"
       9             : 
      10             : /*-------------------------------------------------------------------*
      11             :  * Function pvq_decode_fx()                                             *
      12             :  *                                                                   *
      13             :  * PVQ subvector decoding algorithm                                  *
      14             :  *-------------------------------------------------------------------*/
      15             : 
      16      276160 : void pvq_decode_fx(
      17             :     Decoder_State *st_fx,
      18             :     PVQ_DEC_HANDLE hPVQ,  /* i/o: PVQ decoder handle */
      19             :     Word16 *xq,           /* o:   decoded vector (Q15)             */
      20             :     Word16 *y,            /* o:   decoded vector (non-scaled int)  */
      21             :     const Word16 k_val,   /* i:   number of allocated pulses       */
      22             :     const Word16 dim,     /* i:   Length of vector                 */
      23             :     const Word16 neg_gain /* i:   Gain    (negated to fit 1.0 in Q15 as -1.0)  */
      24             : )
      25             : {
      26             :     Word16 i;
      27             : 
      28             :     UWord32 h_mem[1 + KMAX_NON_DIRECT_FX + 1]; /* allocate max offset memory for dim  6 */
      29             : 
      30             :     PvqEntry entry;
      31             : 
      32             :     Word16 neg_gain_norm, shift_num, shift_den, shift_tot;
      33             :     Word32 L_yy, L_isqrt, L_tmp;
      34             : 
      35             :     UWord16 u16_tmp;
      36             : #ifndef ISSUE_1866_replace_overflow_libdec
      37             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      38             :     Flag Overflow = 0;
      39             :     move16();
      40             : #endif
      41             : #endif
      42             : 
      43      276160 :     entry = get_size_mpvq_calc_offset_fx( dim, k_val, h_mem ); /* get size & prepare H(adaptive table for entry.size=N_MPVQ(dim,k_val) */
      44             : 
      45             : 
      46      276160 :     IF( NE_16( dim, 1 ) )
      47             :     {
      48      276118 :         entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 );
      49      276118 :         entry.index = rc_dec_uniform_fx( st_fx, hPVQ, entry.size );
      50      276118 :         move16();
      51      276118 :         move32();
      52             : 
      53      276118 :         IF( st_fx->hHQ_core != NULL )
      54             :         {
      55             :             /* safety check in case of bit errors */
      56      275996 :             test();
      57      275996 :             IF( GE_32( entry.index, entry.size ) || st_fx->hHQ_core->ber_occured_in_pvq != 0 )
      58             :             {
      59           0 :                 st_fx->hHQ_core->ber_occured_in_pvq = 1;
      60           0 :                 move16();
      61           0 :                 st_fx->BER_detect = 1;
      62           0 :                 move16();
      63           0 :                 entry.index = 0;
      64           0 :                 move16(); /* a zero index will essentially disable PVQ index decompostion complexity */
      65             :             }
      66             :         }
      67             :     }
      68             :     ELSE
      69             :     {
      70          42 :         entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 ); /* always a single sign bit */
      71          42 :         entry.index = L_deposit_l( 0 );
      72          42 :         move16();
      73          42 :         move32();
      74             :     }
      75             : 
      76      276160 :     mpvq_decode_vec_fx( &entry, h_mem, y );
      77             : 
      78      276160 :     IF( neg_gain == 0 )
      79             :     {
      80        5614 :         FOR( i = 0; i < dim; i++ )
      81             :         {
      82        5210 :             xq[i] = 0;
      83        5210 :             move16();
      84             :         }
      85             :     }
      86             :     ELSE
      87             :     {
      88      275756 :         L_yy = L_deposit_l( 0 );
      89     3787412 :         FOR( i = 0; i < dim; i++ )
      90             :         {
      91     3511656 :             L_yy = L_mac( L_yy, y[i], y[i] ); /* Q1 */
      92             :         }
      93             : 
      94      275756 :         L_isqrt = Isqrt( L_shr( L_yy, 1 ) ); /*Q31*/ /* one single gain fac  as in flt not computed  for now */
      95             : 
      96      275756 :         shift_num = norm_s( k_val );                /* account for max possible pulseamp in y */
      97      275756 :         shift_den = norm_s( neg_gain );             /* account for downscaling shift         */
      98      275756 :         neg_gain_norm = shl( neg_gain, shift_den ); /* 10 db loss in minSNR without this in L_qx , at HQ128 FB*/
      99      275756 :         shift_tot = sub( add( shift_num, shift_den ), 15 );
     100             : 
     101      275756 :         L_isqrt = L_negate( L_isqrt );
     102     3787412 :         FOR( i = 0; i < dim; i++ )
     103             :         {
     104             :             /* upshifted y[i]  used    */
     105             : 
     106     3511656 :             Mpy_32_16_ss( L_isqrt, shl( y[i], shift_num ), &L_tmp, &u16_tmp ); /*  Q31*Q(0+x)  *2*/
     107     3511656 :             Mpy_32_16_ss( L_tmp, neg_gain_norm, &L_tmp, &u16_tmp );            /*  Q31*Q(0+x) *Q15 *2*/
     108             : #ifdef ISSUE_1866_replace_overflow_libdec
     109     3511656 :             L_tmp = L_shr_sat( L_tmp, shift_tot );
     110     3511656 :             xq[i] = round_fx_sat( L_tmp ); /* Q15 , array move   */
     111             : #else
     112             :             L_tmp = L_shr_o( L_tmp, shift_tot, &Overflow );
     113             :             xq[i] = round_fx_o( L_tmp, &Overflow ); /* Q15 , array move   */
     114             : #endif
     115     3511656 :             move16();
     116             :         }
     117             :     }
     118             : 
     119             : 
     120      276160 :     return;
     121             : }

Generated by: LCOV version 1.14