Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include "options.h"
34 : #include "prot_fx.h"
35 : #include "ivas_cnst.h"
36 : #include "stl.h"
37 : #include "rom_com.h"
38 :
39 : /*-----------------------------------------------------------------*
40 : * Local functions
41 : *-----------------------------------------------------------------*/
42 :
43 : static void make_offset_scale_fx( Word16 j, const Word32 tab_no_cv[], const Word16 no_ld[], Word16 no_scl, Word32 offset_scale[][MAX_NO_SCALES + 1] );
44 : static void init_offset_fx( Word32 offset_scale1[][MAX_NO_SCALES + 1], Word32 offset_scale2[][MAX_NO_SCALES + 1], Word32 offset_scale1_p[][MAX_NO_SCALES + 1], Word32 offset_scale2_p[][MAX_NO_SCALES + 1], Word16 no_scales[][2], Word16 no_scales_p[][2] );
45 : static void decode_comb_fx( Word32 index, Word16 *cv, Word16 idx_lead );
46 : static void decode_sign_pc1_fx( Word16 *c, Word16 idx_sign, Word16 parity );
47 : static void put_value_fx( Word16 *cv, Word16 *p, Word16 val, Word16 dim, Word16 no_new_val );
48 : static void decode_leaders_fx( Word16 index, Word16 idx_lead, Word16 *cv );
49 : static void idx2c_fx( Word16 n, Word16 *p, Word16 k, Word16 val );
50 : static void divide_64_32_fx( Word16 *xs, Word32 y, Word32 *result, Word32 *rem );
51 : static Word16
52 : decode_indexes_fx( Word16 *index, Word16 no_bits, const Word16 *p_scales, Word16 *p_no_scales, Word32 *p_offset_scale1, Word32 *p_offset_scale2, Word16 *x_lvq, Word16 mode_glb, Word16 *scales );
53 : static Word16 decode_indexes_ivas_fx(
54 : Word16 *index,
55 : const Word16 no_bits,
56 : const Word16 *p_scales, // Q11
57 : const Word16 prediction_flag,
58 : Word16 *x_lvq, // Q0
59 : const Word16 mode_glb,
60 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
61 : );
62 : static Word32 divide_32_32_fx( Word32 y, Word32 x, Word32 *rem );
63 : static Word16 divide_16_16_fx( Word16 y, Word16 x, Word16 *rem );
64 : static Word16 decode_indexes_ivas_fx(
65 : Word16 *index,
66 : const Word16 no_bits,
67 : const Word16 *p_scales, // Q11
68 : const Word16 prediction_flag,
69 : Word16 *x_lvq, // Q0
70 : const Word16 mode_glb,
71 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
72 : );
73 :
74 : /* used in CNG-LP coding */
75 1733 : void permute_fx(
76 : Word16 *pTmp1, /* i/o: vector whose components are to be permuted */
77 : const Word16 *perm /* i : permutation info (indexes that should be interchanged), max two perms */
78 : )
79 : {
80 : Word16 p1, p2;
81 : Word16 tmp;
82 :
83 1733 : p1 = perm[0];
84 1733 : move16();
85 1733 : p2 = perm[1];
86 1733 : move16();
87 1733 : tmp = pTmp1[p1];
88 1733 : move16();
89 1733 : pTmp1[p1] = pTmp1[p2];
90 1733 : move16();
91 1733 : move16();
92 1733 : pTmp1[p2] = tmp;
93 1733 : move16();
94 1733 : p1 = perm[2];
95 1733 : move16();
96 :
97 1733 : IF( GT_16( p1, -1 ) )
98 : {
99 270 : p2 = perm[3];
100 270 : move16();
101 270 : tmp = pTmp1[p1];
102 270 : move16();
103 270 : pTmp1[p1] = pTmp1[p2];
104 270 : move16();
105 270 : move16();
106 270 : pTmp1[p2] = tmp;
107 270 : move16();
108 : }
109 :
110 1733 : return;
111 : }
112 :
113 :
114 7239 : void init_lvq_fx(
115 : Word32 offset_scale1[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
116 : Word32 offset_scale2[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
117 : Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
118 : Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
119 : Word16 no_scales[][2], /* o: number of truncations for each LSF subvector at each MSLVQ structure - safety net */
120 : Word16 no_scales_p[][2] /* o: number of truncations for each LSF subvector at each MSLVQ structure - predictive */
121 : )
122 : {
123 : Word16 i, j;
124 : #ifdef OPT_STEREO_32KBPS_V1
125 : Word16 k;
126 : #endif /* OPT_STEREO_32KBPS_V1 */
127 : /* safety-net mode */
128 933831 : FOR( i = 0; i < MAX_NO_MODES; i++ )
129 : {
130 : #ifdef OPT_STEREO_32KBPS_V1
131 3633978 : FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
132 : {
133 2707386 : if ( no_lead_fx[i][j] > 0 )
134 : {
135 2475738 : k = add( k, 1 );
136 : }
137 2707386 : if ( no_lead_fx[i][j] <= 0 )
138 : {
139 231648 : j = MAX_NO_SCALES - 1;
140 231648 : move16();
141 : }
142 : }
143 926592 : no_scales[i][0] = k;
144 926592 : move16();
145 :
146 3474720 : FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
147 : {
148 2548128 : if ( no_lead_fx[i][j] > 0 )
149 : {
150 2070354 : k = add( k, 1 );
151 : }
152 2548128 : if ( no_lead_fx[i][j] <= 0 )
153 : {
154 477774 : j = MAX_NO_SCALES << 1;
155 477774 : move16();
156 : }
157 : }
158 926592 : no_scales[i][1] = k;
159 926592 : move16();
160 : #else /* OPT_STEREO_32KBPS_V1 */
161 : j = 0;
162 : move16();
163 : test();
164 : WHILE( ( LT_16( j, MAX_NO_SCALES ) ) && ( no_lead_fx[i][j] > 0 ) )
165 : {
166 : j++;
167 : }
168 : no_scales[i][0] = j;
169 : move16();
170 : j = MAX_NO_SCALES;
171 : move16();
172 : test();
173 : WHILE( ( LT_16( j, shl( MAX_NO_SCALES, 1 ) ) ) && ( no_lead_fx[i][j] > 0 ) )
174 : {
175 : j++;
176 : }
177 : no_scales[i][1] = sub( j, MAX_NO_SCALES );
178 : move16();
179 : #endif /* OPT_STEREO_32KBPS_V1 */
180 : }
181 : /* predictive mode */
182 1056894 : FOR( i = 0; i < MAX_NO_MODES_p; i++ )
183 : {
184 : #ifdef OPT_STEREO_32KBPS_V1
185 4147947 : FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
186 : {
187 3098292 : if ( no_lead_p_fx[i][j] > 0 )
188 : {
189 2975229 : k = add( k, 1 );
190 : }
191 3098292 : if ( ( no_lead_p_fx[i][j] <= 0 ) )
192 : {
193 123063 : j = MAX_NO_SCALES - 1;
194 123063 : move16();
195 : }
196 : }
197 1049655 : no_scales_p[i][0] = k;
198 1049655 : move16();
199 :
200 3938016 : FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
201 : {
202 2888361 : if ( no_lead_p_fx[i][j] > 0 )
203 : {
204 2359914 : k = add( k, 1 );
205 : }
206 :
207 2888361 : if ( ( no_lead_p_fx[i][j] <= 0 ) )
208 : {
209 528447 : j = MAX_NO_SCALES << 1;
210 528447 : move16();
211 : }
212 : }
213 :
214 1049655 : no_scales_p[i][1] = k;
215 1049655 : move16();
216 : #else /* OPT_STEREO_32KBPS_V1 */
217 : j = 0;
218 : move16();
219 : WHILE( ( LT_16( j, MAX_NO_SCALES ) ) && ( no_lead_p_fx[i][j] > 0 ) )
220 : {
221 : test();
222 : j++;
223 : }
224 : no_scales_p[i][0] = j;
225 : move16();
226 : j = MAX_NO_SCALES;
227 : move16();
228 : WHILE( ( LT_16( j, shl( MAX_NO_SCALES, 1 ) ) ) && ( no_lead_p_fx[i][j] > 0 ) )
229 : {
230 : test();
231 : j++;
232 : }
233 : no_scales_p[i][1] = sub( j, MAX_NO_SCALES );
234 : move16();
235 : #endif /* OPT_STEREO_32KBPS_V1 */
236 : }
237 : /* index offsets for each truncation */
238 7239 : init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p );
239 7239 : }
240 :
241 : /* make_offset_scale_fx() - calculates scale offset values for a particular MSLVQ structure */
242 3952494 : static void make_offset_scale_fx(
243 : Word16 j, /* i: MSLVQ structure index */
244 : const Word32 tab_no_cv[], /* i: cummulated number of codevectors in each leader class */
245 : const Word16 no_ld[], /* i: number of leaders in each truncation for the MSLVQ structure j*/
246 : Word16 no_scl, /* i: number of truncations in the MSLVQ structure j */
247 : Word32 offset_scale[][MAX_NO_SCALES + 1] /* o: offset values */
248 : )
249 : {
250 : Word16 i;
251 :
252 3952494 : offset_scale[j][0] = L_deposit_l( 1 );
253 3952494 : move32();
254 13833729 : FOR( i = 1; i <= no_scl; i++ )
255 : {
256 9881235 : offset_scale[j][i] = L_add( offset_scale[j][sub( i, 1 )], tab_no_cv[no_ld[sub( i, 1 )]] );
257 9881235 : move32();
258 : }
259 :
260 3952494 : return;
261 : }
262 :
263 7239 : void init_offset_fx(
264 : Word32 offset_scale1[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
265 : Word32 offset_scale2[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
266 : Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
267 : Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
268 : Word16 no_scales[][2], /* i: number of truncations for each LSF subvector at each MSLVQ structure - safety net */
269 : Word16 no_scales_p[][2] /* i: number of truncations for each LSF subvector at each MSLVQ structure - predictive */
270 : )
271 : {
272 : Word16 j;
273 : /* safety-net */
274 933831 : FOR( j = 0; j < MAX_NO_MODES; j++ )
275 : {
276 926592 : make_offset_scale_fx( j, table_no_cv_fx, no_lead_fx[j], no_scales[j][0], offset_scale1 );
277 926592 : make_offset_scale_fx( j, table_no_cv_fx, &no_lead_fx[j][MAX_NO_SCALES], no_scales[j][1], offset_scale2 );
278 : }
279 : /* predictive modes AR and MA */
280 1056894 : FOR( j = 0; j < MAX_NO_MODES_p; j++ )
281 : {
282 1049655 : make_offset_scale_fx( j, table_no_cv_fx, no_lead_p_fx[j], no_scales_p[j][0], offset_scale1_p );
283 1049655 : make_offset_scale_fx( j, table_no_cv_fx, &no_lead_p_fx[j][MAX_NO_SCALES], no_scales_p[j][1], offset_scale2_p );
284 : }
285 :
286 7239 : offset_scale1[MAX_NO_MODES][0] = 1;
287 7239 : move32();
288 7239 : offset_scale2[MAX_NO_MODES][0] = 1;
289 7239 : move32();
290 7239 : offset_scale1_p[MAX_NO_MODES_p][0] = 1;
291 7239 : move32();
292 7239 : offset_scale2_p[MAX_NO_MODES_p][0] = 1;
293 7239 : move32();
294 :
295 7239 : return;
296 : }
297 :
298 : static Word16
299 4165 : decode_indexes_fx(
300 : Word16 *index, /* i: LSF vector index, written as array of Word16 because it generally uses more than 16 bits */
301 : Word16 no_bits, /* i: number of bits for the index */
302 : const Word16 *p_scales, /* i: scale values for the MSLVQ structures */
303 : Word16 *p_no_scales, /* i: number of truncations for each MSLVQ structure */
304 : Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
305 : Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
306 : Word16 *x_lvq, /* o: decoded LSF vector in Q1 */
307 : Word16 mode_glb, /* i: index of LSLVQ structure */
308 : // note_ : renamed from scales
309 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector */
310 : )
311 : {
312 4165 : Word32 index1 = 0, index2 = 0;
313 4165 : move32();
314 4165 : move32();
315 4165 : Word16 len_scales = MAX_NO_SCALES * 2, no_modes;
316 4165 : move16();
317 : Word16 i, im1, idx_scale;
318 : Word16 tmp;
319 :
320 4165 : no_modes = MAX_NO_SCALES + 1;
321 4165 : move16();
322 :
323 4165 : IF( LE_16( no_bits, shl( LEN_INDICE, 1 ) ) ) /* the third short is not used */
324 : {
325 2422 : index[2] = 0;
326 2422 : move16();
327 2422 : if ( LE_16( no_bits, LEN_INDICE ) )
328 : {
329 0 : index[1] = 0;
330 0 : move16();
331 : }
332 : }
333 :
334 : /* safety check in case of bit errors */
335 16660 : FOR( i = 0; i < 3; i++ )
336 : {
337 12495 : IF( index[i] < 0 )
338 : {
339 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
340 0 : scales_mslvq[0] = 0;
341 0 : move16();
342 0 : scales_mslvq[1] = 0;
343 0 : move16();
344 0 : index[i] = 0;
345 0 : move16();
346 0 : return 1;
347 : }
348 : }
349 :
350 : /* first subvector */
351 4165 : tmp = i_mult2( mode_glb, no_modes );
352 :
353 4165 : IF( p_offset_scale2[add( tmp, p_no_scales[add( shl( mode_glb, 1 ), 1 )] )] > 0 )
354 : {
355 4165 : divide_64_32_fx( index, p_offset_scale2[tmp + p_no_scales[add( shl( mode_glb, 1 ), 1 )]], &index1, &index2 );
356 : }
357 : ELSE
358 : {
359 0 : index1 = L_deposit_l( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
360 0 : index2 = L_deposit_l( 0 );
361 : }
362 4165 : IF( index1 == 0 )
363 : {
364 0 : FOR( i = 0; i < LATTICE_DIM; i++ )
365 : {
366 0 : x_lvq[i] = 0;
367 0 : move16();
368 : }
369 0 : scales_mslvq[0] = 0;
370 0 : move16();
371 : }
372 : ELSE
373 : {
374 4165 : IF( GE_32( index1, p_offset_scale1[mode_glb * no_modes + p_no_scales[mode_glb * 2]] ) )
375 : {
376 : /* safety check in case of bit errors */
377 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
378 0 : scales_mslvq[0] = 0;
379 0 : move16();
380 0 : scales_mslvq[1] = 0;
381 0 : move16();
382 0 : return 1;
383 : }
384 :
385 : /* find idx_scale */
386 4165 : i = 1;
387 4165 : move16();
388 6782 : WHILE( LE_16( i, p_no_scales[mode_glb * 2] ) && GE_32( index1, p_offset_scale1[mode_glb * no_modes + i] ) )
389 : {
390 2617 : i = add( i, 1 );
391 : }
392 4165 : idx_scale = sub( i, 1 );
393 4165 : move16();
394 4165 : index1 = L_sub( index1, p_offset_scale1[tmp + idx_scale] );
395 :
396 : /* find idx_leader */
397 4165 : i = 1;
398 4165 : move16();
399 :
400 48437 : WHILE( GE_32( index1, table_no_cv_fx[i] ) )
401 : {
402 44272 : i = add( i, 1 );
403 : }
404 4165 : im1 = sub( i, 1 );
405 4165 : decode_comb_fx( L_sub( index1, table_no_cv_fx[im1] ), x_lvq, im1 );
406 4165 : scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
407 4165 : move16();
408 : }
409 :
410 : /* second subvector */
411 4165 : IF( index2 == 0 )
412 : {
413 270 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
414 : {
415 240 : x_lvq[i] = 0;
416 240 : move16();
417 : }
418 30 : scales_mslvq[1] = 0;
419 30 : move16();
420 : }
421 : ELSE
422 : {
423 : /* find the index for the scale/truncation */
424 4135 : i = 1;
425 4135 : move16();
426 6188 : WHILE( GE_32( index2, p_offset_scale2[tmp + i] ) )
427 : {
428 2053 : i = add( i, 1 );
429 : }
430 :
431 4135 : idx_scale = sub( i, 1 );
432 4135 : index2 = L_sub( index2, p_offset_scale2[add( tmp, idx_scale )] );
433 : /* find the index of the leader vector */
434 4135 : i = 1;
435 4135 : move16();
436 17905 : WHILE( GE_32( index2, table_no_cv_fx[i] ) )
437 : {
438 13770 : i = add( i, 1 );
439 : }
440 4135 : im1 = sub( i, 1 );
441 4135 : decode_comb_fx( index2 - table_no_cv_fx[im1], &x_lvq[LATTICE_DIM], im1 );
442 4135 : scales_mslvq[1] = p_scales[add( i_mult2( mode_glb, len_scales ), add( MAX_NO_SCALES, idx_scale ) )];
443 4135 : move16();
444 : }
445 :
446 4165 : return 0;
447 : }
448 :
449 503384 : static Word16 decode_indexes_ivas_fx(
450 : Word16 *index,
451 : const Word16 no_bits,
452 : const Word16 *p_scales, // Q11
453 : const Word16 prediction_flag,
454 : Word16 *x_lvq, // Q1
455 : const Word16 mode_glb,
456 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
457 : )
458 : {
459 503384 : Word32 index1 = 0, index2, idx_scale;
460 503384 : move32();
461 : Word16 i;
462 :
463 503384 : Word16 len_scales = i_mult( MAX_NO_SCALES, 2 );
464 : UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
465 :
466 503384 : IF( LE_16( no_bits, 2 * LEN_INDICE ) ) /* the third short is not used */
467 : {
468 275744 : index[2] = 0;
469 275744 : move16();
470 275744 : if ( LE_16( no_bits, LEN_INDICE ) )
471 : {
472 1133 : index[1] = 0;
473 1133 : move16();
474 : }
475 : }
476 :
477 : /* safety check in case of bit errors */
478 2013536 : FOR( i = 0; i < 3; i++ )
479 : {
480 1510152 : IF( index[i] < 0 )
481 : {
482 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
483 0 : scales_mslvq[0] = 0;
484 0 : move16();
485 0 : scales_mslvq[1] = 0;
486 0 : move16();
487 0 : index[i] = 0;
488 0 : return 1;
489 : }
490 : }
491 :
492 503384 : create_offset( offset_scale1, offset_scale2, mode_glb, prediction_flag );
493 : /* first subvector */
494 503384 : IF( offset_scale2[MAX_NO_SCALES - 1] > 0 )
495 : {
496 503384 : divide_64_32_fx( index, offset_scale2[MAX_NO_SCALES], &index1, &index2 );
497 : }
498 : ELSE
499 : {
500 0 : index1 = (UWord32) ( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
501 0 : move32();
502 0 : index2 = 0;
503 0 : move32();
504 : }
505 :
506 503384 : IF( index1 == 0 )
507 : {
508 1611 : FOR( i = 0; i < LATTICE_DIM; i++ )
509 : {
510 1432 : x_lvq[i] = 0;
511 1432 : scales_mslvq[0] = 0;
512 1432 : move16();
513 : }
514 : }
515 : ELSE
516 : {
517 503205 : IF( GE_32( index1, (Word32) offset_scale1[MAX_NO_SCALES] ) )
518 : {
519 : /* safety check in case of bit errors */
520 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
521 0 : scales_mslvq[0] = 0;
522 0 : move16();
523 0 : scales_mslvq[1] = 0;
524 0 : move16();
525 0 : return 1;
526 : }
527 :
528 : /* find idx_scale */
529 503205 : i = 1;
530 503205 : test();
531 778334 : WHILE( LE_16( (Word16) i, MAX_NO_SCALES ) && GE_32( index1, (Word32) offset_scale1[i] ) )
532 : {
533 275129 : i++;
534 : }
535 :
536 503205 : idx_scale = i - 1;
537 503205 : index1 = L_sub( index1, offset_scale1[idx_scale] );
538 :
539 : /* find idx_leader */
540 503205 : i = 1;
541 503205 : move16();
542 6094900 : WHILE( GE_32( index1, (Word32) table_no_cv[i] ) )
543 : {
544 5591695 : i++;
545 : }
546 503205 : decode_comb_fx( (Word32) ( index1 - table_no_cv[i - 1] ), x_lvq, i - 1 );
547 503205 : scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
548 503205 : move16();
549 : // for (i = 0; i < LATTICE_DIM; i++)
550 : //{
551 : // //x_lvq[i] *= scale;
552 : // x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
553 : // }
554 : }
555 :
556 : /* second subvector */
557 503384 : IF( index2 == 0 )
558 : {
559 190188 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
560 : {
561 : // x_lvq[i] = 0.0;
562 169056 : x_lvq[i] = 0;
563 169056 : move16();
564 : }
565 21132 : scales_mslvq[1] = 0;
566 21132 : move16();
567 : }
568 : ELSE
569 : {
570 :
571 : /* find the index for the scale/truncation */
572 482252 : i = 1;
573 482252 : move16();
574 719766 : WHILE( GE_32( index2, (Word32) offset_scale2[i] ) )
575 : {
576 237514 : i++;
577 : }
578 :
579 482252 : idx_scale = i - 1;
580 482252 : move16();
581 482252 : index2 = L_sub( index2, offset_scale2[idx_scale] );
582 : /* find the index of the leader vector */
583 482252 : i = 1;
584 482252 : move16();
585 2129488 : WHILE( GE_32( index2, (Word32) table_no_cv[i] ) )
586 : {
587 1647236 : i++;
588 : }
589 482252 : decode_comb_fx( (Word32) ( index2 - table_no_cv[i - 1] ), &x_lvq[LATTICE_DIM], i - 1 );
590 :
591 482252 : scales_mslvq[1] = p_scales[mode_glb * len_scales + MAX_NO_SCALES + idx_scale];
592 482252 : move16();
593 : // for (i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++)
594 : //{
595 : // //x_lvq[i] *= scale;
596 : // x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
597 : // }
598 : }
599 :
600 503384 : return 0;
601 : }
602 :
603 4165 : Word16 deindex_lvq_fx(
604 : Word16 *index, /* i : index to be decoded, as an array of 3 Word16 */
605 : Word16 *x_lvq, /* o : decoded codevector Q(x2.56) */
606 : Word16 mode, /* i : LVQ coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
607 : Word16 sf_flag, /* i : safety net flag */
608 : Word16 no_bits, /* i : number of bits for lattice */
609 : Word32 *p_offset_scale1, /* i : offset for first subvector */
610 : Word32 *p_offset_scale2, /* i : offset for the second subvector */
611 : Word16 *p_no_scales /* i : number of scales for each truncation and each MSLVQ structure */
612 : )
613 : {
614 : Word16 i;
615 : const Word16 *p_scales;
616 : Word16 mode_glb;
617 : Word32 L_tmp;
618 : // note_ : renamed from scales
619 : Word16 scales_mslvq[2];
620 : Word16 ber_flag;
621 :
622 4165 : IF( EQ_16( sf_flag, 1 ) )
623 : {
624 523 : mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][sub( no_bits, min_lat_bits_SN_fx[mode] )] );
625 523 : p_scales = &scales_fx[0][0];
626 523 : move16();
627 : }
628 : ELSE
629 : {
630 3642 : mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][sub( no_bits, min_lat_bits_pred_fx[mode] )] );
631 3642 : p_scales = &scales_p_fx[0][0];
632 3642 : move16();
633 : }
634 :
635 : /* decode the lattice index into the lattice codevectors for the two subvectors */
636 : ber_flag =
637 4165 : decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1,
638 : p_offset_scale2, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
639 :
640 :
641 4165 : IF( EQ_16( sf_flag, 1 ) )
642 : {
643 : /* safety-net case*/
644 523 : IF( scales_mslvq[0] )
645 : {
646 4707 : FOR( i = 0; i < LATTICE_DIM; i++ )
647 : {
648 4184 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
649 : /* Increase calculation accuracy by shifting more to the left and using rounding instead of truncation*/
650 4184 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
651 4184 : x_lvq[i] = round_fx( L_tmp );
652 4184 : move16();
653 : }
654 : }
655 523 : IF( scales_mslvq[1] )
656 : {
657 4608 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
658 : {
659 4096 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
660 4096 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
661 4096 : x_lvq[i] = round_fx( L_tmp );
662 4096 : move16();
663 : }
664 : }
665 : }
666 : ELSE
667 : {
668 : /* predictive mode AR or MA */
669 3642 : IF( scales_mslvq[0] )
670 : {
671 32778 : FOR( i = 0; i < LATTICE_DIM; i++ )
672 : {
673 29136 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
674 29136 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
675 29136 : x_lvq[i] = round_fx( L_tmp );
676 29136 : move16();
677 : }
678 : }
679 3642 : IF( scales_mslvq[1] )
680 : {
681 32607 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
682 : {
683 28984 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
684 28984 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
685 28984 : x_lvq[i] = round_fx( L_tmp );
686 28984 : move16();
687 : }
688 : }
689 : }
690 :
691 4165 : return ber_flag;
692 : }
693 :
694 502967 : Word16 deindex_lvq_ivas_fx(
695 : Word16 *index, /* i : index to be decoded, as an array of 3 Word16 */
696 : Word16 *x_lvq, /* o : decoded codevector Q(x2.56) */
697 : Word16 mode, /* i : LVQ coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
698 : Word16 sf_flag, /* i : safety net flag */
699 : Word16 no_bits /* i : number of bits for lattice */
700 : )
701 : {
702 : Word16 i;
703 : const Word16 *p_scales;
704 : Word16 mode_glb;
705 : Word32 L_tmp;
706 : // note_ : renamed from scales
707 : Word16 scales_mslvq[2];
708 : Word16 ber_flag;
709 :
710 502967 : IF( EQ_16( sf_flag, 1 ) )
711 : {
712 70759 : IF( LT_16( mode, 6 ) ) /* for NB */
713 : {
714 0 : mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][sub( no_bits, min_lat_bits_SN[mode] )] );
715 : }
716 : ELSE
717 : {
718 70759 : mode_glb = add( offset_lvq_modes_SN[mode], sub( no_bits, min_lat_bits_SN[mode] ) ); /* there is granularity of 1 bit */
719 : }
720 70759 : p_scales = &scales_ivas_fx[0][0]; // Q11
721 70759 : move16();
722 : }
723 : ELSE
724 : {
725 432208 : test();
726 432208 : IF( ( LT_16( mode, 6 ) ) || ( EQ_16( mode, 12 ) ) ) /* for NB */
727 : {
728 9583 : mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][sub( no_bits, min_lat_bits_pred[mode] )] );
729 : }
730 : ELSE
731 : {
732 422625 : mode_glb = add( offset_lvq_modes_pred[mode], sub( no_bits, min_lat_bits_pred[mode] ) );
733 : }
734 432208 : p_scales = &scales_p_ivas_fx[0][0]; // Q11
735 432208 : move16();
736 : }
737 :
738 : UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
739 502967 : create_offset( offset_scale1, offset_scale2, mode_glb, 1 - sf_flag );
740 :
741 : /* decode the lattice index into the lattice codevectors for the two subvectors */
742 : // ber_flag =
743 : // decode_indexes_fx(index, no_bits, p_scales, p_no_scales, offset_scale1,
744 : // offset_scale2, x_lvq, mode_glb, scales_mslvq); /* x_lvq is here Q1 */
745 : ber_flag =
746 502967 : decode_indexes_ivas_fx( index, no_bits, p_scales, 1 - sf_flag, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
747 :
748 :
749 502967 : IF( EQ_16( sf_flag, 1 ) )
750 : {
751 : /* safety-net case*/
752 70759 : IF( scales_mslvq[0] )
753 : {
754 636057 : FOR( i = 0; i < LATTICE_DIM; i++ )
755 : {
756 565384 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
757 : /* Increase calculation accuracy by shifting more to the left and using rounding instead of truncation*/
758 565384 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
759 565384 : x_lvq[i] = round_fx( L_tmp );
760 565384 : move16();
761 : }
762 : }
763 70759 : IF( scales_mslvq[1] )
764 : {
765 594045 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
766 : {
767 528040 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
768 528040 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
769 528040 : x_lvq[i] = round_fx( L_tmp );
770 528040 : move16();
771 : }
772 : }
773 : }
774 : ELSE
775 : {
776 : /* predictive mode AR or MA */
777 432208 : IF( scales_mslvq[0] )
778 : {
779 3889098 : FOR( i = 0; i < LATTICE_DIM; i++ )
780 : {
781 3456976 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
782 3456976 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
783 3456976 : x_lvq[i] = round_fx( L_tmp );
784 3456976 : move16();
785 : }
786 : }
787 432208 : IF( scales_mslvq[1] )
788 : {
789 3742479 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
790 : {
791 3326648 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
792 3326648 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
793 3326648 : x_lvq[i] = round_fx( L_tmp );
794 3326648 : move16();
795 : }
796 : }
797 : }
798 :
799 502967 : return ber_flag;
800 : }
801 :
802 : /*----------------------------------------------------------------------------------------------------*
803 : * deindex_lvq_cng()
804 : * Note:
805 : * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
806 : * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
807 : * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
808 : *----------------------------------------------------------------------------------------------------*/
809 :
810 0 : Word16 deindex_lvq_cng_fx(
811 : Word16 *index, /* i: index to be decoded, as an array of 3 short */
812 : Word16 *x_lvq, /* o: decoded codevector Q9 */
813 : Word16 idx_cv, /* i: relative mode_lvq, wrt START_CNG */
814 : Word16 no_bits, /* i: number of bits for lattice */
815 : Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
816 : Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
817 : Word16 *p_no_scales /* i: number of scales for each MSLVQ structure and each subvector */
818 : )
819 : {
820 : Word16 i;
821 : Word32 L_tmp;
822 : const Word16 *p_scales;
823 : Word16 mode_glb, mode;
824 : // note_ : renamed from scales as global declaration of scales is causing warning
825 : Word16 scales_mslvq[2];
826 : Word16 ber_flag;
827 :
828 : /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
829 0 : mode_glb = add( START_CNG, idx_cv );
830 :
831 0 : mode = add( LVQ_COD_MODES, idx_cv );
832 :
833 0 : p_scales = &scales_fx[0][0];
834 0 : move16();
835 : ber_flag =
836 0 : decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq );
837 :
838 0 : FOR( i = 0; i < LATTICE_DIM; i++ )
839 : {
840 0 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
841 0 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
842 0 : x_lvq[i] = round_fx( L_tmp );
843 0 : move16();
844 : }
845 0 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
846 : {
847 0 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
848 0 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
849 0 : x_lvq[i] = round_fx( L_tmp );
850 0 : move16();
851 : }
852 :
853 : /* check if permutting needed */
854 0 : IF( cng_sort[idx_cv] )
855 : {
856 0 : permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
857 : }
858 :
859 0 : return ber_flag;
860 : }
861 :
862 :
863 : /*----------------------------------------------------------------------------------------------------*
864 : * deindex_lvq_cng()
865 : * Note:
866 : * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
867 : * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
868 : * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
869 : *----------------------------------------------------------------------------------------------------*/
870 :
871 417 : Word16 deindex_lvq_cng_ivas_fx(
872 : Word16 *index, /* i: index to be decoded, as an array of 3 short */
873 : Word16 *x_lvq, /* o: decoded codevector Q9 */
874 : Word16 idx_cv, /* i: relative mode_lvq, wrt START_CNG */
875 : Word16 no_bits /* i: number of bits for lattice */
876 : )
877 : {
878 : Word16 i;
879 : Word32 L_tmp;
880 : const Word16 *p_scales;
881 : Word16 mode_glb, mode;
882 : // note_ : renamed from scales as global declaration of scales is causing warning
883 : Word16 scales_mslvq[2];
884 : Word16 ber_flag;
885 :
886 : /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
887 417 : mode_glb = add( START_CNG_IVAS, idx_cv );
888 :
889 417 : mode = add( LVQ_COD_MODES, idx_cv );
890 :
891 417 : p_scales = &scales_ivas_fx[0][0];
892 417 : move16();
893 : // ber_flag =
894 : // decode_indexes_fx(index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq);
895 : ber_flag =
896 417 : decode_indexes_ivas_fx( index, no_bits, p_scales, 0, x_lvq, mode_glb, scales_mslvq );
897 :
898 3753 : FOR( i = 0; i < LATTICE_DIM; i++ )
899 : {
900 3336 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
901 3336 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
902 3336 : x_lvq[i] = round_fx( L_tmp );
903 3336 : move16();
904 : }
905 3753 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
906 : {
907 3336 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
908 3336 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
909 3336 : x_lvq[i] = round_fx( L_tmp );
910 3336 : move16();
911 : }
912 :
913 : /* check if permutting needed */
914 417 : IF( cng_sort[idx_cv] )
915 : {
916 410 : permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
917 : }
918 :
919 417 : return ber_flag;
920 : }
921 :
922 : /* combinatorial indexing */
923 3189609 : static void idx2c_fx(
924 : Word16 n, /* i : total number of positions (components)*/
925 : Word16 *p, /* o : array with positions of the k components */
926 : Word16 k, /* i : number of components whose position is to be determined */
927 : Word16 val /* i : index to be decoded */
928 : )
929 : {
930 : Word16 i, skip, pos, k1;
931 :
932 3189609 : skip = 0;
933 3189609 : move16();
934 3189609 : pos = 0;
935 3189609 : move16();
936 3189609 : k1 = sub( k, 1 );
937 3189609 : move16();
938 6738038 : WHILE( LT_16( add( skip, sub( C_VQ[n - pos - 1][k1], 1 ) ), val ) )
939 : {
940 3548429 : skip = add( skip, C_VQ[n - pos - 1][k1] );
941 3548429 : move16();
942 3548429 : pos++;
943 3548429 : move16();
944 : }
945 :
946 3189609 : p[0] = pos;
947 3189609 : move16();
948 3189609 : n = sub( n, add( pos, 1 ) );
949 3189609 : val = sub( val, skip );
950 3189609 : IF( EQ_16( k, 1 ) )
951 : {
952 1196127 : return;
953 : }
954 :
955 1993482 : idx2c_fx( n, p + 1, k1, val );
956 :
957 : /* pos+1 */
958 6044689 : FOR( i = 1; i < k; i++ )
959 : {
960 4051207 : p[i] = add( p[i], add( pos, 1 ) );
961 4051207 : move16();
962 : }
963 :
964 1993482 : return;
965 : }
966 : /* combinatorial deindexing */
967 996929 : static void decode_comb_fx(
968 : Word32 index, /* i : index to be decoded */
969 : Word16 *cv, /* o : decoded codevector Q1*/
970 : Word16 idx_lead /* i : leader class index */
971 : )
972 : {
973 : Word16 idx_sign;
974 996929 : IF( LT_32( L_shl( index, 1 ), pi0[idx_lead] ) )
975 : {
976 73941 : idx_sign = 0;
977 73941 : move16();
978 : }
979 : ELSE
980 : {
981 922988 : idx_sign = extract_l( div_l( L_shl( index, 1 ), pi0[idx_lead] ) ); /*(index/pi0_fx[idx_lead]); */
982 : }
983 996929 : index = L_sub( index, L_mult0( idx_sign, pi0[idx_lead] ) );
984 996929 : decode_leaders_fx( extract_l( index ), idx_lead, cv );
985 996929 : decode_sign_pc1_fx( cv, idx_sign, pl_par[idx_lead] );
986 :
987 996929 : return;
988 : }
989 996929 : void decode_sign_pc1_fx(
990 : Word16 *c, /* o : decoded codevector Q1*/
991 : Word16 idx_sign, /* i : sign index */
992 : Word16 parity /* i : parity flag (+1/-1/0) */
993 : )
994 : {
995 996929 : Word16 i, len = LATTICE_DIM, cnt_neg = 1;
996 :
997 996929 : if ( parity )
998 : {
999 419102 : len = sub( len, 1 );
1000 : }
1001 :
1002 8553259 : FOR( i = 0; i < len; i++ )
1003 : {
1004 7556330 : IF( c[i] > 0 )
1005 : {
1006 : /*if (idx_sign % 2) */
1007 5481733 : IF( s_and( idx_sign, 1 ) )
1008 : {
1009 2649785 : c[i] = negate( c[i] );
1010 2649785 : move16();
1011 2649785 : cnt_neg = negate( cnt_neg );
1012 2649785 : move16();
1013 : }
1014 5481733 : idx_sign = shr( idx_sign, 1 ); /* >>= 1; */
1015 : }
1016 : }
1017 :
1018 996929 : IF( LT_16( len, LATTICE_DIM ) )
1019 : {
1020 419102 : IF( NE_16( cnt_neg, parity ) )
1021 : {
1022 190130 : c[len] = negate( c[len] );
1023 190130 : move16();
1024 : }
1025 : }
1026 :
1027 996929 : return;
1028 : }
1029 :
1030 :
1031 996929 : static void decode_leaders_fx(
1032 : Word16 index, /* i : index to be decoded */
1033 : Word16 idx_lead, /* i : leader class index */
1034 : Word16 *cv /* o : decoded codevector Q1*/
1035 : )
1036 : {
1037 : Word16 i, no_vals_loc, no_vals_last, p[LATTICE_DIM], dim_loc, n_crt;
1038 : Word16 index1;
1039 : Word16 val_crt;
1040 :
1041 996929 : no_vals_loc = no_vals[idx_lead];
1042 996929 : move16();
1043 996929 : val_crt = vals_fx[idx_lead][no_vals_loc - 1];
1044 996929 : move16(); /*Q1 */
1045 996929 : no_vals_last = no_vals_ind[idx_lead][no_vals_loc - 1];
1046 996929 : move16();
1047 :
1048 5782752 : FOR( i = 0; i < no_vals_last; i++ )
1049 : {
1050 4785823 : cv[i] = val_crt;
1051 4785823 : move16(); /*Q1 */
1052 : }
1053 :
1054 996929 : val_crt = 1;
1055 996929 : move16();
1056 996929 : dim_loc = no_vals_last;
1057 996929 : move16();
1058 :
1059 996929 : SWITCH( no_vals_loc )
1060 : {
1061 100111 : case 1:
1062 100111 : BREAK;
1063 600049 : case 2:
1064 600049 : idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index );
1065 600049 : put_value_fx( cv, p, vals_fx[idx_lead][0], no_vals_last, no_vals_ind[idx_lead][0] );
1066 600049 : BREAK;
1067 2540 : case 4:
1068 2540 : dim_loc = add( dim_loc, no_vals_ind[idx_lead][2] );
1069 2540 : n_crt = no_vals_ind[idx_lead][2];
1070 2540 : move16();
1071 2540 : index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index ); /* index1 = index/C_VQ_fx[dim_loc][n_crt]; */
1072 2540 : /*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]) ); */ /* index-= index1*C_VQ_fx[dim_loc][n_crt]; */ move16();
1073 2540 : idx2c_fx( dim_loc, p, n_crt, index );
1074 2540 : put_value_fx( cv, p, vals_fx[idx_lead][2], no_vals_last, no_vals_ind[idx_lead][2] ); /* Q1 */
1075 2540 : index = index1;
1076 2540 : move16();
1077 : /* no break */
1078 296769 : case 3:
1079 296769 : dim_loc = add( dim_loc, no_vals_ind[idx_lead][1] );
1080 296769 : n_crt = no_vals_ind[idx_lead][1];
1081 296769 : move16();
1082 296769 : index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index );
1083 : /*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]));move16(); */
1084 296769 : idx2c_fx( dim_loc, p, n_crt, index );
1085 296769 : put_value_fx( cv, p, vals_fx[idx_lead][1], sub( dim_loc, n_crt ), n_crt );
1086 296769 : idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index1 );
1087 296769 : move16();
1088 296769 : put_value_fx( cv, p, vals_fx[idx_lead][0], dim_loc, no_vals_ind[idx_lead][0] );
1089 296769 : BREAK;
1090 : }
1091 :
1092 996929 : return;
1093 : }
1094 :
1095 : /* divide_32_32_fx() :Division reminder - rem is the reminder of the division between y and x. */
1096 624090 : static Word32 divide_32_32_fx( Word32 y, /* i */
1097 : Word32 x, /* i */
1098 : Word32 *rem /* o */
1099 : )
1100 : {
1101 : Word32 result, t, L_tmp;
1102 : Word16 i, ny, nx, nyx;
1103 :
1104 :
1105 624090 : IF( LT_32( y, x ) )
1106 : {
1107 25952 : result = L_deposit_l( 0 );
1108 25952 : *rem = y;
1109 25952 : move32();
1110 : }
1111 : ELSE
1112 : {
1113 :
1114 598138 : result = L_deposit_l( 0 );
1115 598138 : IF( y == 0 )
1116 : {
1117 0 : ny = 0;
1118 0 : move16();
1119 : }
1120 : ELSE
1121 : {
1122 598138 : ny = sub( 31, norm_l( y ) );
1123 : }
1124 598138 : IF( x == 0 )
1125 : {
1126 0 : nx = 0;
1127 0 : move16();
1128 : }
1129 : ELSE
1130 : {
1131 598138 : nx = sub( 31, norm_l( x ) );
1132 : }
1133 :
1134 598138 : nyx = sub( ny, nx );
1135 :
1136 : /*t = L_and(L_shr(y, add(nyx,1)),sub(shl(1,sub(nx,1)),1)); */
1137 598138 : t = L_shr( y, add( nyx, 1 ) );
1138 8677040 : FOR( i = 0; i <= nyx; i++ )
1139 : {
1140 8078902 : t = L_add( L_shl( t, 1 ), L_and( L_shr( y, sub( nyx, i ) ), 1 ) ); /* L_and(y,L_shl(1, sub(nyx,i)))); */
1141 8078902 : result = L_shl( result, 1 );
1142 8078902 : L_tmp = L_sub( t, x );
1143 8078902 : IF( L_tmp >= 0 )
1144 : {
1145 4030400 : result = L_add( result, 1 );
1146 4030400 : t = L_add( L_tmp, 0 );
1147 : }
1148 : }
1149 598138 : *rem = t;
1150 598138 : move32();
1151 : }
1152 624090 : return result;
1153 : }
1154 :
1155 : /* divide_32_32_fx() :Division reminder for Word16 - rem is the reminder of the division between y and x. */
1156 299309 : static Word16 divide_16_16_fx( Word16 y, /* i */
1157 : Word16 x, /* i */
1158 : Word16 *rem /* o */
1159 : )
1160 : {
1161 : Word16 result, t, tmp;
1162 : Word16 i, ny, nx, nyx;
1163 :
1164 :
1165 299309 : IF( LT_32( y, x ) )
1166 : {
1167 36771 : result = 0;
1168 36771 : move16();
1169 36771 : *rem = y;
1170 36771 : move16();
1171 : }
1172 : ELSE
1173 : {
1174 :
1175 262538 : result = 0;
1176 262538 : move16();
1177 262538 : IF( y == 0 )
1178 : {
1179 0 : ny = 0;
1180 0 : move16();
1181 : }
1182 : ELSE
1183 : {
1184 262538 : ny = sub( 15, norm_s( y ) );
1185 : }
1186 262538 : IF( x == 0 )
1187 : {
1188 0 : nx = 0;
1189 0 : move16();
1190 : }
1191 : ELSE
1192 : {
1193 262538 : nx = sub( 15, norm_s( x ) );
1194 : }
1195 :
1196 262538 : nyx = sub( ny, nx );
1197 :
1198 262538 : t = s_and( shr( y, add( nyx, 1 ) ), sub( shl( 1, sub( nx, 1 ) ), 1 ) );
1199 1103921 : FOR( i = 0; i <= nyx; i++ )
1200 : {
1201 841383 : t = add( shl( t, 1 ), s_and( shr( y, sub( nyx, i ) ), 1 ) ); /* L_and(y,L_shl(1, sub(nyx,i)))); */
1202 841383 : result = shl( result, 1 );
1203 841383 : tmp = sub( t, x );
1204 841383 : IF( tmp >= 0 )
1205 : {
1206 485308 : result = add( result, 1 );
1207 485308 : t = tmp;
1208 485308 : move16();
1209 : }
1210 : }
1211 262538 : *rem = t;
1212 262538 : move16();
1213 : }
1214 299309 : return result;
1215 : }
1216 :
1217 507549 : static void divide_64_32_fx(
1218 : Word16 *xs, /* i : denominator as array of two int32 */
1219 : Word32 y, /* i : nominator on 32 bits */
1220 : Word32 *result, /* o : integer division result on 32 bits */
1221 : Word32 *rem /* o : integer division reminder on 32 bits */
1222 : )
1223 : {
1224 : Word16 nb_x1;
1225 : Word32 r, x_tmp, x[2], q, q1;
1226 :
1227 507549 : x[0] = L_add( L_add( L_shl( L_deposit_l( s_and( xs[2], 1 ) ), 2 * LEN_INDICE ), L_shl( L_deposit_l( xs[1] ), LEN_INDICE ) ), L_deposit_l( xs[0] ) );
1228 507549 : move32();
1229 507549 : x[1] = L_shr( L_deposit_l( xs[2] ), 1 );
1230 507549 : move32();
1231 :
1232 : /*x[0] = (((xs[2])&(1)<<(LEN_INDICE*2)) + (xs[1]<<LEN_INDICE) + xs[0];
1233 : x[1] = xs[2]>>1; */
1234 :
1235 507549 : IF( x[1] == 0 )
1236 : {
1237 391008 : nb_x1 = 0;
1238 391008 : move16();
1239 : }
1240 : ELSE
1241 : {
1242 116541 : nb_x1 = sub( 31, norm_l( x[1] ) ); /*get_no_bits_fx(x[1]); */
1243 : }
1244 : /* take the first 31 bits */
1245 507549 : IF( nb_x1 > 0 )
1246 : {
1247 116541 : x_tmp = L_add( L_shl( x[1], sub( 31, nb_x1 ) ), L_shr( x[0], nb_x1 ) );
1248 : /* x_tmp = (x[1]<<(32-nb_x1)) + (x[0]>>nb_x1); */
1249 :
1250 116541 : q = divide_32_32_fx( x_tmp, y, &r ); /* q = x_tmp/y, reminder r */
1251 116541 : r = L_add( L_shl( r, nb_x1 ), L_and( x[0], L_deposit_l( sub( shl( 1, nb_x1 ), 1 ) ) ) ); /* this is the first reminder */
1252 : /* r = (r<<nb_x1)+(x[0]&((1<<nb_x1) - 1)); */
1253 :
1254 116541 : q1 = divide_32_32_fx( r, y, rem );
1255 116541 : *result = L_add( L_shl( q, nb_x1 ), q1 );
1256 116541 : move32();
1257 : }
1258 : ELSE
1259 : {
1260 391008 : *result = divide_32_32_fx( x[0], y, rem );
1261 391008 : move32();
1262 : }
1263 :
1264 507549 : return;
1265 : }
1266 :
1267 1196127 : static void put_value_fx(
1268 : Word16 *cv, /* i/o : input codevector Q1*/
1269 : Word16 *p, /* i : array with positions */
1270 : Word16 val, /* i : value to be inserted Q1*/
1271 : Word16 dim, /* i : vector dimension */
1272 : Word16 no_new_val /* i : number of values to be inserted */
1273 : )
1274 : {
1275 : Word16 cv_out[LATTICE_DIM];
1276 : Word16 i, occ[LATTICE_DIM], cnt, limit;
1277 :
1278 1196127 : limit = add( dim, no_new_val );
1279 10387064 : FOR( i = 0; i < limit; i++ )
1280 : {
1281 9190937 : occ[i] = 0;
1282 9190937 : move16();
1283 : }
1284 :
1285 4385736 : FOR( i = 0; i < no_new_val; i++ )
1286 : {
1287 3189609 : cv_out[p[i]] = val;
1288 3189609 : move16();
1289 3189609 : occ[p[i]] = 1;
1290 3189609 : move16();
1291 : }
1292 :
1293 1196127 : cnt = 0;
1294 1196127 : move16();
1295 10387064 : FOR( i = 0; i < limit; i++ )
1296 : {
1297 9190937 : if ( occ[i] == 0 )
1298 : {
1299 6001328 : cv_out[i] = cv[cnt++];
1300 6001328 : move16();
1301 : }
1302 : }
1303 :
1304 10387064 : FOR( i = 0; i < limit; i++ )
1305 : {
1306 9190937 : cv[i] = cv_out[i];
1307 9190937 : move16();
1308 : }
1309 :
1310 1196127 : return;
1311 : }
1312 :
1313 3172 : void deindex_lvq_SHB_fx(
1314 : UWord32 index,
1315 : Word16 *out,
1316 : const Word16 nbits,
1317 : const Word16 mode )
1318 : {
1319 : UWord16 i;
1320 : const Word8 *p_no_lead;
1321 : const Word16 *p_scales;
1322 : Word16 scale;
1323 : Word16 idx_scale;
1324 : UWord32 offsets[MAX_NO_SCALES + 1];
1325 :
1326 3172 : IF( mode == 0 )
1327 : {
1328 3172 : p_no_lead = &no_lead_BWE[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
1329 3172 : p_scales = &scales_BWE_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
1330 : }
1331 : ELSE
1332 : {
1333 0 : p_no_lead = &no_lead_BWE_3b[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
1334 0 : p_scales = &scales_BWE_3b_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
1335 : }
1336 :
1337 :
1338 3172 : IF( index == 0 )
1339 : {
1340 0 : set16_fx( out, 0, LATTICE_DIM );
1341 : }
1342 : ELSE
1343 : {
1344 : /* create offsets */
1345 3172 : offsets[0] = 0;
1346 3172 : move32();
1347 12688 : FOR( i = 0; i < MAX_NO_SCALES; i++ )
1348 : {
1349 9516 : offsets[i + 1] = UL_addNsD( table_no_cv[p_no_lead[i]], offsets[i] );
1350 9516 : move32();
1351 : }
1352 :
1353 : /* find idx_scale */
1354 3172 : idx_scale = 0;
1355 3172 : test();
1356 7331 : WHILE( LE_32( i, MAX_NO_SCALES ) && index >= offsets[idx_scale] )
1357 : {
1358 4159 : test();
1359 4159 : idx_scale = add( idx_scale, 1 );
1360 : }
1361 3172 : idx_scale = sub( idx_scale, 1 );
1362 3172 : index = L_sub( index, offsets[idx_scale] );
1363 :
1364 : /* find idx_leader */
1365 3172 : i = 1;
1366 3172 : move16();
1367 21605 : WHILE( GT_32( index, table_no_cv[i] ) )
1368 : {
1369 18433 : i = add( i, 1 );
1370 : }
1371 3172 : i = sub( i, 1 );
1372 :
1373 3172 : decode_comb_fx( (Word32) ( L_sub( L_sub( index, table_no_cv[i] ), 1 ) ), out, i );
1374 :
1375 3172 : scale = p_scales[idx_scale];
1376 3172 : move16();
1377 28548 : FOR( i = 0; i < LATTICE_DIM; i++ )
1378 : {
1379 25376 : Word32 temp = Mpy_32_16_1( sigma_BWE_fx[add( i_mult( mode, LATTICE_DIM ), i )], scale );
1380 25376 : temp = Mpy_32_16_1( temp, out[i] );
1381 25376 : out[i] = extract_l( temp ); /* Q15 output*/
1382 25376 : move16();
1383 : // out[i] *= scale * sigma_BWE_fx[mode * LATTICE_DIM + i];
1384 : }
1385 : }
1386 :
1387 3172 : return;
1388 : }
|