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 269600 : 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 :
37 269600 : 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) */
38 :
39 :
40 269600 : IF( NE_16( dim, 1 ) )
41 : {
42 269600 : entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 );
43 269600 : entry.index = rc_dec_uniform_fx( st_fx, hPVQ, entry.size );
44 269600 : move16();
45 269600 : move32();
46 :
47 269600 : IF( st_fx->hHQ_core != NULL )
48 : {
49 : /* safety check in case of bit errors */
50 269470 : test();
51 269470 : IF( GE_32( entry.index, entry.size ) || st_fx->hHQ_core->ber_occured_in_pvq != 0 )
52 : {
53 0 : st_fx->hHQ_core->ber_occured_in_pvq = 1;
54 0 : move16();
55 0 : st_fx->BER_detect = 1;
56 0 : move16();
57 0 : entry.index = 0;
58 0 : move16(); /* a zero index will essentially disable PVQ index decompostion complexity */
59 : }
60 : }
61 : }
62 : ELSE
63 : {
64 0 : entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 ); /* always a single sign bit */
65 0 : entry.index = L_deposit_l( 0 );
66 0 : move16();
67 0 : move32();
68 : }
69 :
70 269600 : mpvq_decode_vec_fx( &entry, h_mem, y );
71 :
72 269600 : IF( neg_gain == 0 )
73 : {
74 5610 : FOR( i = 0; i < dim; i++ )
75 : {
76 5206 : xq[i] = 0;
77 5206 : move16();
78 : }
79 : }
80 : ELSE
81 : {
82 269196 : L_yy = L_deposit_l( 0 );
83 3710120 : FOR( i = 0; i < dim; i++ )
84 : {
85 3440924 : L_yy = L_mac( L_yy, y[i], y[i] ); /* Q1 */
86 : }
87 :
88 269196 : L_isqrt = Isqrt( L_shr( L_yy, 1 ) ); /*Q31*/ /* one single gain fac as in flt not computed for now */
89 :
90 269196 : shift_num = norm_s( k_val ); /* account for max possible pulseamp in y */
91 269196 : shift_den = norm_s( neg_gain ); /* account for downscaling shift */
92 269196 : neg_gain_norm = shl( neg_gain, shift_den ); /* 10 db loss in minSNR without this in L_qx , at HQ128 FB*/
93 269196 : shift_tot = sub( add( shift_num, shift_den ), 15 );
94 :
95 269196 : L_isqrt = L_negate( L_isqrt );
96 3710120 : FOR( i = 0; i < dim; i++ )
97 : {
98 : /* upshifted y[i] used */
99 :
100 3440924 : Mpy_32_16_ss( L_isqrt, shl( y[i], shift_num ), &L_tmp, &u16_tmp ); /* Q31*Q(0+x) *2*/
101 3440924 : Mpy_32_16_ss( L_tmp, neg_gain_norm, &L_tmp, &u16_tmp ); /* Q31*Q(0+x) *Q15 *2*/
102 3440924 : L_tmp = L_shr_sat( L_tmp, shift_tot );
103 3440924 : xq[i] = round_fx_sat( L_tmp ); /* Q15 , array move */
104 3440924 : move16();
105 : }
106 : }
107 :
108 :
109 269600 : return;
110 : }
|