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