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 : static Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits);
13 :
14 : static Word16 ac_dec_split_st2VQ_CW( /* local BER flag */
15 : const Word32 L_cwRx, /* max 25 bits */
16 : const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB,
17 : Word16 *submodeLSB);
18 :
19 0 : void processDecoderEntropy_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits,
20 : Word16 L_spec, Word16 fs_idx, Word16 BW_cutoff_bits, Word16 *tns_numfilters,
21 : Word16 *lsbMode, Word16 *lastnz, Word16 *bfi, Word16 *tns_order, Word16 *fac_ns_idx,
22 : Word16 *gg_idx, Word16 *BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx,
23 : Word16 frame_dms)
24 : {
25 : Dyn_Mem_Deluxe_In(
26 : Word16 L, submodeLSB;
27 : Word32 tmp32, tmp32lim;
28 : Word16 gain_e, gain, submodeMSB, BER_detect;
29 : Word32 n;
30 : UWord8 *ptr;
31 : );
32 :
33 0 : ptr = bytes;
34 0 : *bp_side = shr_pos(sub(nbbits, 1), 3);
35 0 : *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3))));
36 :
37 : /* Cutoff-detection */
38 0 : IF (BW_cutoff_bits > 0)
39 : {
40 0 : *BW_cutoff_idx = read_indice(ptr, bp_side, mask_side, BW_cutoff_bits);
41 : /* check for bitflips */
42 0 : IF (sub(fs_idx, *BW_cutoff_idx) < 0)
43 : {
44 0 : *BW_cutoff_idx = fs_idx;
45 0 : *bfi = 1; move16();
46 : Dyn_Mem_Deluxe_Out();
47 0 : return;
48 : }
49 : }
50 : ELSE
51 : {
52 0 : *BW_cutoff_idx = fs_idx;
53 : }
54 :
55 : /* Number of TNS filters */
56 0 : IF (sub(*BW_cutoff_idx, 3) >= 0 && frame_dms >= 50)
57 : {
58 0 : *tns_numfilters = 2; move16();
59 : }
60 : ELSE
61 : {
62 0 : *tns_numfilters = 1; move16();
63 : }
64 :
65 : /* Decode number of ntuples */
66 0 : L = sub(14, norm_s(negate(L_spec)));
67 0 : n = read_indice(ptr, bp_side, mask_side, L);
68 0 : n = add(n, 1);
69 0 : *lastnz = shl_pos(n, 1);
70 0 : IF (sub(*lastnz, L_spec) > 0)
71 : {
72 0 : *bfi = 1; move16();
73 : Dyn_Mem_Deluxe_Out();
74 0 : return;
75 : }
76 :
77 : /* Mode bit */
78 0 : *lsbMode = read_bit(ptr, bp_side, mask_side);
79 :
80 : /* Decode global-gain */
81 0 : *gg_idx = read_indice(ptr, bp_side, mask_side, 8); move16();
82 0 : tmp32 = L_shl_pos(L_mult0(*gg_idx, 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
83 0 : gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); /* get exponent */
84 0 : gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000)));
85 0 : assert(gain >= 0); /* JSv, check if shr_pos(gain,1) is more appropriate) */
86 0 : gain = shr_r(gain, 1);
87 0 : gain_e = add(gain_e, 1);
88 :
89 : /* Decode TNS on/off flag */
90 0 : tns_order[1] = 0; move16(); /* fix problem with uninitialized memory */
91 0 : FOR (n = 0; n < *tns_numfilters; n++)
92 : {
93 0 : tns_order[n] = read_bit(ptr, bp_side, mask_side); move16();
94 : }
95 :
96 : /* LTPF on/off */
97 : #ifdef ENABLE_HR_MODE
98 0 : ltpf_idx[0] = read_bit(ptr, bp_side, mask_side); move16();
99 : #else
100 : ltpf_idx[0] = read_indice(ptr, bp_side, mask_side, 1); move16();
101 : #endif
102 :
103 : /* Decode SNS VQ parameters - 1st stage (10 bits) */
104 : #ifdef ENABLE_HR_MODE
105 0 : L = read_indice(ptr, bp_side, mask_side, 5 + 5);
106 0 : L_scf_idx[0] = L_deposit_l(s_and(L, 0x1F)); /* stage1 LF 5 bits */
107 0 : L_scf_idx[1] = L_deposit_l(shr_pos(L, 5)); /* stage1 HF 5 bits */
108 : #else
109 : L_scf_idx[0] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 LF 5 bits */
110 : L_scf_idx[1] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 HF 5 bits */
111 : #endif
112 :
113 : /* Decode SNS VQ parameters - 2nd stage side-info (3-4 bits) */
114 0 : submodeMSB = read_bit(ptr, bp_side, mask_side); /* submodeMSB 1 bit */
115 0 : L_scf_idx[2] = L_deposit_l(shl_pos(submodeMSB, 1));
116 0 : ASSERT(sns_gainMSBbits[L_scf_idx[2]] > 0);
117 0 : L_scf_idx[3] = L_deposit_l(
118 0 : read_indice(ptr, bp_side, mask_side, sns_gainMSBbits[L_scf_idx[2]])); /* gains or gain MSBs 1-2 bits */
119 0 : L_scf_idx[4] = read_bit(ptr, bp_side, mask_side); /* shape LS 1 bit */
120 :
121 : /* Decode SNS VQ parameters - 2nd stage data (24-25 bits) */
122 0 : IF (submodeMSB == 0)
123 : { /* shape_j = 0, or 1 */
124 : /* regular mode A,B indexes integer multiplexed, total 24.x bits MPVQ codeword section A and codeword for
125 : * section B */
126 : /* regular mode mode shape index total 24.9999 bits MPVQ codeword */
127 0 : tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 13));
128 0 : tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 13)); move16(); /*for ber state */
129 : BER_detect =
130 0 : ac_dec_split_st2VQ_CW( /* local BER flag */
131 : tmp32, /* L_cwRx max 25 bits */
132 0 : sns_MPVQ_Sz[0][0], UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* 12+2 = 14 */
133 : (&L_scf_idx[5]), /* shape A */
134 : (&L_scf_idx[6]), /* shape B or gain LSB */
135 : &submodeLSB /* total submode update below */
136 : );
137 0 : IF (submodeLSB != 0)
138 : { /* add gainLSB bit */
139 0 : L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_scf_idx[6]);
140 0 : L_scf_idx[6] = -2L;
141 : }
142 : }
143 : ELSE
144 : { /* shape_j = 2 or 3 */
145 0 : ASSERT(submodeMSB == 1);
146 : /* outlier mode shape index total 23.8536 + 19.5637 (19.5637 < (log2(2.^24 -2.^23.8537)) bits MPVQ
147 : * codeword */
148 0 : tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 12));
149 0 : tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 12));
150 0 : L_scf_idx[5] = tmp32; move32(); /*shape outl_near or outl_far */
151 0 : submodeLSB = 0; move16();
152 0 : BER_detect = 0; move16();
153 0 : tmp32lim = L_add(sns_MPVQ_Sz[2][0], L_shl_pos(sns_MPVQ_Sz[3][0], 1));
154 0 : IF (L_sub(tmp32, tmp32lim) >= 0)
155 : {
156 0 : BER_detect = 1; move16();
157 : }
158 : ELSE
159 : {
160 0 : tmp32 = L_sub(tmp32, sns_MPVQ_Sz[2][0]); /* a potential high index is computed */
161 0 : IF (tmp32 >= 0)
162 : {
163 0 : submodeLSB = 1; move16();
164 0 : ASSERT(tmp32 >= 0 && tmp32 < (Word32)(2 * sns_MPVQ_Sz[3][0]));
165 0 : L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_and(tmp32, 0x1)); /* add LSB_gain bit to gain MSBs */
166 0 : L_scf_idx[5] = L_shr_pos(tmp32, 1); /* MPVQ index with offset and gainLSB removed */
167 0 : L_scf_idx[6] = -2L; move32();
168 : }
169 : ELSE
170 : {
171 0 : L_scf_idx[6] = -1L; move32();
172 : }
173 : }
174 : }
175 0 : L_scf_idx[2] =
176 0 : L_add(L_scf_idx[2], L_deposit_l(submodeLSB)); /* decoder internal signal shape_j = submode 0..3 to VQ */
177 :
178 0 : IF (BER_detect > 0)
179 : {
180 0 : *bfi = 1; move16();
181 : Dyn_Mem_Deluxe_Out();
182 0 : return;
183 : }
184 :
185 : /* LTPF data */
186 0 : IF (ltpf_idx[0] != 0)
187 : {
188 : #ifdef ENABLE_HR_MODE
189 0 : L = read_indice(ptr, bp_side, mask_side, 1+9); move16();
190 0 : ltpf_idx[1] = s_and(L, 1); move16();
191 0 : ltpf_idx[2] = shr_pos(L, 1); move16();
192 : #else
193 : ltpf_idx[1] = read_indice(ptr, bp_side, mask_side, 1); move16();
194 : ltpf_idx[2] = read_indice(ptr, bp_side, mask_side, 9); move16();
195 :
196 : #endif
197 : }
198 : ELSE
199 : {
200 0 : ltpf_idx[1] = 0; move16();
201 0 : ltpf_idx[2] = 0; move16();
202 : }
203 :
204 : /* Decode noise-fac */
205 0 : *fac_ns_idx = read_indice(ptr, bp_side, mask_side, 3); move16();
206 :
207 : Dyn_Mem_Deluxe_Out();
208 : }
209 :
210 : #ifdef ENABLE_PADDING
211 0 : int paddingDec_fx(UWord8 *bytes, Word16 nbbits, Word16 L_spec, Word16 BW_cutoff_bits, Word16 ep_enabled,
212 : Word16 *total_padding, Word16 *np_zero)
213 : {
214 : Word16 lastnz_threshold;
215 : Word16 padding_len_bits, padding_len;
216 :
217 : Word16 bp_side;
218 0 : Word16 nbbytes = shr(nbbits,3);
219 :
220 : Word16 mask_side;
221 0 : UWord8 *ptr = bytes;
222 :
223 : Word16 lastnz;
224 0 : Word16 nbits = sub(14, norm_s(negate(L_spec)));
225 0 : if (sub(nbbits, nbits) < 0)
226 : {
227 0 : return 1;
228 : }
229 0 : *np_zero = 0;
230 :
231 0 : *total_padding = 0;
232 :
233 0 : bp_side = shr_pos(sub(nbbits, 1), 3);
234 0 : mask_side = shl(1, sub(8, sub(nbbits, shl_pos(bp_side, 3))));
235 :
236 0 : test();
237 0 : IF (sub(bp_side, 19) < 0 || sub(bp_side, LC3PLUS_MAX_BYTES ) >= 0) {
238 0 : return 1;
239 : }
240 :
241 0 : ptr = bytes;
242 :
243 0 : IF (BW_cutoff_bits > 0)
244 : {
245 0 : read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits);
246 0 : move16();
247 : }
248 :
249 0 : lastnz = read_indice(ptr, &bp_side, &mask_side, nbits);
250 0 : move16();
251 :
252 0 : lastnz_threshold = sub(shl(1, nbits), 2);
253 :
254 0 : WHILE (lastnz == lastnz_threshold)
255 : {
256 0 : padding_len_bits = sub(sub(12, nbits), BW_cutoff_bits);
257 :
258 : /*Read padding length*/
259 0 : padding_len = read_indice(ptr, &bp_side, &mask_side, padding_len_bits);
260 0 : move16();
261 :
262 : /* Read 4 reserved bits */
263 0 : read_indice(ptr, &bp_side, &mask_side, 4);
264 0 : move16();
265 :
266 0 : IF (ep_enabled == 0)
267 : {
268 : /* Discard padding length bytes */
269 0 : bp_side = sub(bp_side, padding_len);
270 0 : *total_padding = add(add(*total_padding, padding_len), 2); move16();
271 : }
272 : ELSE
273 : {
274 0 : *total_padding = add(*total_padding, 2); move16();
275 0 : *np_zero = add(*np_zero, padding_len); move16();
276 : }
277 :
278 : /* test if we have less than 20 bytes left; if so frame is broken */
279 0 : IF (sub(sub(nbbytes,add(*total_padding,*np_zero)),20) < 0) {
280 0 : return 1;
281 : }
282 :
283 : /* Read bandwidth bits */
284 0 : IF (BW_cutoff_bits > 0)
285 : {
286 0 : read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits);
287 0 : move16();
288 : }
289 :
290 0 : lastnz = read_indice(ptr, &bp_side, &mask_side, nbits);
291 0 : move16();
292 : }
293 :
294 0 : IF (ep_enabled != 0)
295 : {
296 0 : *total_padding = add(*total_padding, *np_zero); move16();
297 : }
298 0 : return 0;
299 : }
300 : #endif
301 :
302 0 : static __forceinline Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits)
303 : {
304 : Dyn_Mem_Deluxe_In(
305 : Word16 indice, bit;
306 : Counter i;
307 : );
308 :
309 0 : indice = read_bit(ptr, bp, mask);
310 :
311 0 : FOR (i = 1; i < numbits; i++)
312 : {
313 0 : bit = read_bit(ptr, bp, mask);
314 0 : indice = add(indice, lshl_pos(bit, i));
315 : }
316 :
317 : Dyn_Mem_Deluxe_Out();
318 0 : return indice;
319 : }
320 :
321 0 : static __forceinline Word16 ac_dec_split_st2VQ_CW( /* local BER flag */
322 : const Word32 L_cwRx, /* max 25 bits */
323 : const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB,
324 : Word16 *submodeLSB)
325 : {
326 : /* demultiplex: L_cwRx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */
327 : Word16 start, fin, ind;
328 : Word32 L_tmp, L_max_size;
329 : Counter i;
330 :
331 0 : L_max_size = (Word32)UL_Mpy_32_32((UWord32)L_szB, (UWord32)L_szA); /* may be tabled */
332 :
333 : /* section B ind larger than 13 out of the possible 14 = 0..13 */
334 0 : IF (L_sub(L_cwRx, L_max_size) >= 0)
335 : {
336 0 : *L_cwA = L_deposit_l(0);
337 0 : *L_cwB = L_deposit_l(0);
338 0 : *submodeLSB = 0; move16();
339 0 : return (Word16)1; /* set berFlag and exit */
340 : }
341 :
342 : /*initial binary split of cw, select top or low half */
343 0 : start = 0; move16();
344 :
345 0 : ASSERT((L_szB & 0x1L) == 0); /* this middle split only works if L_szB is even */
346 0 : if (L_sub(L_cwRx, L_shr_pos(L_max_size, 1)) >= 0)
347 : {
348 0 : start = L_shr_pos(L_szB, 1); /* top half start index */
349 : }
350 :
351 : /*linear loop over a low or a high section */
352 0 : ind = start; move16();
353 0 : L_tmp = L_negate(L_cwRx); /* search from negative side */
354 :
355 0 : L_tmp = L_add(L_tmp, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)start), (UWord32)L_szA));
356 : /* start is 0 or 7 */ /*non-fractional mult is (int)start * L_szA */
357 :
358 : /* a short linear run over ceil(szB/2) = 7 values */
359 :
360 0 : fin = add(start, shr_pos(L_szB, 1));
361 0 : FOR (i = start; i < fin; i++)
362 : {
363 0 : ind = add(ind, 1);
364 0 : L_tmp = L_add(L_tmp, L_szA);
365 0 : if (L_tmp > 0)
366 : {
367 0 : ind = sub(ind, 1); /* passed criteria point, keep index */
368 : }
369 : }
370 :
371 0 : *L_cwB = L_deposit_l(ind);
372 0 : *L_cwA = L_sub(L_cwRx, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)ind),
373 : (UWord32)L_szA)); /* non-fractional mult; (int)ind * L_szA */
374 :
375 0 : ASSERT(*L_cwA >= 0 && *L_cwA < L_szA);
376 0 : ASSERT(*L_cwB >= 0 && *L_cwB < L_szB);
377 :
378 0 : *submodeLSB = 0;
379 0 : *L_cwB = L_sub(*L_cwB, 2);
380 0 : if (*L_cwB < 0)
381 : {
382 0 : *submodeLSB = 1; move16();
383 : }
384 0 : *L_cwB = L_mac0(*L_cwB, 2, *submodeLSB); /* add back gain ind if needed */
385 :
386 0 : return 0; /* no BER */
387 : }
|