Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.6.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 "options.h"
11 : #include "wmc_auto.h"
12 : #include "functions.h"
13 :
14 : #ifdef CR9_C_ADD_1p25MS_LRSNS
15 :
16 : static LC3_INT16 get_lead_sign( LC3_UINT32* ind_in );
17 : static void mind2vec_one( LC3_UINT8 k_val_in, LC3_INT16 leading_sign, LC3_INT32* vec_out );
18 :
19 0 : LC3_INT16 get_lead_sign( LC3_UINT32* ind_in )
20 : {
21 : LC3_INT16 leading_sign;
22 0 : leading_sign = +1;
23 0 : if ( ( ( *ind_in ) & 0x1 ) != 0 )
24 : {
25 0 : leading_sign = -1;
26 : }
27 0 : ( *ind_in ) = ( *ind_in >> 1 );
28 :
29 0 : return leading_sign;
30 : }
31 :
32 0 : void mind2vec_one( LC3_UINT8 k_val_in, /* i: nb unit pulses */
33 : LC3_INT16 leading_sign, /* i: leading sign -1, 1 */
34 : LC3_INT32* vec_out /* o: updated pulse train */ )
35 : {
36 : LC3_INT32 amp;
37 0 : amp = k_val_in;
38 0 : if ( leading_sign < 0 )
39 : {
40 0 : amp = -k_val_in;
41 : }
42 0 : *vec_out = amp;
43 0 : }
44 :
45 : static LC3_UINT8 setval_update_sign( LC3_INT16 k_delta, LC3_UINT8 k_max_local_in, LC3_INT16* leading_sign, LC3_UINT32* ind_in, LC3_INT32* vec_out );
46 :
47 : static void mind2vec_tab( LC3_UINT8 dim_in, LC3_UINT8 k_max_local, LC3_INT16 leading_sign, LC3_UINT32 ind, LC3_INT32* vec_out );
48 :
49 : #endif
50 :
51 : #ifdef CR9_C_ADD_1p25MS_LRSNS
52 : static void MPVQdeenum( LC3_UINT8 dim_in, LC3_UINT8 k_val_in, LC3_INT32 LS_ind, LC3_INT32 MPVQ_ind, LC3_INT32* vec_out );
53 : #endif
54 :
55 : #ifdef CR9_C_ADD_1p25MS_LRSNS
56 :
57 0 : LC3_UINT8 setval_update_sign( LC3_INT16 k_delta, /* i */
58 : LC3_UINT8 k_max_local_in, /* i */
59 : LC3_INT16* leading_sign, /* i/o */
60 : LC3_UINT32* ind_in, /* i/o */
61 : LC3_INT32* vec_out /* i/o */ )
62 : {
63 : LC3_UINT8 k_max_local_out;
64 0 : k_max_local_out = k_max_local_in;
65 0 : if ( k_delta != 0 )
66 : {
67 0 : mind2vec_one( k_delta, *leading_sign, vec_out );
68 0 : *leading_sign = get_lead_sign( ind_in );
69 0 : k_max_local_out -= k_delta;
70 : }
71 :
72 0 : return k_max_local_out;
73 : }
74 :
75 : #endif
76 :
77 : #ifdef CR9_C_ADD_1p25MS_LRSNS
78 :
79 0 : void mind2vec_tab( LC3_UINT8 dim_in, /* i: dimension */
80 : LC3_UINT8 k_max_local, /* i: nb unit pulses */
81 : LC3_INT16 leading_sign, /* i: leading sign */
82 : LC3_UINT32 ind, /* i: MPVQ-index */
83 : LC3_INT32* vec_out /* o: pulse train */ )
84 : {
85 : /* pvq_enc_A = MPVQ_offsets */
86 : LC3_UINT8 pos, k_acc;
87 : LC3_UINT32 UL_tmp_offset;
88 : LC3_INT32 UL_diff;
89 : LC3_INT16 wrap_flag, k_delta;
90 : const LC3_UINT32* h_row_ptr;
91 : /* init */
92 0 : h_row_ptr = &( pvq_enc_A[( dim_in - 1 )][0] );
93 0 : k_acc = k_max_local;
94 :
95 : /* loop over positions */
96 0 : for ( pos = 0; pos < dim_in; pos++ )
97 : {
98 0 : if ( ind != 0 )
99 : {
100 0 : k_acc = k_max_local;
101 0 : UL_tmp_offset = h_row_ptr[k_acc];
102 :
103 0 : wrap_flag = ( ind < UL_tmp_offset );
104 0 : UL_diff = (LC3_INT32) ( (LC3_INT32) ind - (LC3_INT32) UL_tmp_offset );
105 :
106 0 : while ( wrap_flag != 0 )
107 : {
108 0 : k_acc--;
109 0 : wrap_flag = ( ind < h_row_ptr[k_acc] );
110 0 : UL_diff = (LC3_INT32) ( (LC3_INT32) ind - (LC3_INT32) h_row_ptr[k_acc] );
111 : }
112 0 : ind = UL_diff;
113 0 : k_delta = k_max_local - k_acc;
114 : }
115 : else
116 : {
117 0 : mind2vec_one( k_max_local, leading_sign, &vec_out[pos] );
118 0 : break;
119 : }
120 0 : k_max_local = setval_update_sign( k_delta, k_max_local, &leading_sign, &ind, &vec_out[pos] );
121 0 : h_row_ptr -= 11; /* reduce dimension in MPVQ_offsets table */
122 : }
123 0 : }
124 :
125 : #endif
126 :
127 : #ifdef CR9_C_ADD_1p25MS_LRSNS
128 :
129 0 : void MPVQdeenum( LC3_UINT8 dim_in, /* i : dimension of vec_out */
130 : LC3_UINT8 k_val_in, /* i : number of unit pulses */
131 : LC3_INT32 LS_ind, /* i : leading sign index */
132 : LC3_INT32 MPVQ_ind, /* i : MPVQ shape index */
133 : LC3_INT32* vec_out /* o : PVQ integer pulse train */ )
134 : {
135 : LC3_INT32 leading_sign;
136 :
137 :
138 0 : leading_sign = 1;
139 0 : if ( LS_ind != 0 )
140 : {
141 0 : leading_sign = -1;
142 : }
143 :
144 0 : mind2vec_tab( dim_in, k_val_in, leading_sign, MPVQ_ind, vec_out );
145 0 : }
146 :
147 : /* local funcs*/
148 :
149 : static void FESSdeenum(LC3_UINT8 dim_in, /* i : dimension of vec_out */
150 : LC3_UINT8 n_env, /* i : number envelopes */
151 : LC3_UINT8 n_shift, /* i : number shifts */
152 : LC3_UINT8 n_signs, /* i : number signs */
153 : LC3_INT32 env_ind, /* i:indx */
154 : LC3_INT32 shift_ind, /* i:indx */
155 : LC3_INT32 sign_ind, /* i:indx */
156 : LC3_INT32* vec_out /* o : FESS integer pulse train */);
157 :
158 : LC3_INT32 snsQuantScfEncLRSt1ABC(LC3_FLOAT* env, LC3_INT32* L_index, LC3_FLOAT *min_mse_saveBCA_ptr,
159 : LC3_INT32* ind_saveB_ptr, LC3_FLOAT* st1_vectors,
160 : LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx);
161 :
162 : #endif /* CR9_C_ADD_1p25MS_LRSNS*/
163 :
164 : static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses);
165 : static LC3_INT find_last_indice_le(LC3_INT compare, const LC3_UINT32* array, LC3_INT len);
166 : static void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len);
167 :
168 1181012 : void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len)
169 : {
170 : LC3_INT i;
171 : LC3_FLOAT norm1, sum;
172 :
173 1181012 : norm1 = 0.353553390593274; /* sqrt(2 / 16) */
174 :
175 20077204 : for (i = 0; i < len; i++) {
176 18896192 : sum = mac_loop(in, idct_lookup[i], len);
177 18896192 : out[i] = norm1 * sum;
178 : }
179 1181012 : }
180 :
181 : #ifdef FIX_FLOAT_ENC_PVQ_PULSE_LOOP
182 : static LC3_INT32 pvq_pulse_search_lc(LC3_FLOAT* xabs, LC3_FLOAT* ener, LC3_FLOAT* corr, LC3_INT32* y, LC3_INT32 start, LC3_INT32 end)
183 : {
184 : Dyn_Mem_Deluxe_In(
185 : LC3_INT32 i;
186 : LC3_INT32 nBest;
187 : LC3_FLOAT max_norm_ratio, cand_norm_ratio;
188 : LC3_FLOAT currCorr;
189 : LC3_INT32 currEnInt;
190 : const LC3_FLOAT* isqrt_QxTab;
191 : );
192 :
193 : const LC3_INT16 isqrt_Q16tab[1 + 64] = { /* table generated using ISqrt16 function + shift to Q16 */
194 : 32767, 32767, 32767, 32767, 32766, 29308, 26754, 24770, 23169, 21844,
195 : 20723, 19759, 18918, 18176, 17515, 16921, 16383, 15894, 15446, 15034,
196 : 14654, 14300, 13972, 13665, 13377, 13107, 12852, 12612, 12385, 12169,
197 : 11965, 11770, 11584, 11407, 11238, 11077, 10922, 10773, 10631, 10493,
198 : 10361, 10234, 10112, 9993, 9879, 9769, 9662, 9559, 9459, 9362,
199 : 9268, 9176, 9088, 9001, 8918, 8836, 8757, 8680, 8605, 8532,
200 : 8460, 8390, 8323, 8256, 8191
201 : };
202 : LC3_FLOAT isqrt_Q16tabFlt[1 + 64];
203 :
204 : const LC3_INT16 isqrt_Q15tab[1 + 6] = {
205 : /* onepulse_search_tab based search , Q15 table generated using isqrt_Q16tab table for idx=[8(4*2),16(4*4), 20(4*5),24(4*6) ] */
206 : /* this slighly suboptimal inv_sqrt(x) table is used to enable optional exact use of the ROM saving BASOP ISqrt16() function */
207 :
208 : 32767/*0*/, 32766/*1*/, 23169 /*2*/, 18918 /*3*/ , 16384/*4*/ , 14654 /*5*/, 13377/*6*/
209 : /* i.e. value in isqrt_Q15tab[n=0..6] == isqrt_Q16tab[4*n] */
210 : };
211 : LC3_FLOAT isqrt_Q15tabFlt[1 + 6];
212 :
213 : for ( i = 0; i <= 64; i++ )
214 : {
215 : isqrt_Q16tabFlt[i] = isqrt_Q16tab[i] / 65536.0;
216 : }
217 : for (i = 0; i <= 6; i++)
218 : {
219 : isqrt_Q15tabFlt[i] = isqrt_Q15tab[i] / 32768.0;
220 : }
221 :
222 :
223 : isqrt_QxTab = isqrt_Q16tabFlt; /* Q16 table valid for energies 4...64 */
224 :
225 : assert( *ener >= 0.0 );
226 : *ener += 1.0; /* Added once for the entire loop */
227 : if (*ener <= 3.0 ) /* +1 for the inloop value of *ener was preadded before */
228 : {
229 : isqrt_QxTab = isqrt_Q15tabFlt; /* energies: 1...6 */
230 : }
231 :
232 : nBest = -1;
233 : max_norm_ratio = -1.0;
234 : /* Iterative max search using tabulated inv sqrt */
235 : for ( i = start; i < end; i++)
236 : {
237 : currCorr = *corr + xabs[i];
238 : currEnInt = ((LC3_INT32) *ener) + (2 * y[i]);
239 :
240 : cand_norm_ratio = currCorr * isqrt_QxTab[currEnInt];
241 :
242 : if ( cand_norm_ratio >= max_norm_ratio )
243 : {
244 : nBest = i;
245 : }
246 : max_norm_ratio = LC3_FMAX(max_norm_ratio, cand_norm_ratio); /* always update */
247 : }
248 :
249 : *corr += xabs[nBest];
250 : *ener += (2 * y[nBest]);
251 :
252 : assert(nBest >= 0);
253 : assert(nBest <=M);
254 : assert(*ener <= 64.0);
255 : y[nBest] += 1; /* Add the selected unit pulse */
256 :
257 : Dyn_Mem_Deluxe_Out();
258 : return nBest;
259 : }
260 : #endif
261 :
262 7387957 : static LC3_INT pvq_pulse_search(LC3_FLOAT *xabs, LC3_FLOAT *ener, LC3_FLOAT *corr, LC3_INT *y, LC3_INT start, LC3_INT end)
263 : {
264 : LC3_INT i;
265 : LC3_INT nBest;
266 : LC3_FLOAT bestCorrSq, bestEn;
267 : LC3_FLOAT corrSq, currCorr, currEn;
268 :
269 7387957 : nBest = 0;
270 7387957 : bestCorrSq = 0.0;
271 7387957 : bestEn = 0.0;
272 :
273 7387957 : *ener += 1; /* Added once for the entire loop */
274 :
275 7387957 : i = start;
276 :
277 7387957 : currCorr = *corr + xabs[i];
278 7387957 : currEn = *ener + (2 * y[i]);
279 :
280 7387957 : corrSq = currCorr * currCorr;
281 :
282 7387957 : bestEn = currEn;
283 7387957 : bestCorrSq = corrSq;
284 7387957 : nBest = i;
285 :
286 : /* Iterative max search as recommended in the spec */
287 106299685 : for (; i < end; i++)
288 : {
289 98911728 : currCorr = *corr + xabs[i];
290 98911728 : currEn = *ener + (2 * y[i]);
291 :
292 98911728 : corrSq = currCorr * currCorr;
293 :
294 98911728 : if ((corrSq * bestEn) > (bestCorrSq * currEn))
295 : {
296 15023366 : bestEn = currEn;
297 15023366 : bestCorrSq = corrSq;
298 15023366 : nBest = i;
299 : }
300 : }
301 :
302 7387957 : *corr += xabs[nBest];
303 7387957 : *ener += (2 * y[nBest]);
304 :
305 7387957 : y[nBest] += 1; /* Add the selected unit pulse */
306 :
307 7387957 : return nBest;
308 : }
309 :
310 2362024 : static void pvq_enc_vec_normalize(LC3_FLOAT *vec, LC3_INT N)
311 : {
312 2362024 : LC3_FLOAT mag = 0.0, norm_fac;
313 : LC3_INT i;
314 :
315 40154408 : for (i = 0; i < N; i++)
316 : {
317 37792384 : mag += (vec[i] * vec[i]);
318 : }
319 :
320 2362024 : norm_fac = 1.0 / LC3_SQRT(mag);
321 :
322 40154408 : for (i = 0; i < N; i++)
323 : {
324 37792384 : vec[i] = vec[i] * norm_fac;
325 : }
326 :
327 2362024 : return;
328 : }
329 :
330 590506 : static void pvq_enc_search(LC3_FLOAT* x_in, LC3_INT y[4][M])
331 : {
332 : LC3_INT i, N, K, pulse_total, N_setA;
333 : LC3_FLOAT abs_sum, projfac;
334 : LC3_FLOAT xabs[16];
335 : LC3_FLOAT yy, xy;
336 :
337 590506 : abs_sum = 0.0;
338 :
339 : /* Step 1 : Projection to pyramid N=16, K=6 */
340 590506 : N = 16;
341 590506 : K = 6;
342 590506 : pulse_total = 0;
343 590506 : N_setA = 10;
344 :
345 590506 : yy = xy = 0.0f;
346 :
347 10038602 : for (i = 0; i < N; i++)
348 : {
349 9448096 : xabs[i] = LC3_FABS(x_in[i]);
350 9448096 : abs_sum += xabs[i];
351 : }
352 :
353 590506 : projfac = (K - 1) / abs_sum;
354 :
355 10038602 : for (i = 0; i < N; i++)
356 : {
357 9448096 : y[3][i] = floor(xabs[i] * projfac);
358 :
359 9448096 : pulse_total += y[3][i];
360 :
361 9448096 : yy += (y[3][i] * y[3][i]);
362 9448096 : xy += (xabs[i] * y[3][i]);
363 : }
364 :
365 : /* Step 2: Adding unit pulses up to K = 6 */
366 3975191 : for (; pulse_total < K; pulse_total++)
367 : {
368 3384685 : pvq_pulse_search(xabs, &yy, &xy, y[3], 0, N);
369 : }
370 :
371 : /* Step 3: Adding unit pulses up to K = 8 */
372 590506 : memcpy(y[2], y[3], sizeof(LC3_INT)*N);
373 590506 : K = 8;
374 :
375 1771518 : for (; pulse_total < K; pulse_total++)
376 : {
377 1181012 : pvq_pulse_search(xabs, &yy, &xy, y[2], 0, N);
378 : }
379 :
380 590506 : memcpy(y[1], y[2], sizeof(LC3_INT)*N_setA);
381 :
382 : /* Step 4: Remove unit pulses not belonging to set A */
383 4133542 : for (i = N_setA; i < N; i++)
384 : {
385 3543036 : y[1][i] = 0;
386 : }
387 :
388 : /* Step 5: Update yy and xy terms to reflect y1 */
389 590506 : yy = 0;
390 590506 : xy = 0;
391 590506 : pulse_total = 0;
392 :
393 6495566 : for (i = 0; i < N_setA; i++)
394 : {
395 5905060 : yy += (y[1][i] * y[1][i]);
396 5905060 : xy += (xabs[i] * y[1][i]);
397 :
398 5905060 : pulse_total += y[1][i];
399 : }
400 :
401 : /* Step 6: Add unit pulses until K = 10 over N = 10 */
402 590506 : K = 10;
403 2822260 : for (; pulse_total < K; pulse_total++)
404 : {
405 2231754 : pvq_pulse_search(xabs, &yy, &xy, y[1], 0, N_setA);
406 : }
407 :
408 590506 : memcpy(y[0], y[1], sizeof(LC3_INT)*N);
409 :
410 : /* Step 7: Add unit pulses until K = 1 over N = 6 in set B*/
411 590506 : pvq_pulse_search(xabs, &yy, &xy, y[0], N_setA, N);
412 :
413 : /* Step 8: Add signs to each of the 4 vectors from x */
414 10038602 : for (i = 0; i < N; i++)
415 : {
416 9448096 : if (x_in[i] < 0)
417 : {
418 4605166 : y[0][i] = -y[0][i];
419 4605166 : y[1][i] = -y[1][i];
420 4605166 : y[2][i] = -y[2][i];
421 4605166 : y[3][i] = -y[3][i];
422 : }
423 : }
424 :
425 590506 : return;
426 : }
427 :
428 10629108 : static LC3_FLOAT calc_mse(LC3_FLOAT *t2rot, LC3_FLOAT *y, LC3_FLOAT gain, LC3_INT N)
429 : {
430 : LC3_FLOAT mse;
431 : LC3_INT i;
432 :
433 10629108 : mse = 0.0;
434 :
435 180694836 : for (i = 0; i < N; i++)
436 : {
437 170065728 : LC3_FLOAT err = (t2rot[i] - gain * y[i]);
438 170065728 : mse += (err * err);
439 : }
440 :
441 10629108 : return mse;
442 : }
443 :
444 590506 : static void sns_quant_adj_gain_shape_search(LC3_FLOAT *t2rot, LC3_INT y[4][M] ,
445 : LC3_INT *gain_idx, LC3_INT *shape_idx, LC3_FLOAT *y_norm, LC3_FLOAT *scq_gain)
446 : {
447 : LC3_INT gidx, sidx;
448 : LC3_FLOAT min_mse, mse;
449 : LC3_INT N;
450 : LC3_FLOAT yCur[4][16];
451 : LC3_INT i;
452 :
453 590506 : const LC3_INT gain_levels[4] = { 2, 4, 4, 8 };
454 590506 : const LC3_FLOAT *sns_vq_gains[4] = { sns_vq_reg_adj_gains_fl , sns_vq_reg_lf_adj_gains_fl ,
455 : sns_vq_near_adj_gains_fl , sns_vq_far_adj_gains_fl };
456 :
457 590506 : min_mse = -1.0;
458 590506 : N = 16;
459 :
460 :
461 590506 : *gain_idx = *shape_idx = 0;
462 :
463 2952530 : for (sidx = 0; sidx < 4; sidx++)
464 : {
465 40154408 : for (i = 0; i < N; i++)
466 : {
467 37792384 : yCur[sidx][i] = (LC3_FLOAT)y[sidx][i];
468 : }
469 :
470 : /* Step 9: Normalize the vectors */
471 2362024 : pvq_enc_vec_normalize(yCur[sidx], N);
472 :
473 12991132 : for (gidx = 0; gidx < gain_levels[sidx]; gidx++)
474 : {
475 10629108 : mse = calc_mse(t2rot, yCur[sidx], sns_vq_gains[sidx][gidx], N);
476 :
477 10629108 : if ((mse < min_mse) || (min_mse < 0))
478 : {
479 1231707 : *gain_idx = gidx;
480 1231707 : *shape_idx = sidx;
481 1231707 : min_mse = mse;
482 : }
483 : }
484 : }
485 :
486 10038602 : for (i = 0; i < N; i++)
487 : {
488 9448096 : y_norm[i] = yCur[*shape_idx][i];
489 : }
490 :
491 590506 : *scq_gain = sns_vq_gains[*shape_idx][*gain_idx];
492 :
493 590506 : return;
494 : }
495 :
496 9353164 : static void enc_push_sign(LC3_FLOAT val, LC3_UINT32 *next_sign_ind, LC3_INT *index)
497 : {
498 9353164 : if (((*next_sign_ind & 0x80000000U) == 0) && (val != 0)) {
499 3580664 : *index = 2 * (*index) + *next_sign_ind;
500 : }
501 9353164 : if (val < 0) {
502 2126458 : *next_sign_ind = 1;
503 : }
504 9353164 : if (val > 0) {
505 2314397 : *next_sign_ind = 0;
506 : }
507 :
508 9353164 : return;
509 : }
510 :
511 860191 : static void MPVQ_enum(LC3_INT dim, LC3_INT *sns_vec, LC3_INT *index_val, LC3_INT *lead_sign_ind)
512 : {
513 : LC3_UINT32 next_sign_ind;
514 : LC3_INT k_val_acc;
515 : LC3_INT pos;
516 : LC3_INT index, n;
517 : LC3_INT const *row_ptr;
518 :
519 : /* MPVQ-index composition loop */
520 : LC3_INT tmp_h_row;
521 : LC3_INT tmp_val;
522 :
523 860191 : next_sign_ind = 0x80000000U;
524 860191 : k_val_acc = 0;
525 860191 : pos = dim;
526 860191 : index = 0;
527 860191 : n = 0;
528 :
529 860191 : row_ptr = (LC3_INT const *)&(pvq_enc_A[n]);
530 860191 : tmp_h_row = row_ptr[0];
531 :
532 10213355 : for (pos--; pos >= 0; pos--)
533 : {
534 9353164 : tmp_val = sns_vec[pos];
535 9353164 : enc_push_sign(tmp_val, &next_sign_ind, &index);
536 :
537 9353164 : index += tmp_h_row;
538 9353164 : k_val_acc += abs(tmp_val);
539 9353164 : if (pos != 0) {
540 8492973 : n += 1; /* switch row in offset table MPVQ_offsets(n, k) */
541 : }
542 9353164 : row_ptr = (LC3_INT const *)&(pvq_enc_A[n]);
543 :
544 9353164 : tmp_h_row = row_ptr[k_val_acc];
545 : }
546 :
547 860191 : *index_val = index;
548 860191 : *lead_sign_ind = next_sign_ind;
549 :
550 860191 : return;
551 : }
552 :
553 1181012 : static LC3_INT MSEsearch (LC3_FLOAT *scf, const LC3_FLOAT sns_CB[8][32])
554 : {
555 : LC3_FLOAT distance, mse;
556 : LC3_INT i, n, ind;
557 :
558 1181012 : ind = 0;
559 :
560 1181012 : distance = (LC3_FLOAT) LC3_CONST_POW_2_100;
561 38973396 : for (i = 0; i < 32; i++) {
562 37792384 : mse = 0;
563 340131456 : for (n = 0; n < 8; n++) {
564 302339072 : mse += (scf[n] - sns_CB[n][i]) * (scf[n] - sns_CB[n][i]);
565 : }
566 :
567 37792384 : if (mse < distance) {
568 4846883 : distance = mse;
569 4846883 : ind = i;
570 : }
571 : }
572 1181012 : return ind;
573 : }
574 :
575 590506 : void process_snsQuantizesScf_Enc(LC3_FLOAT* env, LC3_INT* index, LC3_FLOAT* envq, Dct2 dct2structSNS)
576 : {
577 : LC3_FLOAT stage2_en1_norm_sub[M];
578 : LC3_INT i, j;
579 : LC3_FLOAT st1_vector[M];
580 : LC3_FLOAT pvq_target_pre[M];
581 : LC3_FLOAT pvq_target[M];
582 : LC3_FLOAT stage2_en1_norm_pre_sub[M];
583 : LC3_INT gain, shape;
584 : LC3_FLOAT scfq_gain;
585 : LC3_INT y[4][M];
586 :
587 : /* Stage 1 split VQ */
588 590506 : index[0] = MSEsearch(&env[0], sns_LFCB); /* ind_LF */
589 590506 : index[1] = MSEsearch(&env[8], sns_HFCB); /* ind_HF */
590 :
591 590506 : j = 8;
592 5314554 : for (i = 0; i < 8; i++, j++) {
593 4724048 : st1_vector[i] = sns_LFCB[i][index[0]];
594 4724048 : st1_vector[j] = sns_HFCB[i][index[1]];
595 : }
596 :
597 : /* STAGE 2 */
598 10038602 : for (i = 0; i < 16; i++) {
599 9448096 : pvq_target_pre[i] = env[i] - st1_vector[i];
600 : }
601 :
602 590506 : dct2_apply(&dct2structSNS, pvq_target_pre, pvq_target);
603 590506 : pvq_enc_search(pvq_target, y);
604 590506 : sns_quant_adj_gain_shape_search(pvq_target, y, &gain, &shape, stage2_en1_norm_pre_sub, &scfq_gain);
605 :
606 : /* Inverse transform */
607 590506 : idct_II(stage2_en1_norm_pre_sub, stage2_en1_norm_sub, M);
608 :
609 590506 : index[2] = shape;
610 590506 : index[3] = gain;
611 :
612 590506 : if (shape < 2) {
613 285507 : MPVQ_enum(10, y[shape], &index[5], &index[4]);
614 : }
615 : else {
616 304999 : MPVQ_enum(M, y[shape], &index[5], &index[4]);
617 : }
618 :
619 590506 : if (shape == 0) {
620 : LC3_INT ls_ind, ind;
621 269685 : MPVQ_enum(6, &y[shape][10], &ind, &ls_ind);
622 269685 : index[6] = ind * 2 + ls_ind;
623 : }
624 320821 : else if (shape == 2) {
625 293724 : index[6] = -1;
626 : }
627 : else {
628 27097 : index[6] = -2;
629 : }
630 :
631 10038602 : for (i = 0; i < M; i++) {
632 9448096 : envq[i] = st1_vector[i] + (stage2_en1_norm_sub[i] * scfq_gain);
633 : }
634 590506 : }
635 :
636 6990963 : LC3_INT find_last_indice_le(LC3_INT compare, const LC3_UINT32* array, LC3_INT len)
637 : {
638 6990963 : LC3_INT idx = 0, i = 0;
639 :
640 47551324 : for (i = 0; i < len; i++) {
641 40560361 : if ((LC3_UINT32)compare >= array[i]) {
642 35963104 : idx++;
643 : }
644 : }
645 :
646 6990963 : if (idx > 0) {
647 6990963 : idx--;
648 : }
649 :
650 6990963 : return idx;
651 : }
652 :
653 860191 : void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses)
654 : {
655 860191 : LC3_INT leading_sign, idx, k_delta = 0, pos;
656 :
657 860191 : leading_sign = 1 - 2 * LS_ind;
658 :
659 : /* Decoding loop */
660 :
661 7851154 : for (pos = 0; pos < m; pos++) {
662 7851154 : if (MPVQ_ind != 0) {
663 : /* Find last indice */
664 6990963 : idx = find_last_indice_le(MPVQ_ind, &pvq_enc_A[m - pos - 1][0], k + 1);
665 6990963 : MPVQ_ind = MPVQ_ind - pvq_enc_A[m - pos - 1][idx];
666 6990963 : k_delta = k - idx;
667 : } else {
668 860191 : pulses[pos] = leading_sign * k;
669 860191 : break;
670 : }
671 :
672 6990963 : if (k_delta != 0) {
673 3580664 : pulses[pos] = leading_sign * k_delta;
674 3580664 : if ((MPVQ_ind % 2) != 0) {
675 1718953 : leading_sign = -1;
676 : } else {
677 1861711 : leading_sign = 1;
678 : }
679 :
680 3580664 : MPVQ_ind = floor(MPVQ_ind / 2);
681 3580664 : k = k - k_delta;
682 : }
683 : }
684 860191 : }
685 :
686 590506 : void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q)
687 : {
688 : LC3_INT i, submode;
689 590506 : LC3_INT pulses2[6] = {0}, pulses[M] = {0};
690 590506 : LC3_FLOAT st2_vector[M], st2_vector_idct[M], sum = 0;
691 :
692 : /* Decode first stage */
693 :
694 5314554 : for (i = 0; i < 8; i++) {
695 4724048 : scf_q[i] = sns_LFCB[i][scf_idx[0]];
696 4724048 : scf_q[i + 8] = sns_HFCB[i][scf_idx[1]];
697 : }
698 :
699 : /* STAGE 2 */
700 : /* Decode submode */
701 :
702 590506 : submode = scf_idx[2];
703 :
704 : /* Decode pulses */
705 :
706 590506 : if (submode < 2) {
707 285507 : pvq_dec(10, 10, scf_idx[4], scf_idx[5], pulses);
708 :
709 285507 : if (submode == 0) {
710 269685 : pvq_dec(1, 6, (scf_idx[6] % 2), floor(scf_idx[6] / 2), pulses2);
711 :
712 269685 : move_int(&pulses[10], pulses2, 6);
713 :
714 : } else {
715 15822 : pulses[15] = 0;
716 : }
717 304999 : } else if (submode == 2) {
718 293724 : pvq_dec(8, 16, scf_idx[4], scf_idx[5], pulses);
719 : } else {
720 11275 : pvq_dec(6, 16, scf_idx[4], scf_idx[5], pulses);
721 : }
722 :
723 : /* Normalization */
724 :
725 10038602 : for (i = 0; i < M; i++) {
726 9448096 : sum += pulses[i] * pulses[i];
727 : }
728 :
729 590506 : sum = 1.0 / LC3_SQRT(sum);
730 :
731 10038602 : for (i = 0; i < M; i++) {
732 9448096 : st2_vector[i] = pulses[i] * sum;
733 : }
734 :
735 : /* Inverse transform */
736 590506 : idct_II(st2_vector, st2_vector_idct, M);
737 :
738 : /* Gain */
739 : /* Add stage 1 and stage 2 */
740 10038602 : for (i = 0; i < M; i++) {
741 9448096 : scf_q[i] += st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]];
742 : }
743 590506 : }
744 :
745 : #ifdef CR9_C_ADD_1p25MS_LRSNS
746 :
747 : /* 29/30 bits optimized search functions for PVQ and FESS */
748 : /* stage 2 submode shape 0: "splitLF" (N=5,K=6)(N=8,K=2) or (N=5,K=8)(N=8,K=0) , 4 gains */
749 : /* stage 2 submode shape 1: "full" FB (N=15,K=5), 4xfixed , 8 gains */
750 : /* stage 2 submode shape 2-5: "fixed env " (N=13-15,K=10-12), 4xfixed , 8 gains */
751 :
752 0 : static void pvq_fess_enc_search(LC3_FLOAT* x_in /* i: 0...M-1 */
753 : , LC3_INT32 y[SNSLR_MAX_PVQ_SEARCH_CAND][M], /* o: [3]*[0...M-1] */
754 : LC3_INT32 *fixShapeNb /* o: [-1, 0...3] */
755 : )
756 : {
757 : LC3_INT32 i, j, curr_cand;
758 : LC3_INT32 NcandLF, Ngrp, Kgrp, Ktop_LF, Ntop_LF;
759 : LC3_INT32 NcandFB, Kfull;
760 : LC3_INT32 NcandFix, Kfix, Nsigns_fix;
761 :
762 : LC3_INT32 N, K, pulse_total, top_pulses;
763 : LC3_FLOAT abs_sum, projfac;
764 : LC3_FLOAT yy, xy; /* in-loop energy and corr */
765 :
766 : LC3_FLOAT yy_n5k8, xy_n5k8;
767 : LC3_FLOAT xabs[M];
768 : LC3_INT32 y_tmp_n5k8[M];
769 : LC3_INT32 y_tmp[M];
770 : LC3_INT16 n, fix_ind, shift_ind;
771 : LC3_INT16 best_env_ind;
772 : LC3_INT16 best_shift_ind;
773 : LC3_INT16 best_ind;
774 : LC3_INT16 pulse_total_n5k8;
775 : LC3_FLOAT f_normcorr_fixenv[SNSLR_N_FIXENV][SNSLR_N_FIXENV_SHIFTS];
776 : LC3_FLOAT *p;
777 : const LC3_INT32* env_ptr;
778 :
779 : #define SC 1 /*Starting coeff position of PVQ target , (we have no DC) */
780 : {
781 : /* no DC coeff , only coeff 1..15 is quantized in the range 0..15 */
782 0 : NcandLF = 1;
783 :
784 0 : Ngrp = 5; /* PVQ(5, 6) = 10.94b , + P(8,2)=7b + P(2,0)=0b */
785 0 : Kgrp = 6;
786 0 : Ntop_LF = 8; /* allow to encode less than M-sc -Ngrp */
787 0 : Ktop_LF = 2; /* fill a few unit pulses in the HF region */
788 : /* P(5,8)+P(10,0) will also fit in 13 bits */
789 : /* Fullband safety net */
790 0 : NcandFB = 1;
791 0 : Kfull = 5; ; /* PVQ(15,5)= 16.65 bits , */
792 :
793 : /*fixed env */
794 0 : NcandFix = 4; /* 4th only has 10 signs */
795 0 : Kfix = 12; /* number of signs */
796 0 : Nsigns_fix = 12; /* area to cover and number of signs */
797 : }
798 :
799 0 : for (i = SC; i < (M); i++)
800 : {
801 0 : xabs[i] = LC3_FABS(x_in[i]);
802 : }
803 0 : xabs[0] = 0;
804 :
805 : /* splitLF LFfocus subshape idx 0 */
806 0 : if (Kgrp > 0 && NcandLF > 0)
807 : {
808 0 : curr_cand = 0;
809 : /* Projection to LF pyramid N=Ngrp, K=Kgrp */
810 0 : abs_sum = 0.0;
811 0 : N = Ngrp;
812 0 : K = Kgrp;
813 0 : pulse_total = 0;
814 :
815 0 : for (i = SC; i < (SC + N); i++)
816 : {
817 0 : abs_sum += xabs[i];
818 : }
819 0 : projfac = (K - 1) / abs_sum;
820 :
821 0 : if (abs_sum == 0.0)
822 : {
823 0 : projfac = 0.0;
824 : }
825 :
826 0 : yy = xy = 0.0f;
827 0 : for (i = SC; i < (SC + N); i++)
828 : {
829 0 : y_tmp[i] = LC3_FLOOR(xabs[i] * projfac); /* local projection within group over N coeffs used here */
830 :
831 0 : pulse_total += y_tmp[i];
832 :
833 0 : yy += (y_tmp[i] * y_tmp[i]);
834 0 : xy += (xabs[i] * y_tmp[i]);
835 : }
836 :
837 : /* LF Adding unit pulses up to K in LF */
838 0 : for (; pulse_total < K; pulse_total++)
839 : {
840 0 : pvq_pulse_search(xabs, &yy, &xy, y_tmp, SC, SC + N);
841 : }
842 :
843 : {
844 : /* allow (N=5,K=(6+2)=8) in low band only, higher part is then zeroed */
845 : /* can be multiplexed put in 13 bits */
846 0 : yy_n5k8 = yy;
847 0 : xy_n5k8 = xy;
848 0 : pulse_total_n5k8 = pulse_total;
849 :
850 0 : memset(y_tmp_n5k8, 0, sizeof(*y_tmp_n5k8)*M);
851 0 : memcpy(y_tmp_n5k8, y_tmp, sizeof(*y_tmp)*(SC + N)); /* cpy LF initial search result for n5k6 to n5k8 output */
852 :
853 0 : for (; pulse_total_n5k8 < (K + 2); pulse_total_n5k8++)
854 : {
855 0 : pvq_pulse_search(xabs, &yy_n5k8, &xy_n5k8, y_tmp_n5k8, SC, SC + N);
856 : }
857 : }
858 :
859 :
860 : /* split HF : longer M vector */
861 0 : memset(y[curr_cand], 0, sizeof(*y_tmp)*M); /*zero full candidate vector */
862 0 : memcpy(&(y[curr_cand]), y_tmp, sizeof(*y_tmp)*(SC + N)); /* cpy LF-part to output */
863 :
864 :
865 0 : if (Ktop_LF && (M - Ngrp - SC >= Ntop_LF))
866 : {
867 :
868 : /* xy = 0.0; yy = 0.0; */
869 0 : memset(&(y_tmp[Ngrp]), 0, (M - SC - Ngrp) * sizeof(*y_tmp));
870 0 : top_pulses = 0;
871 :
872 0 : for (; top_pulses < Ktop_LF; top_pulses++)
873 : {
874 0 : pvq_pulse_search(xabs, &yy, &xy, y_tmp, SC + N, SC + N + Ntop_LF);
875 : }
876 :
877 0 : for (j = SC + N; j < (SC + N + Ntop_LF); j++)
878 : {
879 0 : y[curr_cand][j] = y_tmp[j];
880 : }
881 : }
882 :
883 : {
884 : /* shape 0 : decide on best split alternative "0a" n5k6 + n8k2 + n2k0 or "0b" n5k8 + n10k0,
885 : shape only assessed , i.e. assume same gain quantizer */
886 0 : if ((xy_n5k8*xy_n5k8)*yy > (xy*xy)*yy_n5k8)
887 : {
888 : /* use n5k8, with zeroed high band */
889 : /* i.e. better to put two additional pulses in the n5 low band than in the higher band */
890 0 : memcpy(&(y[curr_cand]), y_tmp_n5k8, sizeof(*y_tmp_n5k8)*(M)); /* cpy LFonly to output */
891 : }
892 : }
893 :
894 : /* assign signs to the cand vector from x_in */
895 0 : for (i = SC; i < (M); i++)
896 : {
897 0 : if (x_in[i] < 0)
898 : {
899 0 : y[curr_cand][i] *= -1;
900 : }
901 : }
902 0 : y[curr_cand][0] = 0; /* DC */
903 :
904 : }
905 :
906 : /* shape 1 : Full band shape analysis */
907 0 : if (Kfull > 0 && NcandFB > 0)
908 : {
909 0 : curr_cand = 1;
910 0 : N = M - SC;
911 0 : K = Kfull;
912 :
913 : /* project */
914 0 : pulse_total = 0;
915 0 : yy = xy = 0.0f;
916 0 : abs_sum = 0.0;
917 0 : for (i = SC; i < SC + N; i++)
918 : {
919 0 : abs_sum += xabs[i];/* over N */
920 : }
921 :
922 0 : projfac = (K - 1) / abs_sum;
923 0 : if (abs_sum == 0.0)
924 : {
925 0 : projfac = 0.0;
926 : }
927 :
928 :
929 0 : memset(y_tmp, 0, sizeof(*y_tmp)*M);
930 0 : for (i = SC; i < SC + N; i++)
931 : {
932 0 : y_tmp[i] = LC3_FLOOR(xabs[i] * projfac); /* projection over N coeffs */
933 0 : pulse_total += y_tmp[i];
934 0 : yy += (y_tmp[i] * y_tmp[i]);
935 0 : xy += (xabs[i] * y_tmp[i]);
936 : }
937 :
938 0 : for (; pulse_total < K; pulse_total++)
939 : {
940 0 : pvq_pulse_search(xabs, &yy, &xy, y_tmp, SC, SC + N);
941 : }
942 0 : memcpy(&(y[curr_cand]), y_tmp, sizeof(*y_tmp)*M); /* cpy to output */
943 :
944 : /* Step: Add signs to each of the full vector from input */
945 0 : for (i = SC; i < M; i++)
946 : {
947 0 : if (x_in[i] < 0)
948 : {
949 0 : y[curr_cand][i] *= -1; ;
950 : }
951 : }
952 0 : y[curr_cand][0] = 0;
953 : } /* Fullband */
954 :
955 :
956 : { /* fixed envelopes shifted signs shapes 2 ... 5 */
957 0 : best_env_ind = -1;
958 0 : best_shift_ind = -1;
959 :
960 : /* search fixed env shapes first */
961 : /* search shape of all fixed flat-ish envelopes using an optimal nb_env*nbshifts shape analysis */
962 0 : if (Kfix > 0 && NcandFix > 0)
963 : {
964 0 : curr_cand = 2;
965 0 : N = Nsigns_fix;
966 0 : K = Kfix;
967 :
968 : /* find the minimum shape error across all possible 4 fixed envelopes and all 4 shifts */
969 : /* maximise normalized cross correlation target*y *(1/sqrt(y^2)) to minimize shape error */
970 :
971 0 : for (fix_ind = 0; fix_ind < SNSLR_N_FIXENV; fix_ind++)
972 : {
973 0 : for (shift_ind = 0; shift_ind < SNSLR_N_FIXENV_SHIFTS; shift_ind++)
974 : {
975 0 : f_normcorr_fixenv[fix_ind][shift_ind] = 0.0;
976 0 : for (n = 0; n < signs_fix[fix_ind]; n++)
977 : {
978 0 : f_normcorr_fixenv[fix_ind][shift_ind] += (xabs[SC + n + shift_ind] * env_ptrs[fix_ind][n + shift_ind]);
979 : }
980 : /* energy normalize, for the specific shift and env,
981 : otherwise it is not possible to compare among the shifted envelopes properly */
982 :
983 0 : f_normcorr_fixenv[fix_ind][shift_ind] *= shift_en_norm_factors[fix_ind][shift_ind];
984 : }
985 : }
986 :
987 : /* now actually pick the env[0,1,2,3] and env shift[0,1,2,3] option which maximizes the normcorr
988 : (minimizes shape mse as all fixed envelopes have the same gain quantizer) */
989 0 : p = &(f_normcorr_fixenv[0][0]);
990 0 : best_ind = 0;
991 0 : for (n = 1; n < (SNSLR_N_FIXENV * SNSLR_N_FIXENV_SHIFTS); n++)
992 : {
993 0 : if (p[n] > p[best_ind])
994 : {
995 0 : best_ind = n;
996 : }
997 : }
998 0 : best_env_ind = best_ind / SNSLR_N_FIXENV_SHIFTS;
999 0 : best_shift_ind = best_ind - best_env_ind * SNSLR_N_FIXENV;
1000 0 : assert(best_env_ind >= 0 && best_env_ind < SNSLR_N_FIXENV);
1001 0 : assert(best_shift_ind >= 0 && best_shift_ind < SNSLR_N_FIXENV_SHIFTS);
1002 : }
1003 : /* o: best_shift_ind; o: best_env_ind */
1004 :
1005 0 : *fixShapeNb = best_env_ind; /* best normalized correlation out of the 4x4 = 16 envelope options */
1006 : /*best shift ind, later re-established/found via output vector y[2] */
1007 :
1008 : /* Fixed envelope "flat-ish" signband coding , including sign coding of shifted block */
1009 : /* submode idx 2,3,4 , "1"/env 1(s0)+ 2(shift)+ 11bits(s1..s11) + always a 3 bits gain */
1010 : /* submode idx 5 , "1"/env 1(s0)+ 2(shift)+ 9bits(s1..s9) + always a 3 bits gain */
1011 : /*
1012 : 2, init_bell_12signs , [ 8,8,8, 7,7 ... ]
1013 : 3, decaying envelope 12 signs, [ 12,12,11,11, ... ]
1014 : 4, start_bell_12signs ,[ 7,7,8,8,8, 7,... ]
1015 : 5, early_bell_10signs,[ 6,6, 7,7,8,8,8,7,... ]
1016 : */
1017 :
1018 : {
1019 : /* construct the selected fix shape with its corresponding shift */
1020 0 : memset(y[curr_cand], 0, sizeof(LC3_INT32)*M); /* zero output */
1021 0 : env_ptr = env_ptrs[best_env_ind];
1022 :
1023 0 : Nsigns_fix = signs_fix[best_env_ind];
1024 :
1025 : /* now assign unit amplitude and signs to each of the fixed env vector from x_in in the band */
1026 0 : for (i = best_shift_ind; i < (Nsigns_fix + best_shift_ind); i++)
1027 : {
1028 0 : y[curr_cand][SC + i] = env_ptr[i];
1029 : }
1030 0 : for (i = (SC + best_shift_ind); i < (SC + Nsigns_fix + best_shift_ind); i++)
1031 : {
1032 0 : if (x_in[i] < 0)
1033 : {
1034 0 : y[curr_cand][i] *= -1;
1035 : }
1036 : }
1037 0 : y[curr_cand][0] = 0;
1038 : }
1039 : }
1040 :
1041 0 : return;
1042 : }
1043 :
1044 0 : static void lrsns_quant_shape_gain(
1045 : LC3_FLOAT* t2rot, LC3_INT32 y[SNSLR_MAX_PVQ_SEARCH_CAND][M],
1046 : LC3_INT32* gain_idx, LC3_INT32 *shape_idx, LC3_FLOAT* y_norm, LC3_FLOAT* scq_gain, LC3_INT32 n_cand )
1047 : {
1048 : LC3_INT32 gidx, sidx;
1049 : LC3_FLOAT min_mse, mse;
1050 :
1051 : LC3_INT32 i;
1052 : LC3_INT16 start_shape;
1053 : LC3_INT16 end_shape;
1054 : LC3_INT32 gain_levels[SNSLR_MAX_PVQ_SEARCH_CAND];
1055 : LC3_FLOAT yCur[SNSLR_MAX_PVQ_SEARCH_CAND][M];
1056 : const LC3_FLOAT *lrsns_vq_gains[SNSLR_MAX_PVQ_SEARCH_CAND];
1057 :
1058 0 : gain_levels[0] = 4; /* splitLF */
1059 0 : gain_levels[1] = 8; /* full */
1060 0 : gain_levels[2] = 8; /* Fix-env{ 0,1,2,3,4} */
1061 :
1062 0 : lrsns_vq_gains[0] = &(lrsns_gains_Q11[0][0]);
1063 0 : lrsns_vq_gains[1] = &(lrsns_gains_Q11[1][0]);
1064 0 : lrsns_vq_gains[2] = &(lrsns_gains_Q11[2][0]);
1065 :
1066 0 : min_mse = LC3_CONST_FLOATMAX;
1067 :
1068 :
1069 0 : *gain_idx = 0;
1070 0 : *shape_idx = 0;
1071 0 : start_shape = 0;
1072 0 : end_shape = n_cand;
1073 :
1074 0 : for (sidx = start_shape; sidx < end_shape; sidx++)
1075 : {
1076 : /* Normalize the vectors */
1077 0 : for (i = 0; i < M; i++)
1078 : {
1079 0 : yCur[sidx][i] = (LC3_FLOAT)y[sidx][i];
1080 : }
1081 0 : pvq_enc_vec_normalize(yCur[sidx], M);
1082 :
1083 0 : for (gidx = 0; gidx < gain_levels[sidx]; gidx++)
1084 : {
1085 0 : mse = calc_mse(t2rot, yCur[sidx], lrsns_vq_gains[sidx][gidx], M);
1086 :
1087 0 : if (mse < min_mse)
1088 : {
1089 0 : *gain_idx = gidx;
1090 0 : *shape_idx = sidx;
1091 0 : min_mse = mse;
1092 : }
1093 : }
1094 :
1095 : }
1096 :
1097 0 : for (i = 0; i < M; i++)
1098 : {
1099 0 : y_norm[i] = yCur[*shape_idx][i];
1100 : }
1101 :
1102 0 : *scq_gain = lrsns_vq_gains[*shape_idx][*gain_idx];
1103 :
1104 0 : return;
1105 : }
1106 :
1107 0 : LC3_INT32 MSEsearchGeneric(LC3_FLOAT *scf, const LC3_FLOAT *sns_CB, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse)
1108 : {
1109 :
1110 : LC3_FLOAT f_tmp, mse;
1111 : LC3_INT32 i, n, ind;
1112 :
1113 0 : ind = -1;
1114 :
1115 0 : *min_mse = (LC3_FLOAT)LC3_CONST_POW_2_100;
1116 0 : for (i = 0; i < cb_len; i++)
1117 : {
1118 0 : mse = 0;
1119 0 : for (n = 0; n < v_len; n++)
1120 : {
1121 0 : f_tmp = (scf[n] - sns_CB[i * v_len + n]);
1122 0 : mse += (f_tmp * f_tmp);
1123 : }
1124 :
1125 0 : if (mse < *min_mse)
1126 : {
1127 0 : *min_mse = mse;
1128 0 : ind = i;
1129 : }
1130 : }
1131 0 : assert(ind >= 0 && ind < cb_len);
1132 :
1133 0 : return ind;
1134 : }
1135 :
1136 0 : void snslr_st1B_vector_dec(LC3_INT16 idx, const LC3_INT16* LFCB, const LC3_INT16 *HFCB, const LC3_INT16* seg_cnt_cum, const LC3_INT16* idx12b_cb, LC3_FLOAT *st1B_vector)
1137 : {
1138 : /* decompose the received 0 ... 169 index , into the correct intger and float st1B vector */
1139 : LC3_INT32 i, seg; /*counters*/
1140 : const LC3_INT16 *lf_cb, *hf_cb;
1141 : LC3_INT16 idx_12b, lf_sign, hf_sign;
1142 : LC3_INT16 idx_LF, idx_HF;
1143 : LC3_INT16 buf[M];
1144 : LC3_INT16 st1B_W16Q11[M];
1145 0 : LC3_FLOAT f_Q11_scale = (1.0 / 2048.0);
1146 :
1147 0 : assert(idx >= 0 && idx < 170);
1148 0 : seg = 0;
1149 0 : while (seg_cnt_cum[seg + 1] <= idx) {
1150 0 : seg++;
1151 : }
1152 0 : assert(seg >= 0 && seg < 4);
1153 :
1154 0 : idx_12b = idx12b_cb[idx]; /* from sequential value to a coded 12b index*/
1155 :
1156 0 : lf_sign = 1; /* assume a 0 bit -> "+" */
1157 0 : if ((0x0800 & idx_12b) != 0) {
1158 0 : lf_sign = -1; /* assume a 1 bit -> " -" */
1159 : }
1160 :
1161 0 : hf_sign = 1; /* assume a 0 bit -> "+" */
1162 0 : if ((0x0400 & idx_12b) != 0) {
1163 0 : hf_sign = -1; /* assume a 1 bit -> "-" */
1164 : }
1165 0 : idx_LF = (0x03e0 & idx_12b) >> 5;
1166 0 : idx_HF = (0x001f & idx_12b);
1167 :
1168 : /* extseg0 f,f */
1169 0 : lf_cb = &(LFCB[idx_LF*(M / 2)]);
1170 0 : hf_cb = &(HFCB[idx_HF*(M / 2)]);
1171 0 : for (i = 0; i < (M / 2); i++)
1172 : {
1173 0 : st1B_W16Q11[i] = lf_sign * lf_cb[i]; /* imult() or negate */
1174 0 : st1B_W16Q11[M / 2 + i] = hf_sign * hf_cb[i];
1175 : }
1176 0 : memcpy(buf, st1B_W16Q11, sizeof(*buf)*M); /* buffer cpy needed for reversal sections */
1177 :
1178 0 : if ((seg & 0x0002) != 0)
1179 : { /* r,* */ /* flip LF */
1180 0 : for (i = 0; i < (M / 2); i++)
1181 : {
1182 0 : st1B_W16Q11[i] = buf[(M / 2 - 1) - i];
1183 : }
1184 : }
1185 :
1186 0 : if ((seg & 0x0001) != 0)
1187 : { /* *,r */ /* flip HF */
1188 0 : for (i = 0; i < (M / 2); i++)
1189 : {
1190 0 : st1B_W16Q11[(M / 2) + i] = buf[(M - 1) - i];
1191 : }
1192 : }
1193 :
1194 : /* Cfloat: convert the 16bit integer Q11 values from LFCB, and HFCB into floats */
1195 0 : for (i = 0; i < M; i++)
1196 : {
1197 0 : st1B_vector[i] = ((LC3_FLOAT)st1B_W16Q11[i]) * f_Q11_scale;
1198 : }
1199 0 : }
1200 :
1201 0 : LC3_INT32 MSEsearchCbBIdxMap(const LC3_FLOAT *scf, const LC3_INT16 *LFCB, const LC3_INT16 *HFCB, const LC3_INT16 *seg_cnt_cum, const LC3_INT16* idx12b_cb, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse)
1202 : {
1203 : LC3_INT32 seg, i, j; /*counters */
1204 : LC3_INT32 L_mse;
1205 : LC3_INT16 scfLF_Q11[M], tmp_buf[M];
1206 : LC3_INT16* scfHF_Q11;
1207 : const LC3_INT16 *lf_cb, *hf_cb;
1208 : LC3_INT16 err, best_ind, idx_12b, signbitLF, signbitHF, idx_LF, idx_HF;
1209 0 : LC3_INT32 L_mse_best = INT_MAX; /*a huge positive number */
1210 :
1211 : UNUSED(cb_len); /*cb_len only used for assert/verification */
1212 :
1213 0 : assert(v_len == M);
1214 :
1215 0 : scfHF_Q11 = (&scfLF_Q11[v_len / 2]); /* ptr init */
1216 :
1217 : /*set up fwd,fwd search */
1218 0 : for (i = 0; i < M; i++)
1219 : {
1220 0 : tmp_buf[i] = (LC3_INT16)LC3_ROUND(scf[i] * 2048.0); /* scf target moved to BASOP signed Word16Q11 integer domain */
1221 : }
1222 :
1223 0 : best_ind = -1; /*for debug*/
1224 0 : for (seg = 0; seg < 4; seg++)
1225 : {
1226 0 : memcpy(scfLF_Q11, tmp_buf, M * sizeof(*scfLF_Q11)); /* M * move16() */
1227 : /*seg==0: fwd, fwd */
1228 : /*seg==1: fwd, rev */
1229 : /*seg==2: fwd, fwd */
1230 : /*seg==3: rev, rev */
1231 :
1232 0 : if ((seg & 0x0002) != 0)
1233 : { /* {r,*} */ /* flip LF */
1234 0 : for (i = 0; i < (M / 2); i++)
1235 : {
1236 0 : scfLF_Q11[i] = tmp_buf[(M / 2 - 1) - i];
1237 : }
1238 : }
1239 0 : if ((seg & 0x0001) != 0)
1240 : { /* {*,r} */ /* flip HF */
1241 0 : for (i = 0; i < (M / 2); i++)
1242 : {
1243 0 : scfLF_Q11[M / 2 + i] = tmp_buf[(M - 1) - i];
1244 : }
1245 : }
1246 :
1247 0 : for (i = seg_cnt_cum[seg]; i < seg_cnt_cum[seg + 1]; i++)
1248 : {
1249 0 : idx_12b = idx12b_cb[i]; /* indirect adressing lookup of 12b index pointing to LF and HF + individual sign swaps */
1250 0 : signbitLF = (0x0800 & idx_12b); /* b11 logical */
1251 0 : signbitHF = (0x0400 & idx_12b); /* b10 logical */
1252 0 : idx_LF = (0x03e0 & idx_12b) >> 5; /* b9...b5 */
1253 0 : idx_HF = (0x001f & idx_12b); /* b4..b0 lowest 5 bits */
1254 :
1255 0 : lf_cb = &(LFCB[idx_LF * M / 2]); /* ptr init */
1256 0 : hf_cb = &(HFCB[idx_HF * M / 2]); /* ptr init */
1257 :
1258 0 : L_mse = 0; /* move32() */ /* we accumulate energies on the positive side */
1259 0 : for (j = 0; j < (M / 2); j++)
1260 : {
1261 0 : err = (scfLF_Q11[j] - lf_cb[j]); /* a "+"sign, LF err in Q11 */
1262 0 : if (signbitLF != 0)
1263 : { /* negate LF*/
1264 0 : err = (scfLF_Q11[j] + lf_cb[j]); /* "-""-" --> "+" LF err in Q11 ,single BASOP */
1265 : }
1266 0 : L_mse += (err * err); /* simulate L_mac0 , accumulate towards max positive side */
1267 :
1268 0 : err = (scfHF_Q11[j] - hf_cb[j]); /* a "+"sign, HF err in Q11 */
1269 0 : if (signbitHF != 0)
1270 : { /* negate HF */
1271 0 : err = (scfHF_Q11[j] + hf_cb[j]); /* -- --> "+", LF err in Q11 ,single BASOP */
1272 : }
1273 0 : L_mse += (err * err); /*simulate L_mac0 */ /* now total error */
1274 : }
1275 :
1276 0 : L_mse_best = MIN(L_mse, L_mse_best); /* 1 cycle BASOP preupdate best */
1277 0 : if ((L_mse - L_mse_best) == 0)
1278 : {
1279 0 : best_ind = i; /* update winner, single BASOP */
1280 : }
1281 : }
1282 : }/* segment seg */
1283 :
1284 0 : *min_mse = (LC3_FLOAT)((double)L_mse_best) / (2048.0*2048.0); /* Word32 mse -> Cfloat output calculation */
1285 :
1286 0 : assert(best_ind >= 0 && best_ind < cb_len);
1287 :
1288 0 : return (LC3_INT32)best_ind;
1289 : }
1290 :
1291 0 : void snslr_st1C_vector_dec(LC3_INT16 idx, const LC3_INT8* CBW8, LC3_INT16 scaleQ4, LC3_INT16 inv_scaleQ15, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT *st1C_vector)
1292 : {
1293 : /* decompose the received 0... 169 index , into the correct (integer and) float st1C vector */
1294 : /* even in C-float the st1C coeffs are put into a S16Q11 final integers domain */
1295 : /* Enables BE compatibility between {BASOP, float, double} arithmetic implmentations */
1296 :
1297 :
1298 : LC3_INT32 i; /*counter*/
1299 : const LC3_INT8 *cb;
1300 : LC3_INT32 L_tmp;
1301 : LC3_INT16 s_tmp, st1C_Q11[M];
1302 :
1303 : UNUSED(v_len);
1304 : UNUSED(cb_len);
1305 : UNUSED(inv_scaleQ15); /* req for debugging only */
1306 0 : assert(idx >= 0 && idx < cb_len);
1307 0 : assert(v_len == M);
1308 :
1309 0 : cb = &(CBW8[idx*M]); /* pointer init */
1310 0 : for (i = 0; i < (M); i++)
1311 : {
1312 : /* BASOP: L_tmp = L_mult0((int16_t)cb[i], scaleQ4 ); */ /*S8Q7 * S15Q4 */ /*sign+7bit, sign+4 bits --> sign+11bit .lt sign+23 bits*/
1313 0 : L_tmp = ((int16_t)cb[i] /*S8Q7*/ * scaleQ4 /* S16Q4 */); /* S32Q11 */
1314 :
1315 : /* Cfloat: convert to Word16 Q11 integer as Word16 Q11 SNS domain bits, and then into floats */
1316 0 : assert(L_tmp >= -32768L && L_tmp <= 32767L); /* INT16 domain check*/
1317 0 : s_tmp = (int16_t)(L_tmp);
1318 0 : st1C_Q11[i] = s_tmp;
1319 : }
1320 :
1321 : /* Cfloat: convert the Word16 Q11 SNS domain bits, and then into floats */
1322 0 : for (i = 0; i < M; i++)
1323 : {
1324 0 : st1C_vector[i] = ((LC3_FLOAT)st1C_Q11[i])*(1.0 / 2048.0);
1325 : }
1326 0 : }
1327 :
1328 0 : LC3_INT32 MSEsearchGenericScaledW8(LC3_FLOAT *scf, const LC3_INT8 *sns_CBW8, LC3_INT16 scaleQ4, LC3_INT16 inv_scaleQ15, LC3_INT32 v_len, LC3_INT32 cb_len, LC3_FLOAT* min_mse)
1329 : {
1330 : /* scf float input values are typically in the range +12.0 to -12.0.
1331 : ROM table stored in WORD8 [+127,-128], format corresponding to ]+1.0 .. -1.0 ]
1332 : inv_scaleQ15, [downscaling value in Q15] applied before search
1333 : scaleQ12 upscaling value quantized in Q12, used in the mse calulation and in the common float and BASOP synthesis routines
1334 :
1335 : L_mse evaluated here in a positive integer Word32 domain to match BASOP
1336 :
1337 : Fuzzing/saturation considerations
1338 : max M==16 values (4 bits) yields 16*(256*256)=>2^(4+8+8)=2^20 .lt 2^31,
1339 : IntegerWord32 is a safe search domain
1340 :
1341 : a WC input analysis would be when half target entries are "-256" and half +255
1342 :
1343 : */
1344 : LC3_INT32 i, n, best_ind; /*counters*/
1345 : LC3_INT32 L_mse, L_mse_best;
1346 : LC3_INT16 targetW16[M], err;
1347 : LC3_FLOAT f_tmp, f_scale;
1348 : const LC3_INT8 * cbW8;
1349 :
1350 0 : f_scale = ((LC3_FLOAT)inv_scaleQ15) / 32768.0;
1351 0 : for (i = 0; i < v_len; i++) {
1352 0 : f_tmp = (scf[i] * f_scale);
1353 0 : assert(f_tmp >= -4.0 && f_tmp < 4.0); /* check for about 2 bit integer margin in the target */
1354 0 : targetW16[i] = (LC3_INT16)LC3_FLOOR(f_tmp*128.0); /*cast to INT16 W8Q7 */
1355 : };
1356 : /* in BASOP 1/32768 and *128 is handled by one single shift) */
1357 :
1358 0 : L_mse_best = INT_MAX; /* largest possible positive number in INT32 */
1359 0 : best_ind = -1;
1360 :
1361 0 : for (i = 0; i < cb_len; i++) {
1362 0 : L_mse = (0L); /* move32() */
1363 : /* we accumulate energies on the positive side Word8 vectors do not have any issue with saturation (16*256*256) ==2^(4+8+8) .lt 2^31 MAX_INT */
1364 :
1365 0 : cbW8 = &sns_CBW8[i*v_len]; /*ptr init */
1366 0 : for (n = 0; n < v_len; n++)
1367 : {
1368 0 : err = (targetW16[n] - ((LC3_INT16)cbW8[n])); /* cast from Word8 to Word16 is not for free,
1369 : actual cost in a Word16 architecture is a L_and(x,0x00ffff) or a shr(x,8) */
1370 :
1371 0 : L_mse += (err*err); /* L_mse = L_mac0(L_mse, err, err); */
1372 : }
1373 :
1374 0 : if ((L_mse - L_mse_best) <= 0)
1375 : { /* a value closer to 0 */
1376 0 : best_ind = i; /* single BASOP for best idx update */
1377 : }
1378 0 : L_mse_best = MIN(L_mse, L_mse_best); /* always update best MSE using L_min() in the idx loop, reduces WC WMOPS */
1379 : }
1380 0 : assert(best_ind >= 0 && best_ind < cb_len);
1381 :
1382 :
1383 0 : *min_mse = (LC3_FLOAT)((double)(L_mse_best)) / (128.0*128.0); /* Word32 L_mse in Q7 -> Cfloat output calculation */
1384 :
1385 0 : f_tmp = (((double)scaleQ4) / 16.0);
1386 0 : *min_mse *= (f_tmp*f_tmp); /* make gain scaling a part of Word32 L_mse -> Cfloat output calculation */
1387 :
1388 0 : return best_ind;
1389 : }
1390 :
1391 : /* LRSNS stage 1 functionality */
1392 0 : LC3_INT32 snsQuantScfEncLRSt1ABC(LC3_FLOAT* env, LC3_INT32* L_index, LC3_FLOAT *min_mse_saveBCA_ptr,
1393 : LC3_INT32* ind_saveB_ptr, LC3_FLOAT* st1_vectors, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx)
1394 : {
1395 :
1396 : LC3_INT32 i;
1397 : LC3_FLOAT *st1_vector, *st1_vectorA, *st1_vectorB, *st1_vectorC, target[M];
1398 : LC3_FLOAT st1_vectorBC[M];
1399 : LC3_FLOAT min_mse_saveA, min_mse_saveB, min_mse_saveC, min_mse_saveBC;
1400 : LC3_INT32 ind_saveA, ind_saveC;
1401 : const LC3_FLOAT *cb;
1402 : LC3_INT16 stage1_mode; /*0=A, 1=B, 2=C. -1==fail*/
1403 : LC3_FLOAT min_mse_saveB_fxlike;
1404 0 : LC3_INT32 ind_saveB_fxlike = -1;
1405 : LC3_FLOAT st1_vectorB_idx[M];
1406 : LC3_FLOAT st1C_lim;
1407 : LC3_FLOAT f_mse_tmp;
1408 0 : LC3_INT32 ind_saveC_ScaledW8 = -1;
1409 : LC3_FLOAT min_mse_saveC_ScaledW8;
1410 :
1411 : #ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
1412 : UNUSED(ltpf_rx);
1413 : #endif
1414 :
1415 0 : stage1_mode = -1; /* output mode */
1416 :
1417 0 : st1_vectorA = &(st1_vectors[0]);
1418 0 : st1_vectorB = &(st1_vectors[1 * M]);
1419 0 : st1_vectorC = &(st1_vectors[2 * M]);
1420 0 : st1_vector = &(st1_vectors[3 * M]);
1421 :
1422 : /* snslr stage1 B(170) and C(170), A(2) evaluation */
1423 : /* b0-b8 b9
1424 : segm , idx9b , stop bit, comment use
1425 : -----+--------+---------
1426 : A | 510,511| n/a, 2 entries, 9 bit total
1427 : ------+--------+--------
1428 : ------+--------+--------+-------
1429 : B | 0--169 | 1 , 170 entries, 10 bit total
1430 : ------+--------+--------
1431 : C | 170-339| 1 , 170 entries, 10 bit total
1432 : ------+--------+--------+------------
1433 : ------+--------+--------+------------
1434 : B* | 340-509| 1 --> aux=1, 170, 3b+17b for stage2 'LR_full/LR_fix', 30 bit total
1435 : ------+--------+--------+-------
1436 : B* | 0--169 | 0 , --> aux=0, 170, 2b+17b for stage2 'LR_SplitLF' , 29 bit total
1437 : ------+--------+--------+-------
1438 : B* | 170-339| 0 , --> aux=1, 170, 2b+17b for stage2 'LR_SplitLF',29 bit total
1439 : ------+--------+--------+-------
1440 : B* | 340-509| 0 --> aux=0, 170, 3b+17b for stage2 'LR_full/LR_fix', 30 bit total
1441 : ------+--------+--------+-------
1442 : */
1443 :
1444 : { /* stage 1 section A(2), a very small 2xM entry cb */
1445 0 : cb = lrsns_st1A_topTab_1bitNoDC;
1446 :
1447 0 : memcpy(target, env, sizeof(LC3_FLOAT)*M);
1448 :
1449 0 : ind_saveA = MSEsearchGeneric(target, cb, M, 2, &min_mse_saveA);
1450 0 : memcpy(st1_vectorA, &(cb[ind_saveA*M]), sizeof(LC3_FLOAT)*M);
1451 : }
1452 :
1453 0 : min_mse_saveB = LC3_CONST_FLOATMAX; /*safety init*/
1454 :
1455 : { /* stage1 section B(170) MSE analysis */
1456 0 : memcpy(target, env, sizeof(LC3_FLOAT)*M);
1457 0 : *ind_saveB_ptr = -1;
1458 :
1459 0 : ind_saveB_fxlike = MSEsearchCbBIdxMap(target, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11,
1460 : lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx, M, 170, &min_mse_saveB_fxlike); /*st1B LF,HF idx lookup search 170 ,170 Word16s , 0.34kB ROM */
1461 0 : snslr_st1B_vector_dec(ind_saveB_fxlike, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx,
1462 : st1_vectorB_idx);
1463 :
1464 0 : *ind_saveB_ptr = ind_saveB_fxlike;
1465 0 : min_mse_saveB = min_mse_saveB_fxlike;
1466 0 : memcpy(st1_vectorB, st1_vectorB_idx, sizeof(LC3_FLOAT)*M); /*use low ROM version */
1467 :
1468 : {
1469 : /* remove DC that can remain in the LF,HF index stored stage cb B structure */
1470 : /* a very slight offline decrease in perf 0.001 dB in AvSD when searching with DC above,
1471 : but it allows much better stage1 ROM-reuse performance
1472 : */
1473 0 : LC3_FLOAT dc = snslr_remove_st1_DC_fQ11(st1_vectorB, M); /* inplace removal of dc in st1_vectorB */
1474 : LC3_FLOAT f_tmp;
1475 0 : assert(min_mse_saveB >= 0.0);
1476 :
1477 0 : f_tmp = min_mse_saveB - M * (dc*dc);
1478 0 : min_mse_saveB = MAX(f_tmp, 0.0); /* truncation in DC removal can cause negative MSE, limit to 0 */
1479 : }
1480 : } /* end of stage 1 section B , search */
1481 :
1482 :
1483 :
1484 0 : st1C_lim = 3.97; /* corresponding to an SD limit of = 1.5 */
1485 0 : f_mse_tmp = MIN(min_mse_saveA*0.875, min_mse_saveB);
1486 :
1487 0 : if (f_mse_tmp < st1C_lim) /* skip C search if SD is already low enough < 1.5dB) to save average WMOPS */
1488 :
1489 : {
1490 0 : min_mse_saveC = 2 * 5.579999923706055; /*disable C selection in consecutive logic */
1491 0 : ind_saveC = 0; /* a valid index that will not be used */
1492 : }
1493 : else
1494 : { /* search stage1 C */
1495 : /* search another set (pitch dependent section C) of 170 mean residual vectors */
1496 : /* pitch_info rx selects a mean and then employ a trained residual 1x170W8 based harmonic outlier table */
1497 :
1498 : /* float means are based on Word16 S16Q11 values, so that BASOP and float always may become BE in synthesis*/
1499 0 : int16_t CBCmeanp_ind = pitch_rx; /* 0 or 1 */
1500 :
1501 : #ifndef LRSNS_CBC_NO_LTPF_DEPENDENCY
1502 0 : if (pitch_rx != 0 && ltpf_rx != 0)
1503 : {
1504 0 : CBCmeanp_ind = CBCmeanp_ind + 1; /*LTPF_rx is also active */
1505 : }
1506 : #else
1507 : /* CbC only dependent on LTP transmission on/off */
1508 : #endif
1509 :
1510 0 : for (i = 0; i < M; i++)
1511 : {
1512 0 : target[i] = env[i] - lrsns_st1CTrainedMapMeans[CBCmeanp_ind][i];
1513 : }
1514 :
1515 0 : ind_saveC_ScaledW8 = MSEsearchGenericScaledW8(target, lrsns_st1C_Both_Word8,
1516 0 : lrsns_st1C_Both_scaleQ4_7p4bits_fx[1], lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[1],
1517 : M, 170, &(min_mse_saveC_ScaledW8));
1518 :
1519 0 : snslr_st1C_vector_dec(ind_saveC_ScaledW8, lrsns_st1C_Both_Word8, lrsns_st1C_Both_scaleQ4_7p4bits_fx[1], lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[1],
1520 : M, 170, st1_vectorC);
1521 : /* integer based decoder side synthesis of scaled W8 table for best possible interop */
1522 :
1523 0 : ind_saveC = ind_saveC_ScaledW8;
1524 0 : min_mse_saveC = min_mse_saveC_ScaledW8;
1525 :
1526 0 : for (i = 0; i < M; i++) {
1527 0 : st1_vectorC[i] += lrsns_st1CTrainedMapMeans[CBCmeanp_ind][i]; /* Q11 means*/
1528 : }
1529 : }
1530 :
1531 : /* BC stage1 comparison */
1532 : /* initially assume B as stage 1 winner */
1533 0 : min_mse_saveBC = min_mse_saveB;
1534 0 : L_index[0] = *ind_saveB_ptr; /* 0...169 */
1535 :
1536 0 : memcpy(st1_vector, st1_vectorB, sizeof(LC3_FLOAT)*M); /* stage 1 segmentB result without DC copied as base for st2 */
1537 :
1538 :
1539 0 : if (min_mse_saveC < min_mse_saveBC)
1540 : { /* C better than B */
1541 0 : min_mse_saveBC = min_mse_saveC;
1542 0 : L_index[0] = 170 + ind_saveC; /* [2x 170] (9+1)b [170-339] , ">=170" is a signal to multiplexor */
1543 0 : memcpy(st1_vector, st1_vectorC, sizeof(LC3_FLOAT)*M);
1544 : }
1545 :
1546 0 : memcpy(st1_vectorBC, st1_vector, sizeof(LC3_FLOAT)*M);
1547 0 : L_index[1] = -10;
1548 0 : assert(min_mse_saveBC >= 0.0);
1549 :
1550 : /* (9(A)<->10(BC) bit weighted comparison */
1551 0 : *min_mse_saveBCA_ptr = min_mse_saveBC;
1552 0 : if (min_mse_saveA*0.875 < min_mse_saveBC) /* a minor favouring of the 9b vector results sqrt(0.875) => approx 0.6dB level domain */
1553 : {
1554 0 : L_index[0] = 510 + ind_saveA; /* only [510, 511] possible */
1555 0 : L_index[1] = -9;
1556 :
1557 0 : cb = lrsns_st1A_topTab_1bitNoDC;
1558 0 : memcpy(st1_vectorA, &(cb[ind_saveA*M]), sizeof(LC3_FLOAT)*M);
1559 0 : memcpy(st1_vector, st1_vectorA, sizeof(LC3_FLOAT)*M);
1560 :
1561 0 : *min_mse_saveBCA_ptr = min_mse_saveA * 0.875;;
1562 : }
1563 :
1564 : /* index0_saveBCA = index[0];*/ /* 0 ... 511 */
1565 : /* index1_saveBCA = index[1];*/ /* -9 or -10 */
1566 :
1567 0 : stage1_mode = 2; /* C , assumed */
1568 0 : if (L_index[0] >= 510)
1569 : {
1570 0 : stage1_mode = 0; /* A */
1571 : }
1572 0 : if (L_index[0] <= 169) {
1573 0 : stage1_mode = 1; /* B */
1574 : }
1575 :
1576 0 : return stage1_mode; /* return best stage1 mode */
1577 : }
1578 :
1579 0 : LC3_INT16 snsQuantScfEncLR(LC3_FLOAT* env, LC3_INT32* L_index, LC3_FLOAT* envq, Dct2 dct2structSNS, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx)
1580 : {
1581 : LC3_INT32 i;
1582 : LC3_FLOAT min_mse_saveBCA;
1583 : LC3_INT32 ind_saveB;
1584 : LC3_INT16 st1_mode;
1585 :
1586 : LC3_FLOAT stage2_en1_norm_sub[M];
1587 : LC3_FLOAT st1_vectors[(SNSLR_MAX_PVQ_SEARCH_CAND+1)*M], *st1_vectorA, *st1_vectorB, *st1_vectorC, *st1_vector;
1588 : LC3_FLOAT pvq_target_pre[M];
1589 : LC3_FLOAT pvq_target[M];
1590 : #ifdef LRSNS_WMC_FIX
1591 : LC3_INT32 y[SNSLR_MAX_PVQ_SEARCH_CAND][M]; /* o: [3]*[0...M-1] */
1592 : #else
1593 : LC3_INT32 y_tmp[3*M];
1594 : #endif
1595 : LC3_FLOAT stage2_en1_norm_pre_sub[M];
1596 : LC3_FLOAT envq_st1B_st2[M];
1597 : LC3_FLOAT mse_st1B_st2;
1598 : LC3_FLOAT mse_st1B_st2_dct_domain;
1599 : LC3_INT32 gain_idx, shape;
1600 : LC3_FLOAT scfq_gain;
1601 : LC3_INT32 fix_shape_idx;
1602 : LC3_INT16 envelope_bits; /* function output */
1603 : LC3_INT32 fix_shift_ind, fix_shift_bits, fix_end_sign, LS_tmp_ind;
1604 : LC3_INT32 shape_local;
1605 :
1606 : UNUSED(fix_shift_bits); /* used for assert */
1607 :
1608 : #ifndef LRSNS_WMC_FIX
1609 : LC3_INT32(*y)[M]; /* C-construct to allow matrix adressing into a scratch area */
1610 : #endif
1611 0 : envelope_bits = -1; /* output : 9,10, 29/30 */
1612 0 : gain_idx = 1; /* stage 2 gain idx range 0 ... 7 , or 0 ... 3 */
1613 0 : shape = -1; /* stage 2 shape range 0 ... 5 */
1614 :
1615 0 : st1_vectorA = &(st1_vectors[0]);
1616 0 : st1_vectorB = &(st1_vectors[1 * M]);
1617 0 : st1_vectorC = &(st1_vectors[2 * M]);
1618 0 : st1_vector = &(st1_vectors[3 * M]);
1619 :
1620 :
1621 : #ifndef LRSNS_WMC_FIX
1622 : y = (LC3_INT32(*)[M]) &(y_tmp[0]); /* y is an NxM Matrix Ptr */
1623 : #endif
1624 : { /* stage1 A,B,C */
1625 :
1626 0 : ind_saveB = -1;
1627 0 : min_mse_saveBCA = M * 32.0*32.0;
1628 0 : st1_mode = snsQuantScfEncLRSt1ABC(
1629 : env, L_index, &min_mse_saveBCA, &ind_saveB, st1_vectors, pitch_rx, ltpf_rx);
1630 :
1631 0 : if (ind_saveB < 0 || ind_saveB > 169)
1632 : {
1633 0 : assert(ind_saveB >= 0 && ind_saveB <= 169); /* idxB always needed in case stage2 is activated */
1634 : }
1635 :
1636 0 : if (st1_mode == 0)
1637 : {
1638 0 : envelope_bits = 9;
1639 0 : memcpy(st1_vector, st1_vectorA, sizeof(LC3_FLOAT)*M);
1640 0 : assert(L_index[0] >= 510 && L_index[0] <= 511);
1641 : }
1642 :
1643 0 : if (st1_mode == 1)
1644 : {
1645 0 : envelope_bits = 10;
1646 0 : memcpy(st1_vector, st1_vectorB, sizeof(LC3_FLOAT)*M);
1647 0 : assert(L_index[0] >= 0 && L_index[0] <= 169);
1648 : }
1649 :
1650 0 : if (st1_mode == 2)
1651 : {
1652 0 : envelope_bits = 10;
1653 0 : memcpy(st1_vector, st1_vectorC, sizeof(LC3_FLOAT)*M);
1654 0 : assert(L_index[0] >= 170 && L_index[0] < 2 * 170);
1655 : }
1656 :
1657 0 : L_index[1] = -910; /* aux */
1658 0 : L_index[2] = -envelope_bits; /* signal shape */
1659 :
1660 : }
1661 : /* only run stage 2 when necessary */
1662 :
1663 : {
1664 : LC3_FLOAT mse_lim_smooth;
1665 0 : mse_lim_smooth = (5.41); /* 1.75 SD */
1666 :
1667 0 : mse_st1B_st2 = 2.0* min_mse_saveBCA + 1.0; /* indicate that st1B+st2 is not used by setting a higher MSE than st1BCA */
1668 :
1669 0 : if (min_mse_saveBCA > mse_lim_smooth)
1670 : {
1671 : /* run and evaluate STAGE 2, using vector B as stage 1 */
1672 0 : for (i = 0; i < M; i++)
1673 : {
1674 0 : pvq_target_pre[i] = env[i] - st1_vectorB[i];
1675 : }
1676 :
1677 0 : dct2_apply(&dct2structSNS, pvq_target_pre, pvq_target);
1678 :
1679 0 : pvq_target[0] = 0.0; /* DC always zero */
1680 :
1681 0 : fix_shape_idx = -1;
1682 0 : pvq_fess_enc_search(pvq_target, y, &fix_shape_idx); /* best shape search splitLF, full, best_fess_env */
1683 :
1684 0 : assert(y[0][0] == 0 && y[1][0] == 0 && y[2][0] == 0);
1685 0 : lrsns_quant_shape_gain(pvq_target, y, &gain_idx, &shape, stage2_en1_norm_pre_sub, &scfq_gain, 2 + 1);
1686 :
1687 0 : if (shape == 2)
1688 : {
1689 0 : shape = 2 + fix_shape_idx;
1690 : }
1691 :
1692 : /* check if MSE after stage 2 is better already here in dct domain, avoid unnecessary IDCT-II calls */
1693 0 : envq_st1B_st2[0] = 0;
1694 0 : for (i = 1; i < M; i++)
1695 : {
1696 0 : envq_st1B_st2[i] = (stage2_en1_norm_pre_sub[i] * scfq_gain);
1697 : }
1698 :
1699 0 : mse_st1B_st2_dct_domain = calc_mse(pvq_target, envq_st1B_st2, 1.0f, M);
1700 :
1701 0 : if (min_mse_saveBCA < mse_st1B_st2_dct_domain)
1702 : {
1703 : /* no need for an IDCT as stage2 was worse than only stage1 */
1704 0 : mse_st1B_st2 = mse_st1B_st2_dct_domain;
1705 : }
1706 : else
1707 : {
1708 : /* Inverse transform */
1709 0 : idct_II(stage2_en1_norm_pre_sub, stage2_en1_norm_sub, M);
1710 :
1711 0 : for (i = 0; i < M; i++)
1712 : {
1713 0 : envq_st1B_st2[i] = st1_vectorB[i] + (stage2_en1_norm_sub[i] * scfq_gain);
1714 : }
1715 0 : mse_st1B_st2 = calc_mse(env, envq_st1B_st2, 1.0f, M);
1716 : }
1717 : }
1718 : } /*end of stage2 search */
1719 :
1720 : /* post-evaluate if one of (st1B, st1C, st1A) was actually better than st1B+stage2 */
1721 0 : if (mse_st1B_st2 < min_mse_saveBCA)
1722 : { /* use stage1B + st2 at 29b/30b bits total */
1723 0 : L_index[0] = ind_saveB;
1724 0 : L_index[1] = 2930; /* later stage2 aux value LS_splitLF or LS_full or s0, put here as a 0 or 1 */
1725 0 : L_index[2] = shape; /* 0=splitLF, 1=full, ( 2=fixEnv0, 3=fixEnv1, 4: fixEnv2, 5: fixEnv3 ) */
1726 0 : L_index[3] = gain_idx; /* gain_idx with a shape dependent number of levels (4 or 8 levels ) */
1727 :
1728 0 : memcpy(envq, envq_st1B_st2, sizeof(LC3_FLOAT)*M);
1729 0 : memcpy(st1_vector, st1_vectorB, sizeof(LC3_FLOAT)*M); /* save final st1B result, st1 in combination with stage 2, for verification */
1730 0 : envelope_bits = 29; /* 'LR_splitLF' */
1731 0 : if (shape > 0)
1732 : {
1733 0 : envelope_bits += 1; /*30 'LR_full/LR_fixenv' */
1734 : }
1735 :
1736 : {
1737 : /* DBG check values */
1738 0 : assert(shape >= 0);
1739 0 : assert(envelope_bits >= 29);
1740 0 : assert(L_index[0] <= 170); /*only B allowed */
1741 0 : assert(L_index[1] >= 0);
1742 :
1743 0 : assert(gain_idx >= 0); /*index*/
1744 0 : assert(scfq_gain > 0.0); /* value */
1745 : }
1746 : }
1747 : else
1748 : { /* stick to stage1(best of BCA) at 9 or 10 bits */
1749 0 : assert(L_index[1] < 0 && L_index[0] >= 0 && L_index[0] < 512);
1750 0 : envelope_bits = ((L_index[0] >= 510) ? 9 : 10);
1751 0 : shape = -envelope_bits; /* signal an invalid shape number to enc-entropy */
1752 :
1753 0 : memcpy(envq, st1_vector, M * sizeof(LC3_FLOAT)); /* output */
1754 0 : memset(stage2_en1_norm_sub, 0, M * sizeof(*stage2_en1_norm_sub));
1755 0 : scfq_gain = 0.0f;
1756 0 : gain_idx = -1; /* L_index sentinel */
1757 0 : L_index[2] = shape;
1758 : }
1759 :
1760 : /******************************************************************/
1761 : /* signal to enc_entropy for LRSNS semi-fractional multiplexing */
1762 : /******************************************************************/
1763 : /* integer multiplexing 29/30 bit modes into intermediate unmuxed integer indeces 0...7 */
1764 : /* a bit of fractional multiplexing for these indeces 0...7 is done later, in function enc_entropy() */
1765 0 : if (shape >= 0)
1766 : { /* stage 2 multiplexing manipulations */
1767 :
1768 :
1769 0 : if (shape == 0)
1770 : { /* splitLF */
1771 0 : LC3_INT32 n5k = 0;
1772 0 : for (i = 0; i < 5; i++)
1773 : {
1774 0 : n5k += abs(y[shape][1 + i]);
1775 : }
1776 :
1777 0 : if (n5k == 6)
1778 : {
1779 0 : MPVQ_enum(5, &(y[shape][1]), &(L_index[4]), &LS_tmp_ind); /* P(N=5,K=6) (10)=10 bit L_index */
1780 0 : L_index[1] = LS_tmp_ind; /* set the aux bit for the splitLF path, plant the first LS as aux */
1781 0 : assert((L_index[4] >= 0) && (L_index[4] < (SNSLR_NPVQ_L5K6 >> 1)));
1782 :
1783 0 : MPVQ_enum(8, &(y[shape][1 + 5]), &(L_index[5]), &LS_tmp_ind);
1784 0 : L_index[5] = (L_index[5] << 1) + LS_tmp_ind; /* A full PVQ 7 bit index for the P(N=8,K=2) B config*/
1785 0 : assert((L_index[5] >= 0) && (L_index[5] < (1 << 7)));
1786 : }
1787 : else
1788 : {
1789 0 : MPVQ_enum(5, &(y[shape][1]), &(L_index[4]), &LS_tmp_ind); /* PVQ(N=5,K=8) (12.x in total, i.e. LS+ 11.x ) */
1790 0 : L_index[1] = LS_tmp_ind; /* aux bit for the splitLF path , plant the first LS as aux */
1791 0 : assert((L_index[4] >= 0) && (L_index[4] < (SNSLR_NPVQ_L5K8 >> 1)));
1792 0 : L_index[5] = -8; /* signal LF PVQ(5,8) and zeroed HF(10,0) */
1793 : }
1794 : }
1795 0 : if (shape == 1)
1796 : { /* full (15,5) , LS kept separated */
1797 : /* indicate a stage2 path in the 9 bit stage1 index */
1798 0 : MPVQ_enum(15, &(y[shape][1]), &(L_index[4]), &LS_tmp_ind); /* mPVQ 16.66 bits in index[4], and LS 1 bit in index[1] */
1799 0 : L_index[1] = LS_tmp_ind; /*aux bit location, 0 or 1 , we plant the LS there */
1800 0 : assert((L_index[4] >= 0) && (L_index[4] < (SNSLR_NPVQ_L15K5 >> 1)));
1801 : }
1802 0 : if (shape >= 2 && shape <= 5)
1803 : {
1804 : /* fixEnv0, fixEnv1, fixEnv2, fixEnv3 */
1805 : /* send the fixed env subshape mode to enc_entropy */
1806 0 : L_index[4] = (shape - 2); /* env shape, 0-->"1" , 1--> "env1" */ /* L_index[2] has original shape 0...5 */
1807 :
1808 0 : shape_local = 2; /*a single y shape vector for all fixed env */
1809 :
1810 0 : fix_shift_ind = 0;
1811 0 : while (y[shape_local][1 + fix_shift_ind] == 0)
1812 : {
1813 0 : fix_shift_ind += 1;
1814 : }
1815 0 : fix_shift_bits = 2;
1816 :
1817 0 : assert(fix_shift_ind < (1 << fix_shift_bits));
1818 :
1819 0 : L_index[1] = (y[shape_local][1 + fix_shift_ind /* + 0*/] < 0); /* aux_bit : 0 (or 1) , will indicate the s0 sign in the FESS fix shape */
1820 :
1821 :
1822 0 : fix_end_sign = 12;
1823 0 : if (shape == 5)
1824 : {
1825 0 : assert(L_index[4] == 3);
1826 0 : fix_end_sign = (fix_end_sign - 2); /* shape 4 has 2 bits shift and a total of 10 signs =2^10*2^2 = 2^12 = 4096 */
1827 : }
1828 :
1829 0 : L_index[5] = fix_shift_ind; /* the two shift bits will be pushed up to b11,b12 , for 11 signs s1-s11 */
1830 :
1831 0 : for (int sign_ind = 1; sign_ind < fix_end_sign; sign_ind++) /* push the remaining sequential signs s1-s11(or s1-s9), into a single idx */
1832 : { /* s1 is in the MSB, and s11 is in the lsb*/
1833 0 : L_index[5] = L_index[5] << 1;
1834 0 : if (y[shape_local][1 + fix_shift_ind + sign_ind] < 0) /*"1" means negative, "0" means positive */
1835 : {
1836 0 : L_index[5] += 1;
1837 : }
1838 : }
1839 0 : assert(L_index[5] >= 0 && L_index[5] < (1 << (fix_shift_bits + (fix_end_sign - 1))));
1840 : }
1841 : } /* end of stage2 premultiplexing */
1842 :
1843 : {
1844 0 : assert(envelope_bits == 9 || envelope_bits == 10 || envelope_bits == 29 || envelope_bits == 30);
1845 : }
1846 :
1847 0 : return envelope_bits;
1848 : }
1849 :
1850 0 : void FESSdeenum(LC3_UINT8 dim_in, /* i : dimension of vec_out */
1851 : LC3_UINT8 n_env, /* i : number of envelopes */
1852 : LC3_UINT8 n_shift, /* i : number shifts */
1853 : LC3_UINT8 n_signs, /* i : number signs */
1854 : LC3_INT32 env_ind, /* i:indx */
1855 : LC3_INT32 shift_ind, /* i:indx */
1856 : LC3_INT32 sign_ind, /* i:indx */
1857 : LC3_INT32* vec_out /* o : FESS integer pulse train */)
1858 : {
1859 :
1860 : LC3_INT32 i;
1861 : LC3_INT32 sign_val;
1862 :
1863 0 : assert(n_env >= 1 && n_env <= 4);
1864 0 : assert(env_ind >= 0 && env_ind < n_env);
1865 0 : assert(shift_ind >= 0 && shift_ind < n_shift);
1866 :
1867 : UNUSED(n_env);
1868 : UNUSED(n_shift);
1869 0 : memset(vec_out, 0, sizeof(*vec_out)*dim_in);
1870 :
1871 0 : for (i = (shift_ind + n_signs - 1); i >= shift_ind; i--)
1872 : {
1873 : /* low numbered coeff signs are in the msb's */
1874 : /* high numbered coeff signs are in the lsb's */
1875 0 : assert(i < dim_in);
1876 0 : sign_val = 1 - 2 * (sign_ind & 0x01);
1877 0 : sign_ind = (sign_ind >> 1);
1878 0 : vec_out[i] = sign_val * env_ptrs[env_ind][i]; /* vec_out[i] = sign_val * amps[env_ind*(M - 1) + i]; */
1879 : }
1880 0 : }
1881 :
1882 0 : void snsQuantScfDecLR(LC3_INT32* sns_vq_idx, LC3_FLOAT* scf_q, LC3_INT32 pitch_rx, LC3_INT32 ltpf_rx)
1883 : {
1884 : LC3_INT32 i;
1885 : LC3_INT32 mPVQ_ind; /* can be 16-17 bits */
1886 : LC3_INT16 shape_idx, gain_idx, cb_idx, aux_idx, LS_ind;
1887 : LC3_INT16 env_ind, shift_ind, sign_ind, n_signs;
1888 :
1889 : LC3_INT32 Y_shape_j[M];
1890 : LC3_FLOAT Xq_shape_j[M], Xq_shape_j_idct[M], sum;
1891 : const LC3_FLOAT *cb;
1892 : const LC3_FLOAT *gainTab;
1893 : LC3_FLOAT st1_scf_q[M];
1894 0 : LC3_INT16 CBCmeanp_ind = pitch_rx; /* 0 or 1 */
1895 : const LC3_FLOAT *mean_cb;
1896 0 : LC3_INT16 sign_mask = 0x07ff;
1897 :
1898 :
1899 : #ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
1900 : UNUSED(ltpf_rx);
1901 : #endif
1902 :
1903 0 : sum = 0;
1904 0 : memset(Y_shape_j, 0, sizeof(LC3_INT32) * M);
1905 :
1906 0 : gainTab = &(lrsns_gains_Q11[0][0]); /* gcc warning init */
1907 0 : gain_idx = 0; /* gcc warning init */
1908 :
1909 0 : cb_idx = sns_vq_idx[0];
1910 0 : aux_idx = sns_vq_idx[1];
1911 0 : shape_idx = sns_vq_idx[2]; /* analysis order shape idx -9,-10, 0,1, 2,3,4,5 */
1912 0 : gain_idx = sns_vq_idx[3]; /* stage 2 gain */
1913 :
1914 : /* Stage1 cand */
1915 0 : if (shape_idx == -9)
1916 : {
1917 : /* minminal 2*16 SNS codebook, no DC */
1918 0 : cb = lrsns_st1A_topTab_1bitNoDC;
1919 0 : memcpy(scf_q, &(cb[cb_idx * M]), sizeof(LC3_FLOAT) * M);
1920 : }
1921 0 : else if (shape_idx == -10)
1922 : { /* 0..339 */ /* stage 1 only, transmitted in 9+1= 10 bits */
1923 0 : if (cb_idx < 170)
1924 : { /*Stage 1B */
1925 0 : snslr_st1B_vector_dec(cb_idx, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx, scf_q);
1926 0 : snslr_remove_st1_DC_fQ11(scf_q, M);
1927 : }
1928 : else
1929 : {
1930 0 : cb_idx -= 170;
1931 : /* Stage 1C harm outlier CB with a pitch dependent mean */
1932 : /* Q11 values , so that BASOP and float always becomes BE in synthesis*/
1933 0 : assert(cb_idx >= 0 && cb_idx < 170);
1934 0 : snslr_st1C_vector_dec(cb_idx, lrsns_st1C_Both_Word8, lrsns_st1C_Both_scaleQ4_7p4bits_fx[1], lrsns_st1C_Both_inv_scaleQ15_7p4bits_fx[1],
1935 : M, 170, scf_q
1936 : );
1937 :
1938 :
1939 : /* cbC add harmonic mean , based on pitch_info availability */
1940 0 : pitch_rx = sns_vq_idx[3]; /* LTP active flag directly from dec_entropy */
1941 : #ifdef LRSNS_CBC_NO_LTPF_DEPENDENCY
1942 : ltpf_rx = 0; /* CB_C has no dependency on LTPF active flag */
1943 : #else
1944 0 : ltpf_rx = sns_vq_idx[4]; /* LTPF active flag LTP active flag directly from dec_entropy */
1945 : #endif
1946 0 : CBCmeanp_ind = pitch_rx; /* 0 or 1 */
1947 : #ifndef LRSNS_CBC_NO_LTPF_DEPENDENCY
1948 0 : if (pitch_rx != 0 && ltpf_rx != 0)
1949 : {
1950 0 : CBCmeanp_ind = CBCmeanp_ind + 1; /* high corr ltpf_rx is also active */
1951 : }
1952 : #endif
1953 :
1954 0 : mean_cb = lrsns_st1CTrainedMapMeans[CBCmeanp_ind]; /* point to pitch dependent mean */
1955 0 : for (i = 0; i < M; i++)
1956 : {
1957 0 : scf_q[i] += mean_cb[i];
1958 : }
1959 : /* remove_DC() call is not required for section C */
1960 : /* a very small DC can still exist though, due to Q7+Q4 quantization of values */
1961 : }
1962 : }
1963 : else
1964 : { /* 0...169 */ /* st1B* used with a stage 2 shape submode */
1965 0 : assert(shape_idx >= 0);
1966 0 : snslr_st1B_vector_dec(cb_idx, st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, lrsns_st1B_merged170orderSortedSegmCum, lrsns_st1B_merged170orderSort12bitIdx, scf_q);
1967 0 : snslr_remove_st1_DC_fQ11(scf_q, M); /* DC needs removal for st1 part B */
1968 : }
1969 0 : memcpy(st1_scf_q, scf_q, sizeof(LC3_FLOAT) * M); /* keep track of stage 1 contribution */
1970 :
1971 0 : if (shape_idx >= 0) /* stage 2 shapes 0,1, 2,3,4,5 ( negative idx used for stage1 only */
1972 : {
1973 : /* Stage 2 SNS VQ decoding */
1974 : /* Decode shape_j */
1975 0 : Y_shape_j[0] = 0; /* no DCT-II DC-coeff decoded */
1976 :
1977 0 : switch (shape_idx)
1978 : {
1979 0 : case 0: /* splitLF 29 bits total */
1980 0 : LS_ind = aux_idx;
1981 0 : mPVQ_ind = sns_vq_idx[4]; /* mPVQ(5,6) or mPVQ(5,8) */
1982 :
1983 0 : if (sns_vq_idx[5] >= 0)
1984 : {
1985 0 : MPVQdeenum(5, 6, LS_ind, mPVQ_ind, &Y_shape_j[1]);
1986 0 : LS_ind = sns_vq_idx[5] & 0x1;
1987 0 : mPVQ_ind = sns_vq_idx[5] >> 1;
1988 0 : MPVQdeenum(8, 2, LS_ind, mPVQ_ind, &Y_shape_j[1 + 5]);
1989 : }
1990 : else
1991 : {
1992 0 : MPVQdeenum(5, 8, LS_ind, mPVQ_ind, &Y_shape_j[1]);
1993 : }
1994 0 : gainTab = &(lrsns_gains_Q11[0][0]);/* 4 levels in 2 bits */
1995 :
1996 0 : break;
1997 0 : case 1: /* full 30 bits total */
1998 0 : LS_ind = aux_idx;
1999 0 : mPVQ_ind = sns_vq_idx[4];
2000 0 : MPVQdeenum(15, 5, LS_ind, mPVQ_ind, &Y_shape_j[1]);
2001 0 : gainTab = &(lrsns_gains_Q11[1][0]); /* 8 levels in 3 bits */
2002 :
2003 0 : break;
2004 0 : case 2: /* fix env 0 , init_bell 12 signs */
2005 : case 3: /* fix env 1 , decay 24-->13 12 signs */
2006 : case 4: /* fix env 2 , start bell 12 signs */
2007 : case 5: /* fix env 3 , early bell 10 signs */
2008 0 : LS_ind = aux_idx; /* s0 */
2009 0 : env_ind = sns_vq_idx[4];
2010 0 : assert(env_ind == (shape_idx - 2));
2011 :
2012 0 : n_signs = 12; /* including s0 */
2013 0 : if (env_ind == 3) {
2014 0 : n_signs -= 2;
2015 : }
2016 0 : sign_mask = (sign_mask >> (12 - n_signs));
2017 :
2018 0 : shift_ind = sns_vq_idx[5] >> (n_signs - 1);
2019 0 : sign_ind = sns_vq_idx[5] & sign_mask;
2020 :
2021 : /* put s0 , right next to s1 , to make the sign decoding loop easier */
2022 0 : sign_ind = (sign_ind)+(LS_ind << (n_signs - 1)); /* s0 put as MSB at 12th position 2^11 , lsb at 2^0 */
2023 :
2024 : /*FixEnvShiftSigns deenumeration */
2025 0 : FESSdeenum(15, 4, 4, n_signs, env_ind, shift_ind, sign_ind, &Y_shape_j[1]); /*30b , 4xenv,4xshifts, 10 or12 signs, over 15 positions,*/
2026 0 : gainTab = &(lrsns_gains_Q11[2][0]);; /* 8 levels in 3 bits */
2027 : /* fix_envshift_nb = env_ind * 4 + shift_ind; */ /* index for fast normalization lookup */
2028 0 : break;
2029 0 : default:
2030 :
2031 0 : break;
2032 : }
2033 :
2034 : /* Unit energy normalization of the received shape */
2035 0 : for (i = 0; i < M; i++)
2036 : {
2037 0 : sum += (Y_shape_j[i] * Y_shape_j[i]);
2038 : }
2039 :
2040 0 : sum = 1.0 / LC3_SQRT(sum); /* all shapes will have tabled inv_sqrt() divisions as factors in BASOP */
2041 :
2042 0 : for (i = 0; i < M; i++)
2043 : {
2044 0 : Xq_shape_j[i] = Y_shape_j[i] * sum;
2045 : }
2046 :
2047 : /* Reconstruction of the quantized SNS scale factors */
2048 0 : idct_II(Xq_shape_j, Xq_shape_j_idct, M);
2049 0 : for (i = 0; i < M; i++) {
2050 0 : scf_q[i] += Xq_shape_j_idct[i] * gainTab[gain_idx];
2051 : }
2052 : }
2053 : else
2054 : { /* -9, -10 */
2055 : /* LRSNS stage 1 variations only */
2056 0 : memcpy(scf_q, st1_scf_q, sizeof(LC3_FLOAT) * M);
2057 : }
2058 0 : }
2059 :
2060 : /* LRSNS integer precision based function needed in both encoder and decoder */
2061 0 : LC3_FLOAT snslr_remove_st1_DC_fQ11(LC3_FLOAT *scfq, LC3_INT32 len)
2062 : {
2063 : LC3_INT32 i; /*Counter*/
2064 : LC3_INT32 L_dcQ11;
2065 0 : LC3_FLOAT f_dcQ11 = 0.0;
2066 0 : L_dcQ11 = 0L;
2067 :
2068 0 : for (i = 0; i < len; i++) {
2069 0 : L_dcQ11 += (LC3_INT32)(scfq[i] * 2048.0f); /* BE simulation of DC Q11 summation of truncated values in BASOP, preferably BE in synthesis in FLP/BASOP decoder */
2070 : }
2071 :
2072 0 : assert(len == M);
2073 : {
2074 0 : L_dcQ11 = L_dcQ11 >> 4; /* make the average in integer domain , no rounding applied before shift, on purpose */
2075 0 : f_dcQ11 = ((LC3_FLOAT)L_dcQ11) *(1.0f / 2048.0f); /* now a Q11 value to match the overall generic Q11 BASOP scaling of stage1 variables */
2076 : }
2077 :
2078 0 : for (i = 0; i < len; i++)
2079 : {
2080 0 : scfq[i] -= f_dcQ11; /* result update */
2081 : }
2082 0 : return f_dcQ11; /* output used for encoder side mse update*/
2083 : }
2084 :
2085 : #endif
|