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 <stdint.h>
34 : #include "options.h"
35 : #include "cnst.h"
36 : #include "prot_fx.h"
37 : #include "ivas_cnst.h"
38 : #include "stl.h"
39 : #include "rom_com.h"
40 : #include "ivas_prot_fx.h"
41 : #include "wmc_auto.h"
42 :
43 :
44 : /*-----------------------------------------------------------------*
45 : * Local functions
46 : *-----------------------------------------------------------------*/
47 :
48 : 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] );
49 : 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] );
50 : static void decode_comb_fx( Word32 index, Word16 *cv, Word16 idx_lead );
51 : static void decode_sign_pc1_fx( Word16 *c, Word16 idx_sign, Word16 parity );
52 : static void put_value_fx( Word16 *cv, Word16 *p, Word16 val, Word16 dim, Word16 no_new_val );
53 : static void decode_leaders_fx( Word16 index, Word16 idx_lead, Word16 *cv );
54 : static void idx2c_fx( Word16 n, Word16 *p, Word16 k, Word16 val );
55 : static void divide_64_32_fx( Word16 *xs, Word32 y, Word32 *result, Word32 *rem );
56 : static Word16
57 : 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 );
58 : static Word16 decode_indexes_ivas_fx(
59 : Word16 *index,
60 : const Word16 no_bits,
61 : const Word16 *p_scales, // Q11
62 : const Word16 prediction_flag,
63 : Word16 *x_lvq, // Q0
64 : const Word16 mode_glb,
65 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
66 : );
67 : static Word32 divide_32_32_fx( Word32 y, Word32 x, Word32 *rem );
68 : static Word16 divide_16_16_fx( Word16 y, Word16 x, Word16 *rem );
69 : static Word16 decode_indexes_ivas_fx(
70 : Word16 *index,
71 : const Word16 no_bits,
72 : const Word16 *p_scales, // Q11
73 : const Word16 prediction_flag,
74 : Word16 *x_lvq, // Q0
75 : const Word16 mode_glb,
76 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
77 : );
78 :
79 : /* used in CNG-LP coding */
80 1730 : void permute_fx(
81 : Word16 *pTmp1, /* i/o: vector whose components are to be permuted */
82 : const Word16 *perm /* i : permutation info (indexes that should be interchanged), max two perms */
83 : )
84 : {
85 : Word16 p1, p2;
86 : Word16 tmp;
87 :
88 1730 : p1 = perm[0];
89 1730 : move16();
90 1730 : p2 = perm[1];
91 1730 : move16();
92 1730 : tmp = pTmp1[p1];
93 1730 : move16();
94 1730 : pTmp1[p1] = pTmp1[p2];
95 1730 : move16();
96 1730 : move16();
97 1730 : pTmp1[p2] = tmp;
98 1730 : move16();
99 1730 : p1 = perm[2];
100 1730 : move16();
101 :
102 1730 : IF( GT_16( p1, -1 ) )
103 : {
104 270 : p2 = perm[3];
105 270 : move16();
106 270 : tmp = pTmp1[p1];
107 270 : move16();
108 270 : pTmp1[p1] = pTmp1[p2];
109 270 : move16();
110 270 : move16();
111 270 : pTmp1[p2] = tmp;
112 270 : move16();
113 : }
114 :
115 1730 : return;
116 : }
117 :
118 :
119 7239 : void init_lvq_fx(
120 : Word32 offset_scale1[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
121 : Word32 offset_scale2[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
122 : Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
123 : Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
124 : Word16 no_scales[][2], /* o: number of truncations for each LSF subvector at each MSLVQ structure - safety net */
125 : Word16 no_scales_p[][2] /* o: number of truncations for each LSF subvector at each MSLVQ structure - predictive */
126 : )
127 : {
128 : Word16 i, j;
129 : Word16 k;
130 : /* safety-net mode */
131 933831 : FOR( i = 0; i < MAX_NO_MODES; i++ )
132 : {
133 3633978 : FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
134 : {
135 2707386 : if ( no_lead_fx[i][j] > 0 )
136 : {
137 2475738 : k = add( k, 1 );
138 : }
139 2707386 : if ( no_lead_fx[i][j] <= 0 )
140 : {
141 231648 : j = MAX_NO_SCALES - 1;
142 231648 : move16();
143 : }
144 : }
145 926592 : no_scales[i][0] = k;
146 926592 : move16();
147 :
148 3474720 : FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
149 : {
150 2548128 : if ( no_lead_fx[i][j] > 0 )
151 : {
152 2070354 : k = add( k, 1 );
153 : }
154 2548128 : if ( no_lead_fx[i][j] <= 0 )
155 : {
156 477774 : j = MAX_NO_SCALES << 1;
157 477774 : move16();
158 : }
159 : }
160 926592 : no_scales[i][1] = k;
161 926592 : move16();
162 : }
163 : /* predictive mode */
164 1056894 : FOR( i = 0; i < MAX_NO_MODES_p; i++ )
165 : {
166 4147947 : FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; j++ )
167 : {
168 3098292 : if ( no_lead_p_fx[i][j] > 0 )
169 : {
170 2975229 : k = add( k, 1 );
171 : }
172 3098292 : if ( ( no_lead_p_fx[i][j] <= 0 ) )
173 : {
174 123063 : j = MAX_NO_SCALES - 1;
175 123063 : move16();
176 : }
177 : }
178 1049655 : no_scales_p[i][0] = k;
179 1049655 : move16();
180 :
181 3938016 : FOR( k = 0; j < MAX_NO_SCALES << 1; j++ )
182 : {
183 2888361 : if ( no_lead_p_fx[i][j] > 0 )
184 : {
185 2359914 : k = add( k, 1 );
186 : }
187 :
188 2888361 : if ( ( no_lead_p_fx[i][j] <= 0 ) )
189 : {
190 528447 : j = MAX_NO_SCALES << 1;
191 528447 : move16();
192 : }
193 : }
194 :
195 1049655 : no_scales_p[i][1] = k;
196 1049655 : move16();
197 : }
198 : /* index offsets for each truncation */
199 7239 : init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p );
200 7239 : }
201 :
202 : /* make_offset_scale_fx() - calculates scale offset values for a particular MSLVQ structure */
203 3952494 : static void make_offset_scale_fx(
204 : Word16 j, /* i: MSLVQ structure index */
205 : const Word32 tab_no_cv[], /* i: cummulated number of codevectors in each leader class */
206 : const Word16 no_ld[], /* i: number of leaders in each truncation for the MSLVQ structure j*/
207 : Word16 no_scl, /* i: number of truncations in the MSLVQ structure j */
208 : Word32 offset_scale[][MAX_NO_SCALES + 1] /* o: offset values */
209 : )
210 : {
211 : Word16 i;
212 :
213 3952494 : offset_scale[j][0] = L_deposit_l( 1 );
214 3952494 : move32();
215 13833729 : FOR( i = 1; i <= no_scl; i++ )
216 : {
217 9881235 : offset_scale[j][i] = L_add( offset_scale[j][sub( i, 1 )], tab_no_cv[no_ld[sub( i, 1 )]] );
218 9881235 : move32();
219 : }
220 :
221 3952494 : return;
222 : }
223 :
224 2707384 : static void make_offset_scale(
225 : const UWord32 tab_no_cv[],
226 : const Word8 *no_ld,
227 : const Word16 no_scl,
228 : UWord32 *offset_scale )
229 : {
230 : Word16 i;
231 :
232 2707384 : offset_scale[0] = 1;
233 2707384 : move32();
234 10829536 : FOR( i = 1; i <= no_scl; i++ )
235 : {
236 8122152 : offset_scale[i] = UL_addNsD( offset_scale[i - 1], tab_no_cv[(Word16) no_ld[i - 1]] );
237 8122152 : move32();
238 : }
239 :
240 2707384 : return;
241 : }
242 :
243 7239 : void init_offset_fx(
244 : Word32 offset_scale1[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
245 : Word32 offset_scale2[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
246 : Word32 offset_scale1_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - predictive structures*/
247 : Word32 offset_scale2_p[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - predictive structures*/
248 : Word16 no_scales[][2], /* i: number of truncations for each LSF subvector at each MSLVQ structure - safety net */
249 : Word16 no_scales_p[][2] /* i: number of truncations for each LSF subvector at each MSLVQ structure - predictive */
250 : )
251 : {
252 : Word16 j;
253 : /* safety-net */
254 933831 : FOR( j = 0; j < MAX_NO_MODES; j++ )
255 : {
256 926592 : make_offset_scale_fx( j, table_no_cv_fx, no_lead_fx[j], no_scales[j][0], offset_scale1 );
257 926592 : make_offset_scale_fx( j, table_no_cv_fx, &no_lead_fx[j][MAX_NO_SCALES], no_scales[j][1], offset_scale2 );
258 : }
259 : /* predictive modes AR and MA */
260 1056894 : FOR( j = 0; j < MAX_NO_MODES_p; j++ )
261 : {
262 1049655 : make_offset_scale_fx( j, table_no_cv_fx, no_lead_p_fx[j], no_scales_p[j][0], offset_scale1_p );
263 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 );
264 : }
265 :
266 7239 : offset_scale1[MAX_NO_MODES][0] = 1;
267 7239 : move32();
268 7239 : offset_scale2[MAX_NO_MODES][0] = 1;
269 7239 : move32();
270 7239 : offset_scale1_p[MAX_NO_MODES_p][0] = 1;
271 7239 : move32();
272 7239 : offset_scale2_p[MAX_NO_MODES_p][0] = 1;
273 7239 : move32();
274 :
275 7239 : return;
276 : }
277 :
278 : static Word16
279 4144 : decode_indexes_fx(
280 : Word16 *index, /* i: LSF vector index, written as array of Word16 because it generally uses more than 16 bits */
281 : Word16 no_bits, /* i: number of bits for the index */
282 : const Word16 *p_scales, /* i: scale values for the MSLVQ structures */
283 : Word16 *p_no_scales, /* i: number of truncations for each MSLVQ structure */
284 : Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
285 : Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
286 : Word16 *x_lvq, /* o: decoded LSF vector in Q1 */
287 : Word16 mode_glb, /* i: index of LSLVQ structure */
288 : // note_ : renamed from scales
289 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector */
290 : )
291 : {
292 4144 : Word32 index1 = 0, index2 = 0;
293 4144 : move32();
294 4144 : move32();
295 4144 : Word16 len_scales = MAX_NO_SCALES * 2, no_modes;
296 4144 : move16();
297 : Word16 i, im1, idx_scale;
298 : Word16 tmp;
299 :
300 4144 : no_modes = MAX_NO_SCALES + 1;
301 4144 : move16();
302 :
303 4144 : IF( LE_16( no_bits, shl( LEN_INDICE, 1 ) ) ) /* the third short is not used */
304 : {
305 2402 : index[2] = 0;
306 2402 : move16();
307 2402 : if ( LE_16( no_bits, LEN_INDICE ) )
308 : {
309 0 : index[1] = 0;
310 0 : move16();
311 : }
312 : }
313 :
314 : /* safety check in case of bit errors */
315 16576 : FOR( i = 0; i < 3; i++ )
316 : {
317 12432 : IF( index[i] < 0 )
318 : {
319 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
320 0 : scales_mslvq[0] = 0;
321 0 : move16();
322 0 : scales_mslvq[1] = 0;
323 0 : move16();
324 0 : index[i] = 0;
325 0 : move16();
326 0 : return 1;
327 : }
328 : }
329 :
330 : /* first subvector */
331 4144 : tmp = i_mult2( mode_glb, no_modes );
332 :
333 4144 : IF( p_offset_scale2[add( tmp, p_no_scales[add( shl( mode_glb, 1 ), 1 )] )] > 0 )
334 : {
335 4144 : divide_64_32_fx( index, p_offset_scale2[tmp + p_no_scales[add( shl( mode_glb, 1 ), 1 )]], &index1, &index2 );
336 : }
337 : ELSE
338 : {
339 0 : index1 = L_deposit_l( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
340 0 : index2 = L_deposit_l( 0 );
341 : }
342 4144 : IF( index1 == 0 )
343 : {
344 0 : FOR( i = 0; i < LATTICE_DIM; i++ )
345 : {
346 0 : x_lvq[i] = 0;
347 0 : move16();
348 : }
349 0 : scales_mslvq[0] = 0;
350 0 : move16();
351 : }
352 : ELSE
353 : {
354 4144 : IF( GE_32( index1, p_offset_scale1[mode_glb * no_modes + p_no_scales[mode_glb * 2]] ) )
355 : {
356 : /* safety check in case of bit errors */
357 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
358 0 : scales_mslvq[0] = 0;
359 0 : move16();
360 0 : scales_mslvq[1] = 0;
361 0 : move16();
362 0 : return 1;
363 : }
364 :
365 : /* find idx_scale */
366 4144 : i = 1;
367 4144 : move16();
368 6734 : WHILE( LE_16( i, p_no_scales[mode_glb * 2] ) && GE_32( index1, p_offset_scale1[mode_glb * no_modes + i] ) )
369 : {
370 2590 : i = add( i, 1 );
371 : }
372 4144 : idx_scale = sub( i, 1 );
373 4144 : move16();
374 4144 : index1 = L_sub( index1, p_offset_scale1[tmp + idx_scale] );
375 :
376 : /* find idx_leader */
377 4144 : i = 1;
378 4144 : move16();
379 :
380 48269 : WHILE( GE_32( index1, table_no_cv_fx[i] ) )
381 : {
382 44125 : i = add( i, 1 );
383 : }
384 4144 : im1 = sub( i, 1 );
385 4144 : decode_comb_fx( L_sub( index1, table_no_cv_fx[im1] ), x_lvq, im1 );
386 4144 : scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
387 4144 : move16();
388 : }
389 :
390 : /* second subvector */
391 4144 : IF( index2 == 0 )
392 : {
393 270 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
394 : {
395 240 : x_lvq[i] = 0;
396 240 : move16();
397 : }
398 30 : scales_mslvq[1] = 0;
399 30 : move16();
400 : }
401 : ELSE
402 : {
403 : /* find the index for the scale/truncation */
404 4114 : i = 1;
405 4114 : move16();
406 6163 : WHILE( GE_32( index2, p_offset_scale2[tmp + i] ) )
407 : {
408 2049 : i = add( i, 1 );
409 : }
410 :
411 4114 : idx_scale = sub( i, 1 );
412 4114 : index2 = L_sub( index2, p_offset_scale2[add( tmp, idx_scale )] );
413 : /* find the index of the leader vector */
414 4114 : i = 1;
415 4114 : move16();
416 17900 : WHILE( GE_32( index2, table_no_cv_fx[i] ) )
417 : {
418 13786 : i = add( i, 1 );
419 : }
420 4114 : im1 = sub( i, 1 );
421 4114 : decode_comb_fx( index2 - table_no_cv_fx[im1], &x_lvq[LATTICE_DIM], im1 );
422 4114 : scales_mslvq[1] = p_scales[add( i_mult2( mode_glb, len_scales ), add( MAX_NO_SCALES, idx_scale ) )];
423 4114 : move16();
424 : }
425 :
426 4144 : return 0;
427 : }
428 :
429 504351 : static Word16 decode_indexes_ivas_fx(
430 : Word16 *index,
431 : const Word16 no_bits,
432 : const Word16 *p_scales, // Q11
433 : const Word16 prediction_flag,
434 : Word16 *x_lvq, // Q1
435 : const Word16 mode_glb,
436 : Word16 *scales_mslvq /* o: scale values for the decoded MSLVQ LSF codevector Q11*/
437 : )
438 : {
439 504351 : Word32 index1 = 0, index2, idx_scale;
440 504351 : move32();
441 : Word16 i;
442 :
443 504351 : Word16 len_scales = i_mult( MAX_NO_SCALES, 2 );
444 : UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
445 :
446 504351 : IF( LE_16( no_bits, 2 * LEN_INDICE ) ) /* the third short is not used */
447 : {
448 276397 : index[2] = 0;
449 276397 : move16();
450 276397 : if ( LE_16( no_bits, LEN_INDICE ) )
451 : {
452 1140 : index[1] = 0;
453 1140 : move16();
454 : }
455 : }
456 :
457 : /* safety check in case of bit errors */
458 2017404 : FOR( i = 0; i < 3; i++ )
459 : {
460 1513053 : IF( index[i] < 0 )
461 : {
462 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
463 0 : scales_mslvq[0] = 0;
464 0 : move16();
465 0 : scales_mslvq[1] = 0;
466 0 : move16();
467 0 : index[i] = 0;
468 0 : return 1;
469 : }
470 : }
471 :
472 504351 : create_offset( offset_scale1, offset_scale2, mode_glb, prediction_flag );
473 : /* first subvector */
474 504351 : IF( offset_scale2[MAX_NO_SCALES - 1] > 0 )
475 : {
476 504351 : divide_64_32_fx( index, offset_scale2[MAX_NO_SCALES], &index1, &index2 );
477 : }
478 : ELSE
479 : {
480 0 : index1 = (UWord32) ( index[0] ); /* this is for very low bitrates, so there is no loss in truncation */
481 0 : move32();
482 0 : index2 = 0;
483 0 : move32();
484 : }
485 :
486 504351 : IF( index1 == 0 )
487 : {
488 1584 : FOR( i = 0; i < LATTICE_DIM; i++ )
489 : {
490 1408 : x_lvq[i] = 0;
491 1408 : scales_mslvq[0] = 0;
492 1408 : move16();
493 : }
494 : }
495 : ELSE
496 : {
497 504175 : IF( GE_32( index1, (Word32) offset_scale1[MAX_NO_SCALES] ) )
498 : {
499 : /* safety check in case of bit errors */
500 0 : set16_fx( x_lvq, 0, 2 * LATTICE_DIM );
501 0 : scales_mslvq[0] = 0;
502 0 : move16();
503 0 : scales_mslvq[1] = 0;
504 0 : move16();
505 0 : return 1;
506 : }
507 :
508 : /* find idx_scale */
509 504175 : i = 1;
510 504175 : test();
511 780492 : WHILE( LE_16( (Word16) i, MAX_NO_SCALES ) && GE_32( index1, (Word32) offset_scale1[i] ) )
512 : {
513 276317 : i++;
514 : }
515 :
516 504175 : idx_scale = i - 1;
517 504175 : index1 = L_sub( index1, offset_scale1[idx_scale] );
518 :
519 : /* find idx_leader */
520 504175 : i = 1;
521 504175 : move16();
522 6138221 : WHILE( GE_32( index1, (Word32) table_no_cv[i] ) )
523 : {
524 5634046 : i++;
525 : }
526 504175 : decode_comb_fx( (Word32) ( index1 - table_no_cv[i - 1] ), x_lvq, i - 1 );
527 504175 : scales_mslvq[0] = p_scales[mode_glb * len_scales + idx_scale];
528 504175 : move16();
529 : // for (i = 0; i < LATTICE_DIM; i++)
530 : //{
531 : // //x_lvq[i] *= scale;
532 : // x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
533 : // }
534 : }
535 :
536 : /* second subvector */
537 504351 : IF( index2 == 0 )
538 : {
539 190341 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
540 : {
541 : // x_lvq[i] = 0.0;
542 169192 : x_lvq[i] = 0;
543 169192 : move16();
544 : }
545 21149 : scales_mslvq[1] = 0;
546 21149 : move16();
547 : }
548 : ELSE
549 : {
550 :
551 : /* find the index for the scale/truncation */
552 483202 : i = 1;
553 483202 : move16();
554 722512 : WHILE( GE_32( index2, (Word32) offset_scale2[i] ) )
555 : {
556 239310 : i++;
557 : }
558 :
559 483202 : idx_scale = i - 1;
560 483202 : move16();
561 483202 : index2 = L_sub( index2, offset_scale2[idx_scale] );
562 : /* find the index of the leader vector */
563 483202 : i = 1;
564 483202 : move16();
565 2149073 : WHILE( GE_32( index2, (Word32) table_no_cv[i] ) )
566 : {
567 1665871 : i++;
568 : }
569 483202 : decode_comb_fx( (Word32) ( index2 - table_no_cv[i - 1] ), &x_lvq[LATTICE_DIM], i - 1 );
570 :
571 483202 : scales_mslvq[1] = p_scales[mode_glb * len_scales + MAX_NO_SCALES + idx_scale];
572 483202 : move16();
573 : // for (i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++)
574 : //{
575 : // //x_lvq[i] *= scale;
576 : // x_lvq[i] = mult_r(shl(x_lvq[i], Q3), scale); //Q0
577 : // }
578 : }
579 :
580 504351 : return 0;
581 : }
582 :
583 4144 : Word16 deindex_lvq_fx(
584 : Word16 *index, /* i : index to be decoded, as an array of 3 Word16 */
585 : Word16 *x_lvq, /* o : decoded codevector Q(x2.56) */
586 : Word16 mode, /* i : LVQ coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
587 : Word16 sf_flag, /* i : safety net flag */
588 : Word16 no_bits, /* i : number of bits for lattice */
589 : Word32 *p_offset_scale1, /* i : offset for first subvector */
590 : Word32 *p_offset_scale2, /* i : offset for the second subvector */
591 : Word16 *p_no_scales /* i : number of scales for each truncation and each MSLVQ structure */
592 : )
593 : {
594 : Word16 i;
595 : const Word16 *p_scales;
596 : Word16 mode_glb;
597 : Word32 L_tmp;
598 : // note_ : renamed from scales
599 : Word16 scales_mslvq[2];
600 : Word16 ber_flag;
601 :
602 4144 : IF( EQ_16( sf_flag, 1 ) )
603 : {
604 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] )] );
605 523 : p_scales = &scales_fx[0][0];
606 523 : move16();
607 : }
608 : ELSE
609 : {
610 3621 : 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] )] );
611 3621 : p_scales = &scales_p_fx[0][0];
612 3621 : move16();
613 : }
614 :
615 : /* decode the lattice index into the lattice codevectors for the two subvectors */
616 : ber_flag =
617 4144 : decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1,
618 : p_offset_scale2, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
619 :
620 :
621 4144 : IF( EQ_16( sf_flag, 1 ) )
622 : {
623 : /* safety-net case*/
624 523 : IF( scales_mslvq[0] )
625 : {
626 4707 : FOR( i = 0; i < LATTICE_DIM; i++ )
627 : {
628 4184 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
629 : /* Increase calculation accuracy by shifting more to the left and using rounding instead of truncation*/
630 4184 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
631 4184 : x_lvq[i] = round_fx( L_tmp );
632 4184 : move16();
633 : }
634 : }
635 523 : IF( scales_mslvq[1] )
636 : {
637 4599 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
638 : {
639 4088 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
640 4088 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
641 4088 : x_lvq[i] = round_fx( L_tmp );
642 4088 : move16();
643 : }
644 : }
645 : }
646 : ELSE
647 : {
648 : /* predictive mode AR or MA */
649 3621 : IF( scales_mslvq[0] )
650 : {
651 32589 : FOR( i = 0; i < LATTICE_DIM; i++ )
652 : {
653 28968 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
654 28968 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
655 28968 : x_lvq[i] = round_fx( L_tmp );
656 28968 : move16();
657 : }
658 : }
659 3621 : IF( scales_mslvq[1] )
660 : {
661 32427 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
662 : {
663 28824 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
664 28824 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
665 28824 : x_lvq[i] = round_fx( L_tmp );
666 28824 : move16();
667 : }
668 : }
669 : }
670 :
671 4144 : return ber_flag;
672 : }
673 :
674 503934 : Word16 deindex_lvq_ivas_fx(
675 : Word16 *index, /* i : index to be decoded, as an array of 3 Word16 */
676 : Word16 *x_lvq, /* o : decoded codevector Q(x2.56) */
677 : Word16 mode, /* i : LVQ coding mode/MSLVQ structure index (select scales & no_lead ), or idx_cv for CNG case */
678 : Word16 sf_flag, /* i : safety net flag */
679 : Word16 no_bits /* i : number of bits for lattice */
680 : )
681 : {
682 : Word16 i;
683 : const Word16 *p_scales;
684 : Word16 mode_glb;
685 : Word32 L_tmp;
686 : // note_ : renamed from scales
687 : Word16 scales_mslvq[2];
688 : Word16 ber_flag;
689 :
690 503934 : IF( EQ_16( sf_flag, 1 ) )
691 : {
692 71079 : IF( LT_16( mode, 6 ) ) /* for NB */
693 : {
694 0 : mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][sub( no_bits, min_lat_bits_SN[mode] )] );
695 : }
696 : ELSE
697 : {
698 71079 : mode_glb = add( offset_lvq_modes_SN[mode], sub( no_bits, min_lat_bits_SN[mode] ) ); /* there is granularity of 1 bit */
699 : }
700 71079 : p_scales = &scales_ivas_fx[0][0]; // Q11
701 71079 : move16();
702 : }
703 : ELSE
704 : {
705 432855 : test();
706 432855 : IF( ( LT_16( mode, 6 ) ) || ( EQ_16( mode, 12 ) ) ) /* for NB */
707 : {
708 9595 : mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][sub( no_bits, min_lat_bits_pred[mode] )] );
709 : }
710 : ELSE
711 : {
712 423260 : mode_glb = add( offset_lvq_modes_pred[mode], sub( no_bits, min_lat_bits_pred[mode] ) );
713 : }
714 432855 : p_scales = &scales_p_ivas_fx[0][0]; // Q11
715 432855 : move16();
716 : }
717 :
718 : UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
719 503934 : create_offset( offset_scale1, offset_scale2, mode_glb, 1 - sf_flag );
720 :
721 : /* decode the lattice index into the lattice codevectors for the two subvectors */
722 : // ber_flag =
723 : // decode_indexes_fx(index, no_bits, p_scales, p_no_scales, offset_scale1,
724 : // offset_scale2, x_lvq, mode_glb, scales_mslvq); /* x_lvq is here Q1 */
725 : ber_flag =
726 503934 : decode_indexes_ivas_fx( index, no_bits, p_scales, 1 - sf_flag, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */
727 :
728 :
729 503934 : IF( EQ_16( sf_flag, 1 ) )
730 : {
731 : /* safety-net case*/
732 71079 : IF( scales_mslvq[0] )
733 : {
734 638937 : FOR( i = 0; i < LATTICE_DIM; i++ )
735 : {
736 567944 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
737 : /* Increase calculation accuracy by shifting more to the left and using rounding instead of truncation*/
738 567944 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
739 567944 : x_lvq[i] = round_fx( L_tmp );
740 567944 : move16();
741 : }
742 : }
743 71079 : IF( scales_mslvq[1] )
744 : {
745 596772 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
746 : {
747 530464 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
748 530464 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
749 530464 : x_lvq[i] = round_fx( L_tmp );
750 530464 : move16();
751 : }
752 : }
753 : }
754 : ELSE
755 : {
756 : /* predictive mode AR or MA */
757 432855 : IF( scales_mslvq[0] )
758 : {
759 3894948 : FOR( i = 0; i < LATTICE_DIM; i++ )
760 : {
761 3462176 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
762 3462176 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
763 3462176 : x_lvq[i] = round_fx( L_tmp );
764 3462176 : move16();
765 : }
766 : }
767 432855 : IF( scales_mslvq[1] )
768 : {
769 3748302 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
770 : {
771 3331824 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
772 3331824 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_p_ivas_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
773 3331824 : x_lvq[i] = round_fx( L_tmp );
774 3331824 : move16();
775 : }
776 : }
777 : }
778 :
779 503934 : return ber_flag;
780 : }
781 :
782 : /*----------------------------------------------------------------------------------------------------*
783 : * deindex_lvq_cng()
784 : * Note:
785 : * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
786 : * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
787 : * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
788 : *----------------------------------------------------------------------------------------------------*/
789 :
790 0 : Word16 deindex_lvq_cng_fx(
791 : Word16 *index, /* i: index to be decoded, as an array of 3 short */
792 : Word16 *x_lvq, /* o: decoded codevector Q9 */
793 : Word16 idx_cv, /* i: relative mode_lvq, wrt START_CNG */
794 : Word16 no_bits, /* i: number of bits for lattice */
795 : Word32 *p_offset_scale1, /* i: scale index offset for first LSF subvector */
796 : Word32 *p_offset_scale2, /* i: scale index offset for second LSF subvector */
797 : Word16 *p_no_scales /* i: number of scales for each MSLVQ structure and each subvector */
798 : )
799 : {
800 : Word16 i;
801 : Word32 L_tmp;
802 : const Word16 *p_scales;
803 : Word16 mode_glb, mode;
804 : // note_ : renamed from scales as global declaration of scales is causing warning
805 : Word16 scales_mslvq[2];
806 : Word16 ber_flag;
807 :
808 : /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
809 0 : mode_glb = add( START_CNG, idx_cv );
810 :
811 0 : mode = add( LVQ_COD_MODES, idx_cv );
812 :
813 0 : p_scales = &scales_fx[0][0];
814 0 : move16();
815 : ber_flag =
816 0 : decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq );
817 :
818 0 : FOR( i = 0; i < LATTICE_DIM; i++ )
819 : {
820 0 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
821 0 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
822 0 : x_lvq[i] = round_fx( L_tmp );
823 0 : move16();
824 : }
825 0 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
826 : {
827 0 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
828 0 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
829 0 : x_lvq[i] = round_fx( L_tmp );
830 0 : move16();
831 : }
832 :
833 : /* check if permutting needed */
834 0 : IF( cng_sort[idx_cv] )
835 : {
836 0 : permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
837 : }
838 :
839 0 : return ber_flag;
840 : }
841 :
842 :
843 : /*----------------------------------------------------------------------------------------------------*
844 : * deindex_lvq_cng()
845 : * Note:
846 : * The sampling frequency for the LVQ CNG decoder frame can be determined by checking the fully decoded
847 : * value of the highest order LSF coefficient. Thus sampling rate information, nor extra codebooks are
848 : * not needed for deindex_lvq_cng(), since it is embedded inside the LSF codebooks.
849 : *----------------------------------------------------------------------------------------------------*/
850 :
851 417 : Word16 deindex_lvq_cng_ivas_fx(
852 : Word16 *index, /* i: index to be decoded, as an array of 3 short */
853 : Word16 *x_lvq, /* o: decoded codevector Q9 */
854 : Word16 idx_cv, /* i: relative mode_lvq, wrt START_CNG */
855 : Word16 no_bits /* i: number of bits for lattice */
856 : )
857 : {
858 : Word16 i;
859 : Word32 L_tmp;
860 : const Word16 *p_scales;
861 : Word16 mode_glb, mode;
862 : // note_ : renamed from scales as global declaration of scales is causing warning
863 : Word16 scales_mslvq[2];
864 : Word16 ber_flag;
865 :
866 : /* the MSLVQ structure in the second LP-CNG stage depends on the index from the first stage */
867 417 : mode_glb = add( START_CNG_IVAS, idx_cv );
868 :
869 417 : mode = add( LVQ_COD_MODES, idx_cv );
870 :
871 417 : p_scales = &scales_ivas_fx[0][0];
872 417 : move16();
873 : // ber_flag =
874 : // decode_indexes_fx(index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq);
875 : ber_flag =
876 417 : decode_indexes_ivas_fx( index, no_bits, p_scales, 0, x_lvq, mode_glb, scales_mslvq );
877 :
878 3753 : FOR( i = 0; i < LATTICE_DIM; i++ )
879 : {
880 3336 : L_tmp = L_mult( x_lvq[i], scales_mslvq[0] ); /* Q1+Q11+Q1 = Q13 */
881 3336 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
882 3336 : x_lvq[i] = round_fx( L_tmp );
883 3336 : move16();
884 : }
885 3753 : FOR( i = LATTICE_DIM; i < 2 * LATTICE_DIM; i++ )
886 : {
887 3336 : L_tmp = L_mult( x_lvq[i], scales_mslvq[1] ); /* Q1+Q11+Q1 = Q13 */
888 3336 : L_tmp = L_shl( Mult_32_16( L_tmp, shl( sigma_MSLVQ_fx[mode][i], 3 ) ), 15 ); /* Q13 + Q2 +x2.56 -Q15 */
889 3336 : x_lvq[i] = round_fx( L_tmp );
890 3336 : move16();
891 : }
892 :
893 : /* check if permutting needed */
894 417 : IF( cng_sort[idx_cv] )
895 : {
896 410 : permute_fx( x_lvq, perm_MSLVQ[idx_cv] );
897 : }
898 :
899 417 : return ber_flag;
900 : }
901 :
902 : /* combinatorial indexing */
903 3199786 : static void idx2c_fx(
904 : Word16 n, /* i : total number of positions (components)*/
905 : Word16 *p, /* o : array with positions of the k components */
906 : Word16 k, /* i : number of components whose position is to be determined */
907 : Word16 val /* i : index to be decoded */
908 : )
909 : {
910 : Word16 i, skip, pos, k1;
911 :
912 3199786 : skip = 0;
913 3199786 : move16();
914 3199786 : pos = 0;
915 3199786 : move16();
916 3199786 : k1 = sub( k, 1 );
917 3199786 : move16();
918 6766122 : WHILE( LT_16( add( skip, sub( C_VQ[n - pos - 1][k1], 1 ) ), val ) )
919 : {
920 3566336 : skip = add( skip, C_VQ[n - pos - 1][k1] );
921 3566336 : move16();
922 3566336 : pos++;
923 3566336 : move16();
924 : }
925 :
926 3199786 : p[0] = pos;
927 3199786 : move16();
928 3199786 : n = sub( n, add( pos, 1 ) );
929 3199786 : val = sub( val, skip );
930 3199786 : IF( EQ_16( k, 1 ) )
931 : {
932 1200719 : return;
933 : }
934 :
935 1999067 : idx2c_fx( n, p + 1, k1, val );
936 :
937 : /* pos+1 */
938 6058999 : FOR( i = 1; i < k; i++ )
939 : {
940 4059932 : p[i] = add( p[i], add( pos, 1 ) );
941 4059932 : move16();
942 : }
943 :
944 1999067 : return;
945 : }
946 : /* combinatorial deindexing */
947 998807 : static void decode_comb_fx(
948 : Word32 index, /* i : index to be decoded */
949 : Word16 *cv, /* o : decoded codevector Q1*/
950 : Word16 idx_lead /* i : leader class index */
951 : )
952 : {
953 : Word16 idx_sign;
954 998807 : IF( LT_32( L_shl( index, 1 ), pi0[idx_lead] ) )
955 : {
956 73859 : idx_sign = 0;
957 73859 : move16();
958 : }
959 : ELSE
960 : {
961 924948 : idx_sign = extract_l( div_l( L_shl( index, 1 ), pi0[idx_lead] ) ); /*(index/pi0_fx[idx_lead]); */
962 : }
963 998807 : index = L_sub( index, L_mult0( idx_sign, pi0[idx_lead] ) );
964 998807 : decode_leaders_fx( extract_l( index ), idx_lead, cv );
965 998807 : decode_sign_pc1_fx( cv, idx_sign, pl_par[idx_lead] );
966 :
967 998807 : return;
968 : }
969 998807 : void decode_sign_pc1_fx(
970 : Word16 *c, /* o : decoded codevector Q1*/
971 : Word16 idx_sign, /* i : sign index */
972 : Word16 parity /* i : parity flag (+1/-1/0) */
973 : )
974 : {
975 998807 : Word16 i, len = LATTICE_DIM, cnt_neg = 1;
976 :
977 998807 : if ( parity )
978 : {
979 421122 : len = sub( len, 1 );
980 : }
981 :
982 8568141 : FOR( i = 0; i < len; i++ )
983 : {
984 7569334 : IF( c[i] > 0 )
985 : {
986 : /*if (idx_sign % 2) */
987 5498772 : IF( s_and( idx_sign, 1 ) )
988 : {
989 2657370 : c[i] = negate( c[i] );
990 2657370 : move16();
991 2657370 : cnt_neg = negate( cnt_neg );
992 2657370 : move16();
993 : }
994 5498772 : idx_sign = shr( idx_sign, 1 ); /* >>= 1; */
995 : }
996 : }
997 :
998 998807 : IF( LT_16( len, LATTICE_DIM ) )
999 : {
1000 421122 : IF( NE_16( cnt_neg, parity ) )
1001 : {
1002 190921 : c[len] = negate( c[len] );
1003 190921 : move16();
1004 : }
1005 : }
1006 :
1007 998807 : return;
1008 : }
1009 :
1010 :
1011 998807 : static void decode_leaders_fx(
1012 : Word16 index, /* i : index to be decoded */
1013 : Word16 idx_lead, /* i : leader class index */
1014 : Word16 *cv /* o : decoded codevector Q1*/
1015 : )
1016 : {
1017 : Word16 i, no_vals_loc, no_vals_last, p[LATTICE_DIM], dim_loc, n_crt;
1018 : Word16 index1;
1019 : Word16 val_crt;
1020 :
1021 998807 : no_vals_loc = no_vals[idx_lead];
1022 998807 : move16();
1023 998807 : val_crt = vals_fx[idx_lead][no_vals_loc - 1];
1024 998807 : move16(); /*Q1 */
1025 998807 : no_vals_last = no_vals_ind[idx_lead][no_vals_loc - 1];
1026 998807 : move16();
1027 :
1028 5789477 : FOR( i = 0; i < no_vals_last; i++ )
1029 : {
1030 4790670 : cv[i] = val_crt;
1031 4790670 : move16(); /*Q1 */
1032 : }
1033 :
1034 998807 : val_crt = 1;
1035 998807 : move16();
1036 998807 : dim_loc = no_vals_last;
1037 998807 : move16();
1038 :
1039 998807 : SWITCH( no_vals_loc )
1040 : {
1041 99849 : case 1:
1042 99849 : BREAK;
1043 599708 : case 2:
1044 599708 : idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index );
1045 599708 : put_value_fx( cv, p, vals_fx[idx_lead][0], no_vals_last, no_vals_ind[idx_lead][0] );
1046 599708 : BREAK;
1047 2511 : case 4:
1048 2511 : dim_loc = add( dim_loc, no_vals_ind[idx_lead][2] );
1049 2511 : n_crt = no_vals_ind[idx_lead][2];
1050 2511 : move16();
1051 2511 : index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index ); /* index1 = index/C_VQ_fx[dim_loc][n_crt]; */
1052 2511 : /*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]) ); */ /* index-= index1*C_VQ_fx[dim_loc][n_crt]; */ move16();
1053 2511 : idx2c_fx( dim_loc, p, n_crt, index );
1054 2511 : put_value_fx( cv, p, vals_fx[idx_lead][2], no_vals_last, no_vals_ind[idx_lead][2] ); /* Q1 */
1055 2511 : index = index1;
1056 2511 : move16();
1057 : /* no break */
1058 299250 : case 3:
1059 299250 : dim_loc = add( dim_loc, no_vals_ind[idx_lead][1] );
1060 299250 : n_crt = no_vals_ind[idx_lead][1];
1061 299250 : move16();
1062 299250 : index1 = divide_16_16_fx( index, C_VQ[dim_loc][n_crt], &index );
1063 : /*index = sub(index, i_mult2(index1, C_VQ_fx[dim_loc][n_crt]));move16(); */
1064 299250 : idx2c_fx( dim_loc, p, n_crt, index );
1065 299250 : put_value_fx( cv, p, vals_fx[idx_lead][1], sub( dim_loc, n_crt ), n_crt );
1066 299250 : idx2c_fx( LATTICE_DIM, p, no_vals_ind[idx_lead][0], index1 );
1067 299250 : move16();
1068 299250 : put_value_fx( cv, p, vals_fx[idx_lead][0], dim_loc, no_vals_ind[idx_lead][0] );
1069 299250 : BREAK;
1070 : }
1071 :
1072 998807 : return;
1073 : }
1074 :
1075 : /* divide_32_32_fx() :Division reminder - rem is the reminder of the division between y and x. */
1076 626881 : static Word32 divide_32_32_fx( Word32 y, /* i */
1077 : Word32 x, /* i */
1078 : Word32 *rem /* o */
1079 : )
1080 : {
1081 : Word32 result, t, L_tmp;
1082 : Word16 i, ny, nx, nyx;
1083 :
1084 :
1085 626881 : IF( LT_32( y, x ) )
1086 : {
1087 26748 : result = L_deposit_l( 0 );
1088 26748 : *rem = y;
1089 26748 : move32();
1090 : }
1091 : ELSE
1092 : {
1093 :
1094 600133 : result = L_deposit_l( 0 );
1095 600133 : IF( y == 0 )
1096 : {
1097 0 : ny = 0;
1098 0 : move16();
1099 : }
1100 : ELSE
1101 : {
1102 600133 : ny = sub( 31, norm_l( y ) );
1103 : }
1104 600133 : IF( x == 0 )
1105 : {
1106 0 : nx = 0;
1107 0 : move16();
1108 : }
1109 : ELSE
1110 : {
1111 600133 : nx = sub( 31, norm_l( x ) );
1112 : }
1113 :
1114 600133 : nyx = sub( ny, nx );
1115 :
1116 : /*t = L_and(L_shr(y, add(nyx,1)),sub(shl(1,sub(nx,1)),1)); */
1117 600133 : t = L_shr( y, add( nyx, 1 ) );
1118 8706113 : FOR( i = 0; i <= nyx; i++ )
1119 : {
1120 8105980 : 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)))); */
1121 8105980 : result = L_shl( result, 1 );
1122 8105980 : L_tmp = L_sub( t, x );
1123 8105980 : IF( L_tmp >= 0 )
1124 : {
1125 4044245 : result = L_add( result, 1 );
1126 4044245 : t = L_add( L_tmp, 0 );
1127 : }
1128 : }
1129 600133 : *rem = t;
1130 600133 : move32();
1131 : }
1132 626881 : return result;
1133 : }
1134 :
1135 : /* divide_32_32_fx() :Division reminder for Word16 - rem is the reminder of the division between y and x. */
1136 301761 : static Word16 divide_16_16_fx( Word16 y, /* i */
1137 : Word16 x, /* i */
1138 : Word16 *rem /* o */
1139 : )
1140 : {
1141 : Word16 result, t, tmp;
1142 : Word16 i, ny, nx, nyx;
1143 :
1144 :
1145 301761 : IF( LT_32( y, x ) )
1146 : {
1147 36819 : result = 0;
1148 36819 : move16();
1149 36819 : *rem = y;
1150 36819 : move16();
1151 : }
1152 : ELSE
1153 : {
1154 :
1155 264942 : result = 0;
1156 264942 : move16();
1157 264942 : IF( y == 0 )
1158 : {
1159 0 : ny = 0;
1160 0 : move16();
1161 : }
1162 : ELSE
1163 : {
1164 264942 : ny = sub( 15, norm_s( y ) );
1165 : }
1166 264942 : IF( x == 0 )
1167 : {
1168 0 : nx = 0;
1169 0 : move16();
1170 : }
1171 : ELSE
1172 : {
1173 264942 : nx = sub( 15, norm_s( x ) );
1174 : }
1175 :
1176 264942 : nyx = sub( ny, nx );
1177 :
1178 264942 : t = s_and( shr( y, add( nyx, 1 ) ), sub( shl( 1, sub( nx, 1 ) ), 1 ) );
1179 1115074 : FOR( i = 0; i <= nyx; i++ )
1180 : {
1181 850132 : t = add( shl( t, 1 ), s_and( shr( y, sub( nyx, i ) ), 1 ) ); /* L_and(y,L_shl(1, sub(nyx,i)))); */
1182 850132 : result = shl( result, 1 );
1183 850132 : tmp = sub( t, x );
1184 850132 : IF( tmp >= 0 )
1185 : {
1186 490521 : result = add( result, 1 );
1187 490521 : t = tmp;
1188 490521 : move16();
1189 : }
1190 : }
1191 264942 : *rem = t;
1192 264942 : move16();
1193 : }
1194 301761 : return result;
1195 : }
1196 :
1197 508495 : static void divide_64_32_fx(
1198 : Word16 *xs, /* i : denominator as array of two int32 */
1199 : Word32 y, /* i : nominator on 32 bits */
1200 : Word32 *result, /* o : integer division result on 32 bits */
1201 : Word32 *rem /* o : integer division reminder on 32 bits */
1202 : )
1203 : {
1204 : Word16 nb_x1;
1205 : Word32 r, x_tmp, x[2], q, q1;
1206 :
1207 508495 : 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] ) );
1208 508495 : move32();
1209 508495 : x[1] = L_shr( L_deposit_l( xs[2] ), 1 );
1210 508495 : move32();
1211 :
1212 : /*x[0] = (((xs[2])&(1)<<(LEN_INDICE*2)) + (xs[1]<<LEN_INDICE) + xs[0];
1213 : x[1] = xs[2]>>1; */
1214 :
1215 508495 : IF( x[1] == 0 )
1216 : {
1217 390109 : nb_x1 = 0;
1218 390109 : move16();
1219 : }
1220 : ELSE
1221 : {
1222 118386 : nb_x1 = sub( 31, norm_l( x[1] ) ); /*get_no_bits_fx(x[1]); */
1223 : }
1224 : /* take the first 31 bits */
1225 508495 : IF( nb_x1 > 0 )
1226 : {
1227 118386 : x_tmp = L_add( L_shl( x[1], sub( 31, nb_x1 ) ), L_shr( x[0], nb_x1 ) );
1228 : /* x_tmp = (x[1]<<(32-nb_x1)) + (x[0]>>nb_x1); */
1229 :
1230 118386 : q = divide_32_32_fx( x_tmp, y, &r ); /* q = x_tmp/y, reminder r */
1231 118386 : 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 */
1232 : /* r = (r<<nb_x1)+(x[0]&((1<<nb_x1) - 1)); */
1233 :
1234 118386 : q1 = divide_32_32_fx( r, y, rem );
1235 118386 : *result = L_add( L_shl( q, nb_x1 ), q1 );
1236 118386 : move32();
1237 : }
1238 : ELSE
1239 : {
1240 390109 : *result = divide_32_32_fx( x[0], y, rem );
1241 390109 : move32();
1242 : }
1243 :
1244 508495 : return;
1245 : }
1246 :
1247 1200719 : static void put_value_fx(
1248 : Word16 *cv, /* i/o : input codevector Q1*/
1249 : Word16 *p, /* i : array with positions */
1250 : Word16 val, /* i : value to be inserted Q1*/
1251 : Word16 dim, /* i : vector dimension */
1252 : Word16 no_new_val /* i : number of values to be inserted */
1253 : )
1254 : {
1255 : Word16 cv_out[LATTICE_DIM];
1256 : Word16 i, occ[LATTICE_DIM], cnt, limit;
1257 :
1258 1200719 : limit = add( dim, no_new_val );
1259 10425239 : FOR( i = 0; i < limit; i++ )
1260 : {
1261 9224520 : occ[i] = 0;
1262 9224520 : move16();
1263 : }
1264 :
1265 4400505 : FOR( i = 0; i < no_new_val; i++ )
1266 : {
1267 3199786 : cv_out[p[i]] = val;
1268 3199786 : move16();
1269 3199786 : occ[p[i]] = 1;
1270 3199786 : move16();
1271 : }
1272 :
1273 1200719 : cnt = 0;
1274 1200719 : move16();
1275 10425239 : FOR( i = 0; i < limit; i++ )
1276 : {
1277 9224520 : if ( occ[i] == 0 )
1278 : {
1279 6024734 : cv_out[i] = cv[cnt++];
1280 6024734 : move16();
1281 : }
1282 : }
1283 :
1284 10425239 : FOR( i = 0; i < limit; i++ )
1285 : {
1286 9224520 : cv[i] = cv_out[i];
1287 9224520 : move16();
1288 : }
1289 :
1290 1200719 : return;
1291 : }
1292 :
1293 : /*-----------------------------------------------------------------*
1294 : * create_offset()
1295 : *
1296 : *
1297 : *-----------------------------------------------------------------*/
1298 :
1299 1353692 : void create_offset(
1300 : UWord32 *offset_scale1,
1301 : UWord32 *offset_scale2,
1302 : const Word16 mode,
1303 : const Word16 prediction_flag )
1304 : {
1305 : Word16 tmp, tmp1;
1306 :
1307 1353692 : if ( prediction_flag == 0 )
1308 : {
1309 : /* safety_net */
1310 233856 : tmp = no_lead_idx[mode][0];
1311 233856 : if ( ( tmp <= LIMIT_LEADER ) && ( tmp < no_lead_idx[mode][1] - 2 ) )
1312 : {
1313 0 : tmp += DELTA_LEADER;
1314 : }
1315 233856 : make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
1316 233856 : make_offset_scale( table_no_cv, leaders_short[no_lead_idx[mode][1]], MAX_NO_SCALES, offset_scale2 );
1317 : }
1318 : else
1319 : {
1320 1119836 : tmp = no_lead_p_idx[mode][0];
1321 1119836 : tmp1 = no_lead_p_idx[mode][1];
1322 1119836 : if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
1323 : {
1324 25763 : tmp += DELTA_LEADER;
1325 : }
1326 :
1327 1119836 : if ( ( tmp == LIMIT_LEADER ) && ( tmp1 == 0 ) )
1328 : {
1329 0 : tmp += DELTA_LEADER;
1330 0 : tmp1 = DELTA_LEADER;
1331 : }
1332 :
1333 1119836 : make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
1334 1119836 : make_offset_scale( table_no_cv, leaders_short[tmp1], MAX_NO_SCALES, offset_scale2 );
1335 : }
1336 :
1337 1353692 : return;
1338 : }
1339 :
1340 : /*-----------------------------------------------------------------*
1341 : * sort_desc_ind()
1342 : *
1343 : * sorts in descending order and computes indices in the sorted vector
1344 : *-----------------------------------------------------------------*/
1345 :
1346 4355 : void sort_desc_ind_32_fx(
1347 : Word32 *s, /* i/o: vector to be sorted Qx*/
1348 : const Word16 len, /* i : vector length */
1349 : Word16 *ind /* o : array of indices */
1350 : )
1351 : {
1352 : Word16 i, k, sorted, a;
1353 : Word32 t;
1354 :
1355 21520 : FOR( i = 0; i < len; i++ )
1356 : {
1357 17165 : ind[i] = i;
1358 17165 : move16();
1359 : }
1360 4355 : sorted = 0;
1361 4355 : move16();
1362 14684 : FOR( k = len - 1; k && !sorted; k-- )
1363 : {
1364 10329 : sorted = 1;
1365 10329 : move16();
1366 32826 : FOR( i = 0; i < k; i++ )
1367 : {
1368 22497 : IF( LT_32( s[i], s[i + 1] ) )
1369 : {
1370 10458 : sorted = 0;
1371 10458 : move16();
1372 10458 : t = s[i];
1373 10458 : move16();
1374 10458 : s[i] = s[i + 1];
1375 10458 : move16();
1376 10458 : s[i + 1] = t;
1377 10458 : move16();
1378 10458 : a = ind[i];
1379 10458 : move16();
1380 10458 : ind[i] = ind[i + 1];
1381 10458 : move16();
1382 10458 : ind[i + 1] = a;
1383 10458 : move16();
1384 : }
1385 : }
1386 : }
1387 :
1388 4355 : return;
1389 : }
1390 :
1391 3172 : void deindex_lvq_SHB_fx(
1392 : UWord32 index,
1393 : Word16 *out,
1394 : const Word16 nbits,
1395 : const Word16 mode )
1396 : {
1397 : UWord16 i;
1398 : const Word8 *p_no_lead;
1399 : const Word16 *p_scales;
1400 : Word16 scale;
1401 : Word16 idx_scale;
1402 : UWord32 offsets[MAX_NO_SCALES + 1];
1403 :
1404 3172 : IF( mode == 0 )
1405 : {
1406 3172 : p_no_lead = &no_lead_BWE[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
1407 3172 : p_scales = &scales_BWE_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[0] ), 3 )];
1408 : }
1409 : ELSE
1410 : {
1411 0 : p_no_lead = &no_lead_BWE_3b[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
1412 0 : p_scales = &scales_BWE_3b_fx[i_mult( sub( nbits, mslvq_SHB_min_bits[1] ), 3 )];
1413 : }
1414 :
1415 :
1416 3172 : IF( index == 0 )
1417 : {
1418 0 : set16_fx( out, 0, LATTICE_DIM );
1419 : }
1420 : ELSE
1421 : {
1422 : /* create offsets */
1423 3172 : offsets[0] = 0;
1424 3172 : move32();
1425 12688 : FOR( i = 0; i < MAX_NO_SCALES; i++ )
1426 : {
1427 9516 : offsets[i + 1] = UL_addNsD( table_no_cv[p_no_lead[i]], offsets[i] );
1428 9516 : move32();
1429 : }
1430 :
1431 : /* find idx_scale */
1432 3172 : idx_scale = 0;
1433 3172 : test();
1434 7331 : WHILE( LE_32( i, MAX_NO_SCALES ) && index >= offsets[idx_scale] )
1435 : {
1436 4159 : test();
1437 4159 : idx_scale = add( idx_scale, 1 );
1438 : }
1439 3172 : idx_scale = sub( idx_scale, 1 );
1440 3172 : index = L_sub( index, offsets[idx_scale] );
1441 :
1442 : /* find idx_leader */
1443 3172 : i = 1;
1444 3172 : move16();
1445 21605 : WHILE( GT_32( index, table_no_cv[i] ) )
1446 : {
1447 18433 : i = add( i, 1 );
1448 : }
1449 3172 : i = sub( i, 1 );
1450 :
1451 3172 : decode_comb_fx( (Word32) ( L_sub( L_sub( index, table_no_cv[i] ), 1 ) ), out, i );
1452 :
1453 3172 : scale = p_scales[idx_scale];
1454 3172 : move16();
1455 28548 : FOR( i = 0; i < LATTICE_DIM; i++ )
1456 : {
1457 25376 : Word32 temp = Mpy_32_16_1( sigma_BWE_fx[add( i_mult( mode, LATTICE_DIM ), i )], scale );
1458 25376 : temp = Mpy_32_16_1( temp, out[i] );
1459 25376 : out[i] = extract_l( temp ); /* Q15 output*/
1460 25376 : move16();
1461 : // out[i] *= scale * sigma_BWE_fx[mode * LATTICE_DIM + i];
1462 : }
1463 : }
1464 :
1465 3172 : return;
1466 : }
|