Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include "cnst.h"
6 : #include "rom_com_fx.h"
7 : #include "rom_com.h"
8 : #include "stl.h"
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "basop32.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 :
13 :
14 : /*-----------------------------------------------------------------*
15 : * Local functions
16 : *-----------------------------------------------------------------*/
17 :
18 : static Word32 quantize_data_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, Word16 no_scales, const Word16 *no_lead );
19 : Word32 quantize_data_ivas_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, const Word16 *no_lead );
20 : static Word32 q_data_fx( Word16 *pTmp1, const Word16 *w1, Word16 *quant, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *p_sigma, const Word16 *p_inv_sigma, const Word16 *p_scales, Word16 *p_no_scales, const Word16 *p_no_lead );
21 : static void prepare_data_fx( Word16 *xsort, Word16 *sign, Word16 *data, Word32 *w, const Word16 *w_in, const Word16 *sigma, const Word16 *inv_sigma, Word16 *p_sig );
22 : static Word32 calculate_min_dist_fx( Word16 cv_pot[LATTICE_DIM], Word16 no_scales, const Word16 *scale, const Word32 *w, Word16 *p_best_scale, Word16 *p_best_idx, const Word16 *no_leaders, Word16 sig, Word16 *indx );
23 : static Word16 find_pos_fx( Word16 *c, Word16 len, Word16 arg, Word16 *p );
24 : static void take_out_val_fx( Word16 *v, Word16 *v_out, Word16 val, Word16 len );
25 : static Word16 index_leaders_fx( Word16 *cv, Word16 idx_lead, Word16 dim );
26 : static Word16 c2idx_fx( Word16 n, Word16 *p, Word16 k );
27 : static Word16 encode_sign_pc1_fx( Word16 parity, Word16 *cv );
28 : Word32 encode_comb_fx( Word16 *cv, Word16 idx_lead );
29 : static void sort_desc_ind_fx( Word16 *s, Word16 len, Word16 *ind );
30 :
31 :
32 : /*-----------------------------------------------------------------*
33 : * mslvq_fx()
34 : *
35 : * Encodes the LSF residual
36 : *-----------------------------------------------------------------*/
37 5070 : Word32 mslvq_fx(
38 : Word16 *pTmp, /* i : M-dimensional input vector x2.56*/
39 : Word16 *quant, /* o : quantized vector x2.56*/
40 : Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) Q13*/
41 : Word16 *idx_lead, /* o : leader index for each 8-dim subvector */
42 : Word16 *idx_scale, /* o : scale index for each subvector */
43 : Word16 *w, /* i : weights for LSF quantization Q10*/
44 : Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/
45 : Word16 mode_glb, /* i : LVQ coding mode */
46 : Word16 pred_flag, /* i : prediction flag (0: safety net, 1,2 - predictive )*/
47 : Word16 no_scales[][2] )
48 : {
49 : Word32 dist, L_tmp;
50 : const Word16 *p_scales, *p_sigma, *p_inv_sigma;
51 : const Word16 *p_no_lead;
52 : Word16 *p_no_scales;
53 :
54 :
55 5070 : dist = L_deposit_l( 0 );
56 5070 : p_no_scales = no_scales[mode_glb];
57 5070 : move16();
58 :
59 5070 : IF( pred_flag == 0 )
60 : {
61 1194 : p_sigma = sigma_MSLVQ_fx[mode]; // Qlog2(2.56)
62 : /* inverse sigma is precomputed to save complexity */
63 1194 : p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15
64 1194 : p_scales = scales_fx[mode_glb]; // Q11
65 1194 : p_no_lead = no_lead_fx[mode_glb]; // Q0
66 : }
67 : ELSE
68 : {
69 3876 : p_sigma = sigma_p_fx[mode]; // Qlog2(2.56)
70 : /* inverse sigma is precomputed to save complexity */
71 3876 : p_inv_sigma = inv_sigma_p_fx[mode]; // Q15
72 3876 : p_scales = scales_p_fx[mode_glb]; // Q11
73 3876 : p_no_lead = no_lead_p_fx[mode_glb]; // Q0
74 : }
75 :
76 : /* first subvector */
77 5070 : dist = quantize_data_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale,
78 5070 : p_sigma, p_inv_sigma, p_scales, p_no_scales[0], p_no_lead );
79 : /* second subvector */
80 5070 : L_tmp = quantize_data_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM,
81 : cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1],
82 : p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES,
83 5070 : p_no_scales[1], p_no_lead + MAX_NO_SCALES );
84 :
85 5070 : dist = L_add( dist, L_tmp );
86 :
87 5070 : return dist;
88 : }
89 :
90 :
91 : /*-----------------------------------------------------------------*
92 : * q_data()
93 : *
94 : * (used for LSF quantization in CNG)
95 : *-----------------------------------------------------------------*/
96 :
97 0 : static Word32 q_data_fx(
98 : Word16 *pTmp1, /* i: M-dimensional input vector x2.56 */
99 : const Word16 *w1, /* i: M-dimensional weight vector Q8 */
100 : Word16 *quant, /* o: quantized vector x2.56 */
101 : Word16 *cv_out, /* o: non-scaled lattice codevector x2.56 */
102 : Word16 *idx_lead, /* o: leader indexes for each subvector */
103 : Word16 *idx_scale, /* o: scale indexes for each subvector */
104 : const Word16 *p_sigma, /* i: standard deviation x2.56 */
105 : const Word16 *p_inv_sigma, /* i: inverse standard deviation Q15 */
106 : const Word16 *p_scales, /* i: scale values Q11 */
107 : Word16 *p_no_scales, /* i: number of scales/truncations for each subvector */
108 : const Word16 *p_no_lead /* i: number of leaders for each truncation and each subvector */
109 : )
110 : {
111 : Word32 dist, L_tmp;
112 : /* first subvector */
113 0 : dist = quantize_data_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale,
114 0 : p_sigma, p_inv_sigma, p_scales, p_no_scales[0], p_no_lead );
115 : /* second subvector */
116 0 : L_tmp = quantize_data_fx( pTmp1 + LATTICE_DIM, w1 + LATTICE_DIM,
117 : quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1],
118 : p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES,
119 0 : p_no_scales[1], p_no_lead + MAX_NO_SCALES );
120 :
121 0 : dist = L_add( dist, L_tmp );
122 :
123 0 : return dist;
124 : }
125 :
126 448 : static Word32 q_data_ivas_fx(
127 : Word16 *pTmp1, /* i: M-dimensional input vector x2.56 */
128 : const Word16 *w1, /* i: M-dimensional weight vector Q8 */
129 : Word16 *quant, /* o: quantized vector x2.56 */
130 : Word16 *cv_out, /* o: non-scaled lattice codevector x2.56 */
131 : Word16 *idx_lead, /* o: leader indexes for each subvector */
132 : Word16 *idx_scale, /* o: scale indexes for each subvector */
133 : const Word16 *p_sigma, /* i: standard deviation x2.56 */
134 : const Word16 *p_inv_sigma, /* i: inverse standard deviation Q15 */
135 : const Word16 *p_scales, /* i: scale values Q11 */
136 : const Word16 *p_no_lead /* i: number of leaders for each truncation and each subvector */
137 : )
138 : {
139 : Word32 dist, L_tmp;
140 : /* first subvector */
141 448 : dist = quantize_data_ivas_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale,
142 : p_sigma, p_inv_sigma, p_scales, p_no_lead );
143 : /* second subvector */
144 448 : L_tmp = quantize_data_ivas_fx( pTmp1 + LATTICE_DIM, w1 + LATTICE_DIM,
145 : quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1],
146 : p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES,
147 : p_no_lead + MAX_NO_SCALES );
148 :
149 448 : dist = L_add( dist, L_tmp );
150 :
151 448 : return dist;
152 : }
153 : /*-----------------------------------------------------------------*
154 : * mslvq_cng()
155 : *
156 : * Encodes the LSF residual in SID frames with LVQ
157 : * LVQ has separate codebook for each individual first stage index
158 : *-----------------------------------------------------------------*/
159 :
160 :
161 0 : Word32 mslvq_cng_fx(
162 : Word16 idx_cv, /* i : index of cv from previous stage */
163 : Word16 *pTmp, /* i : 16 dimensional input vector x2.56*/
164 : Word16 *quant, /* o : quantized vector x2.56*/
165 : Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) Q13*/
166 : Word16 *idx_lead, /* o : leader index for each 8-dim subvector */
167 : Word16 *idx_scale, /* o : scale index for each subvector */
168 : const Word16 *w, /* i : weights for LSF quantization Q10*/
169 : Word16 *no_scales )
170 : {
171 : Word32 dist;
172 : const Word16 *p_scales, *p_sigma, *p_inv_sigma;
173 : const Word16 *p_no_lead;
174 : Word16 *p_no_scales;
175 : Word16 mode_glb, mode, i;
176 : Word16 pTmp1[M], w1[M];
177 :
178 0 : dist = L_deposit_l( 0 );
179 0 : mode = add( LVQ_COD_MODES, idx_cv );
180 0 : move16();
181 :
182 : /* for CNG there is only one bitrate but several lattice quantizer structures,
183 : depending on the previous VQ stage */
184 0 : mode_glb = add( START_CNG, idx_cv );
185 0 : move16();
186 :
187 0 : p_sigma = sigma_MSLVQ_fx[mode]; // x2.56
188 0 : move16();
189 0 : p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15
190 0 : move16();
191 0 : p_scales = scales_fx[mode_glb]; // Q11
192 0 : move16();
193 0 : p_no_lead = no_lead_fx[mode_glb]; // Q0
194 0 : move16();
195 0 : p_no_scales = &no_scales[( mode_glb << 1 )];
196 0 : move16();
197 :
198 : /* check if LSF component permutation is needed or not */
199 0 : IF( cng_sort[idx_cv] )
200 : {
201 0 : FOR( i = 0; i < M; i++ )
202 : {
203 0 : pTmp1[i] = pTmp[i];
204 0 : move16();
205 0 : w1[i] = w[i];
206 0 : move16();
207 : }
208 : /* sorting the quantizer input and the corresponding weights according to the specified permutations */
209 0 : permute_fx( pTmp1, perm_MSLVQ[idx_cv] );
210 0 : permute_fx( w1, perm_MSLVQ[idx_cv] );
211 :
212 0 : dist = q_data_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_scales, p_no_lead );
213 : /* permute back */
214 0 : permute_fx( quant, perm_MSLVQ[idx_cv] );
215 : }
216 : ELSE
217 : {
218 0 : dist = q_data_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_scales, p_no_lead );
219 : }
220 :
221 0 : return dist;
222 : }
223 :
224 448 : Word32 mslvq_cng_ivas_fx(
225 : Word16 idx_cv, /* i : index of cv from previous stage */
226 : Word16 *pTmp, /* i : 16 dimensional input vector x2.56*/
227 : Word16 *quant, /* o : quantized vector x2.56*/
228 : Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) Q13*/
229 : Word16 *idx_lead, /* o : leader index for each 8-dim subvector */
230 : Word16 *idx_scale, /* o : scale index for each subvector */
231 : const Word16 *w /* i : weights for LSF quantization Q10*/
232 : )
233 : {
234 : Word32 dist;
235 : const Word16 *p_scales, *p_sigma, *p_inv_sigma;
236 : Word16 no_scales[2];
237 : Word16 mode_glb, mode, i;
238 : Word16 pTmp1[M], w1[M];
239 : Word16 p_no_lead[MAX_NO_SCALES * 2];
240 :
241 448 : dist = L_deposit_l( 0 );
242 448 : mode = add( LVQ_COD_MODES, idx_cv );
243 448 : move16();
244 :
245 : /* for CNG there is only one bitrate but several lattice quantizer structures,
246 : depending on the previous VQ stage */
247 448 : mode_glb = add( START_CNG_IVAS, idx_cv );
248 448 : move16();
249 :
250 448 : p_sigma = sigma_MSLVQ_fx[mode]; // x2.56
251 448 : move16();
252 448 : p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15
253 448 : move16();
254 448 : p_scales = scales_ivas_fx[mode_glb]; // Q11
255 448 : move16();
256 :
257 448 : no_scales[0] = 0;
258 448 : no_scales[1] = 0;
259 :
260 1792 : FOR( i = 0; i < MAX_NO_SCALES; i++ )
261 : {
262 1344 : p_no_lead[i] = (Word16) leaders_short[no_lead_idx[mode_glb][0]][i];
263 1344 : p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[no_lead_idx[mode_glb][1]][i];
264 :
265 1344 : IF( p_scales[i] > 0 )
266 : {
267 1174 : no_scales[0] += 1;
268 : }
269 1344 : IF( p_scales[i + MAX_NO_SCALES] > 0 )
270 : {
271 1306 : no_scales[1] += 1;
272 : }
273 : }
274 :
275 : /* check if LSF component permutation is needed or not */
276 448 : IF( cng_sort[idx_cv] )
277 : {
278 7497 : FOR( i = 0; i < M; i++ )
279 : {
280 7056 : pTmp1[i] = pTmp[i];
281 7056 : move16();
282 7056 : w1[i] = w[i];
283 7056 : move16();
284 : }
285 : /* sorting the quantizer input and the corresponding weights according to the specified permutations */
286 441 : permute_fx( pTmp1, perm_MSLVQ[idx_cv] );
287 441 : permute_fx( w1, perm_MSLVQ[idx_cv] );
288 :
289 441 : dist = q_data_ivas_fx( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
290 : /* permute back */
291 441 : permute_fx( quant, perm_MSLVQ[idx_cv] );
292 : }
293 : ELSE
294 : {
295 7 : dist = q_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
296 : }
297 :
298 448 : return dist;
299 : }
300 : /*-----------------------------------------------------------------*
301 : * prepare_data_fx()
302 : *
303 : *-----------------------------------------------------------------*/
304 1373643 : static void prepare_data_fx(
305 : Word16 *xsort, /* o: normalized absolute valued input vector Q10 */
306 : Word16 *sign, /* o: signs of input vector */
307 : Word16 *data, /* i: input vector x2.56 */
308 : Word32 *w, /* o; scaled weights Q-4 */
309 : const Word16 *w_in, /* i: input weights Q8 */
310 : const Word16 *sigma, /* i: standard deviation x2.56 */
311 : const Word16 *inv_sigma, /* i: inverse standard deviation Q15 */
312 : Word16 *p_sig /* o: parity of input vector */
313 : )
314 : {
315 : Word16 j, sig;
316 : Word16 s, inv_s;
317 : Word32 L_in;
318 :
319 :
320 : /* scale data */
321 12362787 : FOR( j = 0; j < LATTICE_DIM; j++ )
322 : {
323 10989144 : inv_s = inv_sigma[j];
324 10989144 : move16(); /*Q15 */
325 10989144 : s = sigma[j];
326 10989144 : move16(); /*Qx2.56 */
327 10989144 : L_in = L_mult0( inv_s, data[j] );
328 10989144 : move16(); /*x2.56 + Q15 */
329 10989144 : L_in = Mult_32_16( L_in, 100 ); /* 100 = 25*4 Q15+6+4 = Q25 -Q15 = Q8 */
330 10989144 : xsort[j] = extract_l( L_shl( L_in, 2 ) ); /*Q10 */
331 :
332 10989144 : w[j] = L_shr( L_mult0( s, s ), 4 ); /*x2.56 + x2.56 - Q4 */
333 10989144 : w[j] = Mult_32_16( L_shl( w_in[j], 5 ), extract_l( w[j] ) ); /*Q6 + Q5 +x2.56 +x2.56- Q15 */
334 10989144 : w[j] = L_shl( w[j], 2 );
335 : }
336 :
337 :
338 1373643 : sig = 1;
339 1373643 : move16();
340 12362787 : FOR( j = 0; j < LATTICE_DIM; j++ ){
341 10989144 : IF( xsort[j] < 0 ){
342 5203988 : sign[j] = -1;
343 5203988 : move16();
344 5203988 : sig = negate( sig );
345 5203988 : move16();
346 5203988 : xsort[j] = negate( xsort[j] ); /*Q10 */
347 : }
348 : ELSE
349 : {
350 5785156 : sign[j] = 1;
351 5785156 : move16();
352 : }
353 : }
354 1373643 : *p_sig = sig;
355 1373643 : move16();
356 :
357 1373643 : return;
358 : }
359 :
360 : /*-----------------------------------------------------------------*
361 : * calculate_min_dist()
362 : *
363 : *-----------------------------------------------------------------*/
364 1373643 : static Word32 calculate_min_dist_fx(
365 : Word16 cv_pot[LATTICE_DIM], /* i: sorted absolute valued normalized input vector Q10 */
366 : Word16 no_scales, /* i: number of scales */
367 : const Word16 *scale, /* i: scale values Q11 */
368 : const Word32 *w, /* i: scaled weights Q-4 */
369 : Word16 *p_best_scale, /* o: pointer to obtained scale value */
370 : Word16 *p_best_idx, /* o: pointer to obtained leader index */
371 : const Word16 *no_leaders, /* i: number of leaders for each truncation */
372 : Word16 sig, /* i: parity of input vector */
373 : Word16 *indx /* i: permutation vector indicating the order of the sorted input vector */
374 : )
375 : {
376 1373643 : Word16 k, l, j, best_scale = -1, best_idx = -1;
377 : Word16 s, p;
378 : Word32 tmp_dist, min_dist;
379 : Word32 w_norm[LATTICE_DIM];
380 :
381 :
382 : Word16 wx[LATTICE_DIM];
383 : const Word16 *pl_crt;
384 : Word32 sum1[NO_LEADERS], sum2[NO_LEADERS];
385 : Word16 s2, p1;
386 1373643 : Word16 low_prec = 0;
387 : Word16 max_nb, nb, max_nb1;
388 :
389 1373643 : max_nb = 0;
390 12362787 : FOR( l = 0; l < LATTICE_DIM; l++ )
391 : {
392 10989144 : nb = sub( 31, norm_l( w[l] ) );
393 10989144 : if ( GT_16( nb, max_nb ) )
394 : {
395 1665964 : max_nb = nb;
396 1665964 : move16();
397 : }
398 : }
399 1373643 : max_nb1 = 0;
400 12362787 : FOR( l = 0; l < LATTICE_DIM; l++ )
401 : {
402 10989144 : nb = sub( 15, norm_s( cv_pot[l] ) );
403 10989144 : if ( GT_16( nb, max_nb1 ) )
404 : {
405 1395393 : max_nb1 = nb;
406 1395393 : move16();
407 : }
408 : }
409 1373643 : nb = sub( max_nb1, 13 );
410 1373643 : if ( nb < 0 )
411 : {
412 1280848 : nb = 0;
413 : }
414 :
415 1373643 : nb = sub( 30, add( max_nb, nb ) );
416 : /* sorting the weight based on the ordering indx[] of the input vector */
417 12362787 : FOR( l = 0; l < LATTICE_DIM; l++ )
418 : {
419 10989144 : w_norm[l] = L_shl( w[indx[l]], nb ); /* Q(26-nb) here nb = 30-nb;*/
420 : }
421 :
422 : /* compare first with the origin */
423 1373643 : min_dist = L_deposit_l( 0 );
424 12362787 : FOR( j = 0; j < LATTICE_DIM; j++ )
425 : {
426 10989144 : wx[j] = extract_h( L_shl( Mult_32_16( w_norm[j], cv_pot[j] ), 3 ) ); /*Q(26-nb) + Q10 -Q15 +Q2 -Q16 = Q(7-nb) //it is multiplicated by 2 */
427 : }
428 :
429 1373643 : s = scale[0];
430 1373643 : move16(); /*Q11 */
431 1373643 : s2 = extract_h( L_shl( L_mult( s, s ), 3 ) ); /*Q11+Q11++Q1+Q3-Q16 = Q10 */
432 1373643 : pl_crt = &pl_HQ_fx[0];
433 1373643 : move16();
434 :
435 19163004 : FOR( j = 0; j < no_leaders[0]; j++ )
436 : {
437 17789361 : sum1[j] = L_deposit_l( 0 );
438 17789361 : sum2[j] = L_deposit_l( 0 );
439 :
440 17789361 : l = 0;
441 17789361 : move16();
442 116342478 : WHILE( l < LATTICE_DIM - 1 )
443 : {
444 98553117 : p = *pl_crt;
445 98553117 : IF( p )
446 : {
447 88729224 : sum1[j] = L_mac( sum1[j], wx[l], p ); /* Q(7-nb) + Q1 + Q1 = Q(9-nb) */
448 88729224 : p1 = i_mult2( p, p ); /*Q2 */
449 88729224 : sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb) */
450 88729224 : pl_crt++;
451 88729224 : l++;
452 : }
453 : ELSE
454 : {
455 9823893 : pl_crt += ( sub( LATTICE_DIM, l ) );
456 9823893 : l = LATTICE_DIM;
457 9823893 : move16();
458 : }
459 : }
460 17789361 : IF( EQ_16( l, LATTICE_DIM - 1 ) )
461 : {
462 7965468 : p = *pl_crt;
463 : /* if it went up to 7th position */
464 7965468 : IF( pl_par[j] )
465 : {
466 6375941 : IF( NE_16( sig, pl_par[j] ) )
467 : {
468 3167508 : sum1[j] = L_msu( sum1[j], wx[l], p ); /* Q(7-nb) + Q1 + Q1 = Q(9-nb) //Q-7 + Q1 + Q1 = Q-5 */
469 3167508 : p1 = i_mult2( p, p ); /*Q2 */
470 3167508 : sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb) //Q12 + Q2 -Q15 = Q-1 */
471 3167508 : pl_crt++;
472 : }
473 : ELSE
474 : {
475 3208433 : sum1[j] = L_mac( sum1[j], wx[l], p ); /* Q(7-nb) + Q1 + Q1 = Q(9-nb) //Q-7 + Q1 + Q1 = Q-5 */
476 3208433 : p1 = i_mult2( p, p ); /*Q2 */
477 3208433 : sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb) //Q12 + Q2 -Q15 = Q-1 */
478 3208433 : pl_crt++;
479 : }
480 : }
481 : ELSE
482 : {
483 1589527 : sum1[j] = L_mac( sum1[j], wx[l], p ); /* Q(7-nb) + Q1 + Q1 = Q(9-nb) //Q-7 + Q1 + Q1 = Q-5 */
484 1589527 : p1 = i_mult2( p, p ); /*Q2 */
485 1589527 : sum2[j] = L_add( sum2[j], Mult_32_16( w_norm[l], p1 ) ); /* Q(26-nb) + Q2 -Q15 = Q(13-nb) // Q12 + Q2 -Q15 = Q-1 */
486 1589527 : pl_crt++;
487 : }
488 : }
489 : /* distance between the potential codevector and the input calculated in ordered space */
490 17789361 : tmp_dist = L_sub( Mult_32_16( sum2[j], s2 ), Mult_32_16( L_shl( sum1[j], 3 ), s ) ); /* Q(13-nb) + Q10 -Q15= Q(8-nb) Q(9-nb) + Q3+Q11 -Q15 = Q(8-nb) */
491 17789361 : IF( LT_32( tmp_dist, min_dist ) )
492 : {
493 6235664 : min_dist = L_add( tmp_dist, 0 );
494 6235664 : best_scale = 0;
495 6235664 : move16(); /* scale(truncation) index of potential codevector */
496 6235664 : best_idx = j;
497 6235664 : move16(); /* leader class index of potential codevector */
498 : }
499 : }
500 1373643 : tmp_dist = L_add( min_dist, 1 ); /* initialization */
501 4118915 : FOR( k = 1; k < no_scales; k++ )
502 : {
503 2745272 : s = scale[k];
504 2745272 : move16(); /*Q11 */
505 2745272 : IF( LE_16( 16, norm_l( s ) ) )
506 : {
507 2384384 : s2 = extract_h( L_shl( L_mult( s, s ), 1 ) ); /*Q11+Q11+Q1+Q1-Q16 = Q7 */
508 2384384 : low_prec = 1;
509 : }
510 : ELSE
511 : {
512 360888 : s2 = extract_h( L_shl( L_mult( s, s ), 3 ) ); /*Q11+Q11++Q1+Q3-Q16 = Q10 */
513 : }
514 25340981 : FOR( j = 0; j < no_leaders[k]; j++ )
515 : {
516 : /* distance between the potential codevector and the input calculated in ordered space */
517 22595709 : IF( EQ_16( low_prec, 1 ) )
518 : {
519 22595709 : tmp_dist = L_sub( L_shl( Mult_32_16( sum2[j], s2 ), 2 ), Mult_32_16( L_shl( sum1[j], 3 ), s ) ); /* Q-1 + Q7 + 3-Q15= Q-6 Q-5 + Q3+Q11 -Q15 = Q-6 */
520 : }
521 : ELSE
522 : {
523 0 : tmp_dist = L_sub( Mult_32_16( sum2[j], s2 ), Mult_32_16( L_shl( sum1[j], 3 ), s ) ); /* Q-1 + Q10 -Q15= Q-6 Q-5 + Q3+Q11 -Q15 = Q-6 */
524 : }
525 22595709 : IF( LT_32( tmp_dist, min_dist ) )
526 : {
527 1134184 : min_dist = L_add( tmp_dist, 0 );
528 1134184 : best_scale = k;
529 1134184 : move16(); /* scale(truncation) index of the potential codevector */
530 1134184 : best_idx = j;
531 1134184 : move16(); /* leader class index of the potential codevector */
532 : }
533 : }
534 2745272 : low_prec = 0;
535 2745272 : move16();
536 : }
537 1373643 : *p_best_scale = best_scale;
538 1373643 : move16();
539 1373643 : *p_best_idx = best_idx;
540 1373643 : move16();
541 :
542 1373643 : return min_dist;
543 : }
544 :
545 : /*-----------------------------------------------------------------*
546 : * quantize_data_fx()
547 : *
548 : *-----------------------------------------------------------------*/
549 :
550 :
551 10140 : static Word32 quantize_data_fx(
552 : Word16 *data, /* i : residual LSF data to quantize x2.56*/
553 : const Word16 *w_in, /* i : weights Q10*/
554 : Word16 *qin, /* o : quantized output (scaled) x2.56*/
555 : Word16 *cv_out, /* o : codevectors Q1*/
556 : Word16 *idx_lead, /* o : leader indexes for each subvector */
557 : Word16 *idx_scale, /* o : scale indexes for each subvector */
558 : const Word16 *sigma, /* i : standard deviation x2.56 */
559 : const Word16 *inv_sigma, /* i : inverse of standard deviation Q15 */
560 : const Word16 *scale, /* i : scales for each truncation Q11*/
561 : Word16 no_scales, /* i : number of truncation for each subvector */
562 : const Word16 *no_leaders /* i : number of leader vectors for each truncation of each subvector */
563 : )
564 : {
565 : Word16 j;
566 : Word32 w[LATTICE_DIM];
567 10140 : Word32 min_dist = 0;
568 10140 : Word16 best_idx = 0, best_scale = -1;
569 : Word16 s;
570 : Word16 indx[LATTICE_DIM];
571 : Word16 sig, sign[LATTICE_DIM];
572 : Word16 cv_pot[LATTICE_DIM];
573 : Word16 id[8];
574 : Word16 smallest;
575 : Word32 L_tmp;
576 :
577 10140 : IF( no_scales > 0 )
578 : {
579 10140 : prepare_data_fx( cv_pot, sign, data, w, w_in, sigma, inv_sigma, &sig );
580 10140 : move16();
581 : /* sorting of the input vector based on its absolute values; indx: permutation corresponding to the sorting */
582 10140 : sort_desc_ind_fx( cv_pot, LATTICE_DIM, indx );
583 10140 : smallest = indx[LATTICE_DIM - 1];
584 10140 : move16();
585 :
586 10140 : min_dist = calculate_min_dist_fx( cv_pot, no_scales, scale, w, &best_scale, &best_idx, no_leaders, sig, indx );
587 :
588 10140 : IF( GT_16( best_scale, -1 ) )
589 : {
590 90972 : FOR( j = 0; j < LATTICE_DIM; j++ )
591 : {
592 80864 : id[indx[j]] = j;
593 : }
594 90972 : FOR( j = 0; j < LATTICE_DIM; j++ )
595 : {
596 80864 : cv_out[j] = i_mult2( sign[j], pl_HQ_fx[best_idx * LATTICE_DIM + id[j]] );
597 80864 : move16();
598 : }
599 10108 : IF( pl_par[best_idx] )
600 : {
601 4153 : IF( NE_16( sig, pl_par[best_idx] ) )
602 : {
603 1130 : cv_out[smallest] = negate( cv_out[smallest] );
604 : }
605 : }
606 10108 : s = scale[best_scale];
607 10108 : move16(); /*Q11 */
608 90972 : FOR( j = 0; j < LATTICE_DIM; j++ )
609 : {
610 : /*qin[j] = s * cv_out[j] * sigma[j]; */
611 80864 : L_tmp = L_mult( cv_out[j], s ); /* Q1+Q11+Q1 = Q13 */
612 80864 : L_tmp = Mult_32_16( L_tmp, shl( sigma[j], 2 ) ); /* Q13 + Q2 +x2.56 -Q15 */
613 :
614 80864 : qin[j] = extract_l( L_tmp ); /*x2.56 */
615 : }
616 10108 : *idx_lead = best_idx;
617 10108 : move16();
618 10108 : *idx_scale = best_scale;
619 10108 : move16();
620 : }
621 : ELSE
622 : {
623 288 : FOR( j = 0; j < LATTICE_DIM; j++ )
624 : {
625 256 : qin[j] = 0;
626 256 : move16();
627 : }
628 :
629 32 : *idx_lead = best_idx;
630 32 : move16();
631 32 : *idx_scale = best_scale;
632 32 : move16();
633 : }
634 : }
635 : ELSE
636 : {
637 0 : *idx_lead = 0;
638 0 : move16();
639 0 : *idx_scale = -1;
640 0 : move16();
641 :
642 0 : FOR( j = 0; j < LATTICE_DIM; j++ )
643 : {
644 0 : cv_out[j] = 0;
645 0 : move16();
646 0 : qin[j] = 0;
647 0 : move16();
648 : }
649 : }
650 :
651 10140 : return min_dist;
652 : }
653 :
654 1379757 : Word32 quantize_data_ivas_fx(
655 : Word16 *data, /* i : residual LSF data to quantize x2.56*/
656 : const Word16 *w_in, /* i : weights Q10*/
657 : Word16 *qin, /* o : quantized output (scaled) x2.56*/
658 : Word16 *cv_out, /* o : codevectors Q1*/
659 : Word16 *idx_lead, /* o : leader indexes for each subvector */
660 : Word16 *idx_scale, /* o : scale indexes for each subvector */
661 : const Word16 *sigma, /* i : standard deviation x2.56 */
662 : const Word16 *inv_sigma, /* i : inverse of standard deviation Q15 */
663 : const Word16 *scale, /* i : scales for each truncation Q11*/
664 : const Word16 *no_leaders /* i : number of leader vectors for each truncation of each subvector */
665 : )
666 : {
667 : Word16 j;
668 : Word32 w[LATTICE_DIM];
669 1379757 : Word32 min_dist = 0;
670 1379757 : Word16 best_idx = 0, best_scale = -1;
671 : Word16 s;
672 : Word16 indx[LATTICE_DIM];
673 : Word16 sig, sign[LATTICE_DIM];
674 : Word16 cv_pot[LATTICE_DIM];
675 : Word16 id[8];
676 : Word16 smallest;
677 : Word32 L_tmp;
678 :
679 1379757 : IF( scale[0] > 0 )
680 : {
681 1363503 : prepare_data_fx( cv_pot, sign, data, w, w_in, sigma, inv_sigma, &sig );
682 1363503 : move16();
683 : /* sorting of the input vector based on its absolute values; indx: permutation corresponding to the sorting */
684 1363503 : sort_desc_ind_fx( cv_pot, LATTICE_DIM, indx );
685 1363503 : smallest = indx[LATTICE_DIM - 1];
686 1363503 : move16();
687 :
688 1363503 : min_dist = calculate_min_dist_fx( cv_pot, MAX_NO_SCALES, scale, w, &best_scale, &best_idx, no_leaders, sig, indx );
689 :
690 1363503 : IF( GT_16( best_scale, -1 ) )
691 : {
692 12183534 : FOR( j = 0; j < LATTICE_DIM; j++ )
693 : {
694 10829808 : id[indx[j]] = j;
695 : }
696 12183534 : FOR( j = 0; j < LATTICE_DIM; j++ )
697 : {
698 10829808 : cv_out[j] = i_mult2( sign[j], pl_HQ_fx[best_idx * LATTICE_DIM + id[j]] );
699 10829808 : move16();
700 : }
701 1353726 : IF( pl_par[best_idx] )
702 : {
703 571082 : IF( NE_16( sig, pl_par[best_idx] ) )
704 : {
705 148660 : cv_out[smallest] = negate( cv_out[smallest] );
706 : }
707 : }
708 1353726 : s = scale[best_scale];
709 1353726 : move16(); /*Q11 */
710 12183534 : FOR( j = 0; j < LATTICE_DIM; j++ )
711 : {
712 : /*qin[j] = s * cv_out[j] * sigma[j]; */
713 10829808 : L_tmp = L_mult( cv_out[j], s ); /* Q1+Q11+Q1 = Q13 */
714 10829808 : L_tmp = Mult_32_16( L_tmp, shl( sigma[j], 2 ) ); /* Q13 + Q2 +x2.56 -Q15 */
715 :
716 10829808 : qin[j] = extract_l( L_tmp ); /*x2.56 */
717 : }
718 1353726 : *idx_lead = best_idx;
719 1353726 : move16();
720 1353726 : *idx_scale = best_scale;
721 1353726 : move16();
722 : }
723 : ELSE
724 : {
725 87993 : FOR( j = 0; j < LATTICE_DIM; j++ )
726 : {
727 78216 : qin[j] = 0;
728 78216 : move16();
729 : }
730 :
731 9777 : *idx_lead = best_idx;
732 9777 : move16();
733 9777 : *idx_scale = best_scale;
734 9777 : move16();
735 : }
736 : }
737 : ELSE
738 : {
739 16254 : *idx_lead = 0;
740 16254 : move16();
741 16254 : *idx_scale = -1;
742 16254 : move16();
743 :
744 146286 : FOR( j = 0; j < LATTICE_DIM; j++ )
745 : {
746 130032 : cv_out[j] = 0;
747 130032 : move16();
748 130032 : qin[j] = 0;
749 130032 : move16();
750 : }
751 : }
752 :
753 1379757 : return min_dist;
754 : }
755 : /*-----------------------------------------------------------------*
756 : * sort_desc_ind()
757 : *
758 : * sorts in descending order and computes indices in the sorted vector
759 : *-----------------------------------------------------------------*/
760 :
761 1373643 : static void sort_desc_ind_fx(
762 : Word16 *s, /* i/o: vector to be sorted Q10*/
763 : Word16 len, /* i : vector length */
764 : Word16 *ind /* o : array of indices */
765 : )
766 : {
767 : Word16 i, k, sorted, a;
768 : Word16 t;
769 :
770 12362787 : FOR( i = 0; i < len; i++ )
771 : {
772 10989144 : ind[i] = i;
773 10989144 : move16();
774 : }
775 1373643 : sorted = 0;
776 9090554 : FOR( k = ( len - 1 ); k > 0; k-- )
777 : {
778 8641882 : IF( sorted )
779 : {
780 924971 : BREAK;
781 : }
782 :
783 7716911 : sorted = 1;
784 7716911 : move16();
785 42802863 : FOR( i = 0; i < k; i++ )
786 : {
787 35085952 : IF( LT_16( s[i], s[i + 1] ) )
788 : {
789 18889132 : sorted = 0;
790 18889132 : move16();
791 18889132 : t = s[i];
792 18889132 : move16();
793 18889132 : s[i] = s[i + 1];
794 18889132 : move16();
795 18889132 : s[i + 1] = t;
796 18889132 : move16();
797 18889132 : a = ind[i];
798 18889132 : move16();
799 18889132 : ind[i] = ind[i + 1];
800 18889132 : move16();
801 18889132 : ind[i + 1] = a;
802 18889132 : move16();
803 : }
804 : }
805 : }
806 :
807 1373643 : return;
808 : }
809 :
810 : /*-----------------------------------------------------------------*
811 : * index_lvq()
812 : *
813 : * sorts in descending order and computes indices in the sorted vector
814 : *-----------------------------------------------------------------*/
815 2535 : void index_lvq_fx(
816 : Word16 *quant, /* i : codevector to be indexed (2 8-dim subvectors) Q13*/
817 : Word16 *idx_lead, /* i : leader class index for each subvector */
818 : Word16 *idx_scale, /* i :scale index for each subvector */
819 : Word16 mode, /* i : integer signalling the quantizer structure for the current bitrate */
820 : Word16 *index, /* o : encoded index (represented on 3 short each with 15 bits ) */
821 : Word32 *p_offset_scale1, /* i : scales for first subvector */
822 : Word32 *p_offset_scale2, /* i : scales for second subvector */
823 : Word16 *p_no_scales /* i : number of scales for each subvector */
824 : )
825 : {
826 : Word32 index1, index2;
827 : Word16 len_offset;
828 : Word64 idx64;
829 : Word64 index2_64;
830 :
831 2535 : len_offset = add( MAX_NO_SCALES, 1 );
832 2535 : move16();
833 :
834 2535 : index1 = 0;
835 2535 : move16();
836 :
837 : /* for first subvector */
838 2535 : IF( GT_16( idx_scale[0], -1 ) )
839 : {
840 2535 : index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[( mode * len_offset ) + idx_scale[0]] ) );
841 : }
842 :
843 : /* for second subvector */
844 2535 : index2 = L_deposit_l( 0 );
845 :
846 2535 : IF( GT_16( idx_scale[1], -1 ) )
847 : {
848 2515 : index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[( mode * len_offset ) + idx_scale[1]] ) );
849 : }
850 2535 : idx64 = W_mult0_32_32( index1, p_offset_scale2[mode * len_offset + p_no_scales[mode * 2 + 1]] );
851 2535 : index2_64 = W_deposit32_l( index2 );
852 2535 : idx64 = W_add_nosat( idx64, index2_64 );
853 :
854 : /* convert to 3 short */
855 2535 : index[0] = ( ( idx64 ) & ( 0x7fff ) );
856 2535 : move16();
857 2535 : index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff );
858 2535 : move16();
859 2535 : index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff );
860 2535 : move16();
861 2535 : return;
862 : }
863 :
864 344321 : void index_lvq_ivas_fx(
865 : Word16 *quant, /* i : codevector to be indexed (2 8-dim subvectors) Q13*/
866 : Word16 *idx_lead, /* i : leader class index for each subvector */
867 : Word16 *idx_scale, /* i :scale index for each subvector */
868 : Word16 mode, /* i : integer signalling the quantizer structure for the current bitrate */
869 : Word16 *index, /* o : encoded index (represented on 3 short each with 15 bits ) */
870 : const Word16 prediction_flag )
871 : {
872 : Word32 index1, index2;
873 : UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
874 : Word64 idx64;
875 : Word64 index2_64;
876 :
877 344321 : index1 = 0;
878 344321 : move16();
879 :
880 344321 : create_offset( offset_scale1, offset_scale2, mode, prediction_flag );
881 :
882 : /* for first subvector */
883 344321 : IF( GT_16( idx_scale[0], -1 ) )
884 : {
885 344172 : index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], offset_scale1[idx_scale[0]] ) );
886 : }
887 :
888 : /* for second subvector */
889 344321 : index2 = L_deposit_l( 0 );
890 :
891 344321 : IF( GT_16( idx_scale[1], -1 ) )
892 : {
893 330775 : index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], offset_scale2[idx_scale[1]] ) );
894 : }
895 :
896 344321 : idx64 = W_mult0_32_32( index1, offset_scale2[MAX_NO_SCALES] );
897 344321 : index2_64 = W_deposit32_l( index2 );
898 344321 : idx64 = W_add_nosat( idx64, index2_64 );
899 :
900 : /* convert to 3 short */
901 344321 : index[0] = ( ( idx64 ) & ( 0x7fff ) );
902 344321 : move16();
903 344321 : index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff );
904 344321 : move16();
905 344321 : index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff );
906 344321 : move16();
907 :
908 344321 : return;
909 : }
910 : /*-----------------------------------------------------------------*
911 : * encode_comb()
912 : *
913 : * creates an index for the lattice codevector
914 : *-----------------------------------------------------------------*/
915 :
916 683366 : Word32 encode_comb_fx( /* o : index of the absolute valued codevector*/
917 : Word16 *cv, /* i : codevector to be indexed Q13*/
918 : Word16 idx_lead /* i : leader class index, to know the values */
919 : )
920 : {
921 : Word16 idx_sign, idx_ld_class;
922 : Word32 L_tmp;
923 :
924 683366 : idx_sign = encode_sign_pc1_fx( pl_par[idx_lead], cv );
925 683366 : move16();
926 683366 : idx_ld_class = index_leaders_fx( cv, idx_lead, LATTICE_DIM );
927 683366 : move16();
928 :
929 683366 : L_tmp = L_mac0( idx_ld_class, idx_sign, pi0[idx_lead] );
930 :
931 683366 : return L_tmp;
932 : }
933 :
934 : /*-----------------------------------------------------------------*
935 : * index_leaders()
936 : *
937 : * gives the index in a class of leaders without considering the sign yet
938 : *-----------------------------------------------------------------*/
939 :
940 683366 : static Word16 index_leaders_fx( /* o : index */
941 : Word16 *cv, /* i : codevector to be indexed Q13*/
942 : Word16 idx_lead, /* i : leader class index */
943 : Word16 dim /* i : vector dimension */
944 : )
945 : {
946 : Word16 index;
947 : Word16 i, no_vals_loc, nr, p[LATTICE_DIM], dim_loc;
948 : Word16 cv_copy[LATTICE_DIM], val_crt;
949 :
950 683366 : no_vals_loc = no_vals[idx_lead];
951 683366 : move16();
952 :
953 683366 : IF( EQ_16( no_vals_loc, 1 ) )
954 : {
955 71854 : return 0;
956 : }
957 :
958 5503608 : FOR( i = 0; i < LATTICE_DIM; i++ )
959 : {
960 4892096 : cv_copy[i] = abs_s( cv[i] ); /*Q13 */
961 : }
962 :
963 611512 : val_crt = vals_fx[idx_lead][0];
964 611512 : move16(); /*Q13 */
965 611512 : nr = find_pos_fx( cv_copy, dim, val_crt, p );
966 611512 : move16();
967 611512 : index = c2idx_fx( LATTICE_DIM, p, nr );
968 611512 : move16();
969 :
970 611512 : IF( EQ_16( no_vals_loc, 2 ) )
971 : {
972 425163 : return index;
973 : }
974 :
975 186349 : take_out_val_fx( cv_copy, cv_copy, val_crt, dim );
976 186349 : dim_loc = sub( dim, no_vals_ind[idx_lead][0] );
977 186349 : index = extract_l( L_mult0( index, C_VQ[dim_loc][no_vals_ind[idx_lead][1]] ) );
978 :
979 186349 : val_crt = vals_fx[idx_lead][1];
980 186349 : move16(); /*Q13 */
981 186349 : nr = find_pos_fx( cv_copy, dim_loc, val_crt, p );
982 186349 : move16();
983 186349 : index = add( index, c2idx_fx( dim_loc, p, nr ) );
984 :
985 186349 : IF( EQ_16( no_vals_loc, 3 ) )
986 : {
987 184916 : return index;
988 : }
989 :
990 1433 : take_out_val_fx( cv_copy, cv_copy, val_crt, dim_loc );
991 1433 : dim_loc = sub( dim_loc, no_vals_ind[idx_lead][1] );
992 1433 : index = extract_l( L_mult0( index, C_VQ[dim_loc][no_vals_ind[idx_lead][2]] ) );
993 :
994 1433 : val_crt = vals_fx[idx_lead][2];
995 1433 : move16(); /*Q13 */
996 1433 : nr = find_pos_fx( cv_copy, dim_loc, val_crt, p );
997 1433 : move16();
998 1433 : index = add( index, c2idx_fx( dim_loc, p, nr ) );
999 : /* maximum 4 values */
1000 :
1001 1433 : return index;
1002 : }
1003 :
1004 : /*-----------------------------------------------------------------*
1005 : * find_pos()
1006 : *
1007 : * Finds the positions in vector c for which the vector components are equal to 'arg'.
1008 : * It returns the number of such positions and their values in the array 'p'.
1009 : *-----------------------------------------------------------------*/
1010 :
1011 799294 : Word16 find_pos_fx( /* o : number of positions */
1012 : Word16 *c, /* i : input vector Q13*/
1013 : Word16 len, /* i : input vector dim */
1014 : Word16 arg, /* i : argument to be compared with Q13*/
1015 : Word16 *p /* o : vector of positions */
1016 : )
1017 : {
1018 799294 : Word16 i = 0, j = 0;
1019 :
1020 : /* how many (j) and which (p) positions are in the relation pred(arg,c[i]) */
1021 6957587 : FOR( i = 0; i < len; i++ )
1022 : {
1023 6158293 : IF( EQ_16( arg, c[i] ) )
1024 : {
1025 2135889 : p[j++] = i;
1026 2135889 : move16();
1027 : }
1028 : }
1029 :
1030 799294 : return j;
1031 : }
1032 : /*-----------------------------------------------------------------*
1033 : * encode_sign_pc1()
1034 : *
1035 : * Creates an index for signs of the significant codevector components
1036 : * Gives the index of the signs - binary representation where negative sign stands for 1
1037 : * and positive sign stands for 1.
1038 : *-----------------------------------------------------------------*/
1039 683366 : static Word16 encode_sign_pc1_fx( /* o : index of signs */
1040 : Word16 parity, /* i : parity of the leader class to which the codevector belongs */
1041 : Word16 *cv /* i : input codevector Q13*/
1042 : )
1043 : {
1044 : Word16 idx_sign;
1045 683366 : Word16 cnt, i, len = LATTICE_DIM;
1046 :
1047 683366 : idx_sign = 0;
1048 683366 : move16();
1049 683366 : cnt = 0;
1050 683366 : move16();
1051 :
1052 683366 : if ( parity )
1053 : {
1054 286810 : len = sub( len, 1 );
1055 : }
1056 :
1057 5863484 : FOR( i = 0; i < len; i++ )
1058 : {
1059 5180118 : IF( cv[i] < 0 )
1060 : {
1061 1802983 : idx_sign = add( idx_sign, ( shl( 1, cnt ) ) );
1062 1802983 : cnt = add( cnt, 1 );
1063 : }
1064 :
1065 5180118 : if ( cv[i] > 0 )
1066 : {
1067 1929526 : cnt = add( cnt, 1 );
1068 : }
1069 : }
1070 :
1071 683366 : return idx_sign;
1072 : }
1073 :
1074 : /*-----------------------------------------------------------------*
1075 : * take_out_val()
1076 : *
1077 : * removes the value val from the vector v
1078 : *-----------------------------------------------------------------*/
1079 :
1080 187782 : static void take_out_val_fx(
1081 : Word16 *v, /* i : input vector x2.56*/
1082 : Word16 *v_out, /* o : output vector without the value val */
1083 : Word16 val, /* i : value to be removed x2.56*/
1084 : Word16 len /* i : input vector length */
1085 : )
1086 : {
1087 : Word16 i, cnt;
1088 :
1089 187782 : cnt = 0;
1090 187782 : move16();
1091 :
1092 1688605 : FOR( i = 0; i < len; i++ )
1093 : {
1094 1500823 : if ( NE_16( v[i], val ) )
1095 : {
1096 1266197 : v_out[cnt++] = v[i];
1097 1266197 : move16();
1098 : }
1099 : }
1100 :
1101 187782 : return;
1102 : }
1103 :
1104 : /*-----------------------------------------------------------------------*
1105 : * c2idx()
1106 : * Indexing of vectors having k non-nul positions located in the positions
1107 : * given by the array p.
1108 : *-----------------------------------------------------------------------*/
1109 2135889 : Word16 c2idx_fx( /* o: index */
1110 : Word16 n, /* i: vector lenght */
1111 : Word16 *p, /* i: non null value positions */
1112 : Word16 k /* i: non-nullnumber of values */
1113 : )
1114 : {
1115 : Word16 skip, i, p0;
1116 : Word16 tmp;
1117 :
1118 2135889 : IF( EQ_16( k, 1 ) )
1119 : {
1120 799294 : return p[0];
1121 : }
1122 : ELSE
1123 : {
1124 1336595 : skip = 0;
1125 1336595 : move16();
1126 2396375 : FOR( i = 1; i <= p[0]; i++ )
1127 : {
1128 1059780 : skip = add( skip, C_VQ[( n - i )][( k - 1 )] ); // Q0
1129 : }
1130 :
1131 1336595 : p0 = p[0];
1132 1336595 : move16();
1133 4055516 : FOR( i = 1; i < k; i++ )
1134 : {
1135 2718921 : p[i] = sub( p[i], add( p0, 1 ) );
1136 : }
1137 1336595 : tmp = add( skip, c2idx_fx( sub( n, add( p0, 1 ) ), p + 1, sub( k, 1 ) ) );
1138 :
1139 1336595 : return tmp;
1140 : }
1141 : }
1142 :
1143 : /*-----------------------------------------------------------------*
1144 : * mslvq()
1145 : *
1146 : * Encodes the LSF residual
1147 : *-----------------------------------------------------------------*/
1148 :
1149 691115 : Word32 mslvq_ivas_16(
1150 : Word16 *pTmp, /* i : M-dimensional input vector */
1151 : Word16 *quant, /* o : quantized vector */
1152 : Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */
1153 : Word16 *idx_lead, /* o : leader index for each 8-dim subvector */
1154 : Word16 *idx_scale, /* o : scale index for each subvector */
1155 : const Word16 *w, /* i : weights for LSF quantization */
1156 : const Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/
1157 : const Word16 mode_glb, /* i : LVQ coding mode */
1158 : const Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/
1159 : /*Retunr dist in q 22*/
1160 : )
1161 : {
1162 : Word32 dist, L_tmp;
1163 : const Word16 *p_scales, *p_sigma, *p_inv_sigma;
1164 : Word16 i, tmp, tmp1;
1165 : Word16 p_no_lead[MAX_NO_SCALES * 2];
1166 691115 : dist = L_deposit_l( 0 );
1167 691115 : IF( pred_flag == 0 )
1168 : {
1169 181290 : p_sigma = sigma_MSLVQ_fx[mode];
1170 : /* inverse sigma is precomputed to save complexity */
1171 181290 : p_inv_sigma = inv_sigma_MSLVQ_fx[mode];
1172 181290 : p_scales = scales_ivas_fx[mode_glb];
1173 :
1174 181290 : tmp = no_lead_idx[mode_glb][0];
1175 181290 : move16();
1176 181290 : tmp1 = no_lead_idx[mode_glb][1];
1177 181290 : move16();
1178 181290 : test();
1179 181290 : if ( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) )
1180 : {
1181 0 : tmp = add( tmp, DELTA_LEADER );
1182 : }
1183 725160 : FOR( i = 0; i < MAX_NO_SCALES; i++ )
1184 : {
1185 543870 : p_no_lead[i] = (Word16) leaders_short[tmp][i];
1186 543870 : move16();
1187 543870 : p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i];
1188 543870 : move16();
1189 : }
1190 : }
1191 : ELSE
1192 : {
1193 509825 : IF( GE_16( pred_flag, 5 ) )
1194 : {
1195 : /* assert( pred_flag >= 12 && pred_flag <= 15 ); */
1196 : /* pred_flag is here the number of bits for MSLVQ */
1197 :
1198 3369 : p_sigma = &modified_sigma_BWE_fx[mode_glb * LATTICE_DIM];
1199 :
1200 : /* inverse sigma is precomputed to save complexity */
1201 3369 : p_inv_sigma = &inv_modified_sigma_BWE_fx[mode_glb * LATTICE_DIM];
1202 3369 : IF( mode_glb == 0 )
1203 : {
1204 3369 : p_scales = &scales_BWE_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )];
1205 :
1206 13476 : FOR( i = 0; i < MAX_NO_SCALES; i++ )
1207 : {
1208 10107 : p_no_lead[i] = (Word16) no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
1209 10107 : move16();
1210 : }
1211 : }
1212 : ELSE
1213 : {
1214 0 : p_scales = &scales_BWE_3b_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )];
1215 0 : FOR( i = 0; i < MAX_NO_SCALES; i++ )
1216 : {
1217 0 : p_no_lead[i] = (Word16) no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
1218 0 : move16();
1219 : }
1220 : }
1221 : }
1222 : ELSE
1223 : {
1224 506456 : p_sigma = sigma_p_fx[mode];
1225 :
1226 : /* inverse sigma is precomputed to save complexity */
1227 506456 : p_inv_sigma = inv_sigma_p_fx[mode];
1228 :
1229 506456 : p_scales = scales_p_ivas_fx[mode_glb];
1230 :
1231 506456 : tmp = no_lead_p_idx[mode_glb][0];
1232 506456 : move16();
1233 506456 : tmp1 = no_lead_p_idx[mode_glb][1];
1234 506456 : move16();
1235 :
1236 506456 : test();
1237 506456 : IF( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) )
1238 : {
1239 10838 : tmp = add( tmp, DELTA_LEADER );
1240 : }
1241 :
1242 506456 : test();
1243 506456 : IF( EQ_16( tmp, LIMIT_LEADER ) && ( tmp1 == 0 ) )
1244 : {
1245 0 : tmp = add( tmp, DELTA_LEADER );
1246 0 : tmp1 = add( tmp1, DELTA_LEADER );
1247 : }
1248 :
1249 2025824 : FOR( i = 0; i < MAX_NO_SCALES; i++ )
1250 : {
1251 1519368 : p_no_lead[i] = (Word16) leaders_short[tmp][i];
1252 1519368 : move16();
1253 1519368 : p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i];
1254 1519368 : move16();
1255 : }
1256 : }
1257 : }
1258 :
1259 : /* first subvector */
1260 691115 : dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale,
1261 : p_sigma, p_inv_sigma, p_scales, p_no_lead );
1262 :
1263 691115 : IF( LT_16( pred_flag, 5 ) )
1264 : {
1265 : /* second subvector */
1266 687746 : L_tmp = quantize_data_ivas_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES );
1267 :
1268 687746 : dist = L_add( dist, L_tmp );
1269 : }
1270 :
1271 691115 : return dist;
1272 : }
1273 :
1274 :
1275 3369 : UWord32 index_lvq_SHB_fx(
1276 : const Word16 idx_lead,
1277 : const Word16 idx_scale,
1278 : const Word16 nbits,
1279 : Word16 *lat_cv,
1280 : const Word16 mode )
1281 : {
1282 : UWord16 i;
1283 : const Word8 *p_no_lead;
1284 : UWord32 index;
1285 :
1286 3369 : IF( mode == 0 )
1287 : {
1288 3369 : p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3];
1289 : }
1290 : ELSE
1291 : {
1292 0 : p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3];
1293 : }
1294 :
1295 3369 : index = 0;
1296 3369 : move32();
1297 3369 : IF( GT_16( idx_lead, -1 ) )
1298 : {
1299 3369 : index = 1;
1300 3369 : move32();
1301 4452 : FOR( i = 0; i < idx_scale; i++ )
1302 : {
1303 1083 : index = index + table_no_cv[p_no_lead[i]];
1304 1083 : move32();
1305 : }
1306 :
1307 3369 : IF( idx_lead > 0 )
1308 : {
1309 3312 : index = index + table_no_cv[idx_lead];
1310 3312 : move32();
1311 : }
1312 :
1313 3369 : index = index + encode_comb_fx( lat_cv, idx_lead );
1314 3369 : move32();
1315 : }
1316 :
1317 3369 : return index;
1318 : }
|