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 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #include <math.h>
40 : #include "prot.h"
41 : #include "rom_com.h"
42 : #include "cnst.h"
43 : #include "wmc_auto.h"
44 : #include "ivas_prot.h"
45 :
46 : /*-----------------------------------------------------------------*
47 : * Local function prototypes
48 : *-----------------------------------------------------------------*/
49 :
50 : static float quantize_data( float *data, const float *w_in, float *qin, float *cv_out, int16_t *idx_lead, int16_t *idx_scale, const float *sigma, const float *inv_sigma, const float *scales, Word8 *no_leaders );
51 : static float q_data( float *pTmp1, const float *w1, float *quant, float *cv_out, int16_t *idx_lead, int16_t *idx_scale, const float *p_inv_sigma, const float *p_sigma, const float *p_scales, Word8 *no_leaders );
52 : static void prepare_data( float *xsort, int16_t *sign, float *data, float *w, const float *w_in, const float *sigma, const float *inv_sigma, int16_t *p_sig );
53 : static float calculate_min_dist( float cv_pot[LATTICE_DIM], const float *scale, const float *w, int16_t *p_best_scale, int16_t *p_best_idx, Word8 *no_leaders, int16_t sig, int16_t *indx );
54 : static int16_t find_pos( float *c, const int16_t len, float arg, int16_t *p );
55 : static void take_out_val( float *v, float *v_out, const float val, const int16_t len );
56 : static UWord32 index_leaders( float *cv, int16_t idx_lead, const int16_t dim );
57 : static UWord32 c2idx( const int16_t n, int16_t *p, const int16_t k );
58 : static UWord32 encode_sign_pc1( const int16_t parity, float *cv );
59 : static UWord32 encode_comb( float *cv, const int16_t idx_lead );
60 :
61 :
62 : /*-----------------------------------------------------------------*
63 : * mslvq()
64 : *
65 : * Encodes the LSF residual
66 : *-----------------------------------------------------------------*/
67 :
68 696088 : float mslvq(
69 : float *pTmp, /* i : M-dimensional input vector */
70 : float *quant, /* o : quantized vector */
71 : float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */
72 : int16_t *idx_lead, /* o : leader index for each 8-dim subvector */
73 : int16_t *idx_scale, /* o : scale index for each subvector */
74 : const float *w, /* i : weights for LSF quantization */
75 : const int16_t mode, /* i : number indicating the coding type (V/UV/G...)*/
76 : const int16_t mode_glb, /* i : LVQ coding mode */
77 : const int16_t pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/
78 : )
79 : {
80 : float dist;
81 : const float *p_scales, *p_sigma, *p_inv_sigma;
82 : int16_t i, tmp, tmp1;
83 : Word8 p_no_lead[MAX_NO_SCALES * 2];
84 :
85 696088 : dist = 0.0f;
86 :
87 696088 : if ( pred_flag == 0 )
88 : {
89 182946 : p_sigma = sigma_MSLVQ[mode];
90 : /* inverse sigma is precomputed to save complexity */
91 182946 : p_inv_sigma = inv_sigma_MSLVQ[mode];
92 182946 : p_scales = scales[mode_glb];
93 :
94 182946 : tmp = no_lead_idx[mode_glb][0];
95 182946 : tmp1 = no_lead_idx[mode_glb][1];
96 182946 : if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
97 : {
98 0 : tmp += DELTA_LEADER;
99 : }
100 731784 : for ( i = 0; i < MAX_NO_SCALES; i++ )
101 : {
102 548838 : p_no_lead[i] = (int16_t) leaders_short[tmp][i];
103 548838 : p_no_lead[i + MAX_NO_SCALES] = (int16_t) leaders_short[tmp1][i];
104 : }
105 : }
106 : else
107 : {
108 513142 : if ( pred_flag >= 5 )
109 : {
110 : /* assert( pred_flag >= 12 && pred_flag <= 15 ); */
111 : /* pred_flag is here the number of bits for MSLVQ */
112 :
113 3338 : p_sigma = &sigma_BWE[mode_glb * LATTICE_DIM];
114 :
115 : /* inverse sigma is precomputed to save complexity */
116 3338 : p_inv_sigma = &inv_sigma_BWE[mode_glb * LATTICE_DIM];
117 :
118 3338 : if ( mode_glb == 0 )
119 : {
120 3338 : p_scales = &scales_BWE[( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
121 13352 : for ( i = 0; i < MAX_NO_SCALES; i++ )
122 : {
123 10014 : p_no_lead[i] = no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
124 : }
125 : }
126 : else
127 : {
128 0 : p_scales = &scales_BWE_3b[( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
129 0 : for ( i = 0; i < MAX_NO_SCALES; i++ )
130 : {
131 0 : p_no_lead[i] = no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3];
132 : }
133 : }
134 : }
135 : else
136 : {
137 509804 : p_sigma = sigma_p[mode];
138 :
139 : /* inverse sigma is precomputed to save complexity */
140 509804 : p_inv_sigma = inv_sigma_p[mode];
141 509804 : p_scales = scales_p[mode_glb];
142 :
143 509804 : tmp = no_lead_p_idx[mode_glb][0];
144 509804 : tmp1 = no_lead_p_idx[mode_glb][1];
145 :
146 509804 : if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
147 : {
148 11144 : tmp += DELTA_LEADER;
149 : }
150 :
151 509804 : if ( ( tmp == LIMIT_LEADER ) && ( tmp1 == 0 ) )
152 : {
153 0 : tmp += DELTA_LEADER;
154 0 : tmp1 += DELTA_LEADER;
155 : }
156 :
157 2039216 : for ( i = 0; i < MAX_NO_SCALES; i++ )
158 : {
159 1529412 : p_no_lead[i] = (int16_t) leaders_short[tmp][i];
160 1529412 : p_no_lead[i + MAX_NO_SCALES] = (int16_t) leaders_short[tmp1][i];
161 : }
162 : }
163 : }
164 :
165 : /* first subvector */
166 696088 : dist += quantize_data( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
167 :
168 696088 : if ( pred_flag < 5 )
169 : {
170 : /* second subvector */
171 692750 : dist += quantize_data( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES );
172 : }
173 :
174 696088 : return dist;
175 : }
176 :
177 :
178 : /*-----------------------------------------------------------------*
179 : * q_data()
180 : *
181 : * (used for LSF quantization in CNG)
182 : *-----------------------------------------------------------------*/
183 :
184 433 : static float q_data(
185 : float *pTmp1,
186 : const float *w1,
187 : float *quant,
188 : float *cv_out,
189 : int16_t *idx_lead,
190 : int16_t *idx_scale,
191 : const float *p_sigma,
192 : const float *p_inv_sigma,
193 : const float *p_scales,
194 : Word8 *p_no_lead )
195 : {
196 433 : float dist = 0.0f;
197 : /* first subvector */
198 433 : dist += quantize_data( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
199 : /* second subvector */
200 433 : dist += quantize_data( pTmp1 + LATTICE_DIM, w1 + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES );
201 :
202 433 : return dist;
203 : }
204 :
205 : /*-----------------------------------------------------------------*
206 : * mslvq_cng()
207 : *
208 : * Encodes the LSF residual in SID frames
209 : *-----------------------------------------------------------------*/
210 :
211 433 : float mslvq_cng(
212 : int16_t idx_cv, /* i : index of cv from previous stage */
213 : float *pTmp, /* i : 16 dimensional input vector */
214 : float *quant, /* o : quantized vector */
215 : float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */
216 : int16_t *idx_lead, /* o : leader index for each 8-dim subvector */
217 : int16_t *idx_scale, /* o : scale index for each subvector */
218 : const float *w /* i : weights for LSF quantization */
219 : )
220 : {
221 : float dist;
222 : const float *p_scales, *p_sigma, *p_inv_sigma;
223 : Word8 p_no_lead[MAX_NO_SCALES * 2];
224 : int16_t no_scales[2];
225 : int16_t mode_glb, mode, i;
226 : float pTmp1[M], w1[M];
227 :
228 433 : dist = 0.0f;
229 433 : mode = LVQ_COD_MODES + idx_cv;
230 :
231 : /* for CNG there is only one bitrate but several quantizer structures, depending on the previous VQ stage */
232 433 : mode_glb = START_CNG + idx_cv;
233 :
234 433 : p_sigma = sigma_MSLVQ[mode];
235 433 : p_inv_sigma = inv_sigma_MSLVQ[mode];
236 433 : p_scales = scales[mode_glb];
237 :
238 433 : no_scales[0] = 0;
239 433 : no_scales[1] = 0;
240 :
241 1732 : for ( i = 0; i < MAX_NO_SCALES; i++ )
242 : {
243 1299 : p_no_lead[i] = (int16_t) leaders_short[no_lead_idx[mode_glb][0]][i];
244 1299 : p_no_lead[i + MAX_NO_SCALES] = (int16_t) leaders_short[no_lead_idx[mode_glb][1]][i];
245 :
246 1299 : if ( p_scales[i] > 0.0f )
247 : {
248 1143 : no_scales[0] += 1;
249 : }
250 1299 : if ( p_scales[i + MAX_NO_SCALES] > 0.0f )
251 : {
252 1262 : no_scales[1] += 1;
253 : }
254 : }
255 :
256 : /* check if LSF component permutation is needed or not */
257 433 : if ( cng_sort[idx_cv] )
258 : {
259 : /* change order in subvecs */
260 7242 : for ( i = 0; i < M; i++ )
261 : {
262 6816 : pTmp1[i] = pTmp[i];
263 6816 : w1[i] = w[i];
264 : }
265 : /* sorting the quantizer input and the corresponding weights according to the specified permutations */
266 426 : permute( pTmp1, perm_MSLVQ[idx_cv] );
267 426 : permute( w1, perm_MSLVQ[idx_cv] );
268 :
269 426 : dist = q_data( pTmp1, w1, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
270 : /* permute back */
271 426 : permute( quant, perm_MSLVQ[idx_cv] );
272 : }
273 : else
274 : {
275 7 : dist = q_data( pTmp, w, quant, cv_out, idx_lead, idx_scale, p_sigma, p_inv_sigma, p_scales, p_no_lead );
276 : }
277 :
278 433 : return dist;
279 : }
280 : /*-----------------------------------------------------------------*
281 : * prepare_data()
282 : *
283 : *-----------------------------------------------------------------*/
284 :
285 1373450 : static void prepare_data(
286 : float *xsort,
287 : int16_t *sign,
288 : float *data,
289 : float *w,
290 : const float *w_in,
291 : const float *sigma,
292 : const float *inv_sigma,
293 : int16_t *p_sig )
294 : {
295 : int16_t j, sig;
296 : float s, inv_s;
297 :
298 : /* scale data */
299 12361050 : for ( j = 0; j < LATTICE_DIM; j++ )
300 : {
301 10987600 : s = sigma[j];
302 10987600 : inv_s = inv_sigma[j];
303 10987600 : xsort[j] = data[j] * inv_s;
304 10987600 : w[j] = w_in[j] * ( s * s );
305 : }
306 :
307 1373450 : sig = 1;
308 12361050 : for ( j = 0; j < LATTICE_DIM; j++ )
309 : {
310 10987600 : if ( xsort[j] < 0 )
311 : {
312 5226713 : sign[j] = -1;
313 5226713 : sig = -sig;
314 5226713 : xsort[j] = -xsort[j];
315 : }
316 : else
317 : {
318 5760887 : sign[j] = 1;
319 : }
320 : }
321 1373450 : *p_sig = sig;
322 :
323 1373450 : return;
324 : }
325 :
326 : /*-----------------------------------------------------------------*
327 : * calculate_min_dist()
328 : *
329 : *-----------------------------------------------------------------*/
330 :
331 1373450 : static float calculate_min_dist(
332 : float cv_pot[LATTICE_DIM],
333 : const float *scale,
334 : const float *w,
335 : int16_t *p_best_scale,
336 : int16_t *p_best_idx,
337 : Word8 *no_leaders,
338 : int16_t sig,
339 : int16_t *indx )
340 : {
341 1373450 : int16_t k, l, j, best_scale = -1, best_idx = -1;
342 : float s, s2, tmp_dist, min_dist, wx[LATTICE_DIM], wind[LATTICE_DIM];
343 : float sum1[NO_LEADERS], sum2[NO_LEADERS];
344 : const float *pl_crt;
345 : float p;
346 :
347 : /* compare first with the origin */
348 1373450 : min_dist = 0.0f;
349 12361050 : for ( j = 0; j < LATTICE_DIM; j++ )
350 : {
351 : /* sorting the weight based on the ordering indx[] of the input vector */
352 10987600 : wind[j] = w[indx[j]];
353 10987600 : wx[j] = 2.0f * wind[j] * cv_pot[j];
354 : }
355 1373450 : s = scale[0];
356 1373450 : s2 = s * s;
357 1373450 : pl_crt = &pl_HQ[0];
358 :
359 19193823 : for ( j = 0; j < no_leaders[0]; j++ )
360 : {
361 17820373 : sum1[j] = 0;
362 17820373 : sum2[j] = 0;
363 17820373 : l = 0;
364 116565249 : while ( l < LATTICE_DIM - 1 )
365 : {
366 98744876 : p = *pl_crt;
367 98744876 : if ( p )
368 : {
369 88907247 : sum1[j] += wx[l] * p;
370 88907247 : sum2[j] += wind[l] * p * p;
371 88907247 : pl_crt++;
372 88907247 : l++;
373 : }
374 : else
375 : {
376 9837629 : pl_crt += LATTICE_DIM - l;
377 9837629 : l = LATTICE_DIM;
378 : }
379 : }
380 17820373 : if ( ( l - LATTICE_DIM + 1 ) == 0 )
381 : {
382 7982744 : p = *pl_crt;
383 : /* if it went up to 7th position */
384 7982744 : if ( pl_par[j] )
385 : {
386 6389612 : if ( sig != pl_par[j] )
387 : {
388 3174011 : sum1[j] -= wx[l] * p;
389 3174011 : sum2[j] += wind[l] * p * p;
390 3174011 : pl_crt++;
391 : }
392 : else
393 : {
394 3215601 : sum1[j] += wx[l] * p;
395 3215601 : sum2[j] += wind[l] * p * p;
396 3215601 : pl_crt++;
397 : }
398 : }
399 : else
400 : {
401 1593132 : sum1[j] += wx[l] * p;
402 1593132 : sum2[j] += wind[l] * p * p;
403 1593132 : pl_crt++;
404 : }
405 : }
406 : /* distance between the potential codevector and the input calculated in ordered space */
407 17820373 : tmp_dist = s2 * sum2[j] - s * sum1[j];
408 17820373 : if ( tmp_dist < min_dist )
409 : {
410 6288213 : min_dist = tmp_dist;
411 6288213 : best_scale = 0;
412 6288213 : best_idx = j;
413 : }
414 : }
415 :
416 1373450 : tmp_dist = min_dist + 1.0f;
417 :
418 4120350 : for ( k = 1; k < MAX_NO_SCALES; k++ )
419 : {
420 2746900 : s = scale[k];
421 :
422 2746900 : if ( s > 0.0f )
423 : {
424 2384643 : s2 = s * s;
425 24999894 : for ( j = 0; j < no_leaders[k]; j++ )
426 : {
427 : /* distance between the potential codevector and the input calculated in ordered space */
428 22615251 : tmp_dist = s2 * sum2[j] - s * sum1[j];
429 22615251 : if ( tmp_dist < min_dist )
430 : {
431 1138763 : min_dist = tmp_dist;
432 1138763 : best_scale = k;
433 1138763 : best_idx = j;
434 : }
435 : }
436 : }
437 : }
438 1373450 : *p_best_scale = best_scale;
439 1373450 : *p_best_idx = best_idx;
440 :
441 1373450 : return min_dist;
442 : }
443 :
444 :
445 : /*-----------------------------------------------------------------*
446 : * quantize_data()
447 : *
448 : *-----------------------------------------------------------------*/
449 :
450 1389704 : static float quantize_data(
451 : float *data, /* i : residual LSF data to quantize */
452 : const float *w_in, /* i : weights */
453 : float *qin, /* o : quantized output (scaled) */
454 : float *cv_out, /* o : codevectors */
455 : int16_t *idx_lead, /* o : leader indexes for each subvector */
456 : int16_t *idx_scale, /* o : scale indexes for each subvector */
457 : const float *sigma, /* i : standard deviation */
458 : const float *inv_sigma, /* i : inverse of standard deviation */
459 : const float *scale, /* i : scales for each truncation */
460 : Word8 *no_leaders /* i : number of leader vectors for each truncation of each subvector */
461 : )
462 : {
463 : int16_t j;
464 1389704 : float w[LATTICE_DIM], min_dist = 0;
465 1389704 : int16_t best_idx = 0, best_scale = -1;
466 : float s;
467 : float cv_pot[LATTICE_DIM];
468 : int16_t indx[LATTICE_DIM];
469 : int16_t sig, sign[LATTICE_DIM];
470 : int16_t smallest;
471 : int16_t id[LATTICE_DIM];
472 :
473 1389704 : if ( scale[0] > 0.0f )
474 : {
475 1373450 : prepare_data( cv_pot, sign, data, w, w_in, sigma, inv_sigma, &sig );
476 : /* sorting of the input vector based on its absolute values; indx: permutation corresponding to the sorting */
477 1373450 : sort_desc_ind( cv_pot, LATTICE_DIM, indx );
478 1373450 : smallest = indx[LATTICE_DIM - 1];
479 1373450 : min_dist = calculate_min_dist( cv_pot, scale, w, &best_scale, &best_idx, no_leaders, sig, indx );
480 1373450 : if ( best_scale > -1 )
481 : {
482 12276504 : for ( j = 0; j < LATTICE_DIM; j++ )
483 : {
484 10912448 : id[indx[j]] = j;
485 : }
486 12276504 : for ( j = 0; j < LATTICE_DIM; j++ )
487 : {
488 10912448 : cv_out[j] = sign[j] * pl_HQ[best_idx * LATTICE_DIM + id[j]];
489 : }
490 1364056 : if ( pl_par[best_idx] )
491 : {
492 576530 : if ( sig - pl_par[best_idx] != 0 )
493 : {
494 150096 : cv_out[smallest] = -cv_out[smallest];
495 : }
496 : }
497 1364056 : s = scale[best_scale];
498 12276504 : for ( j = 0; j < LATTICE_DIM; j++ )
499 : {
500 10912448 : qin[j] = cv_out[j] * s * sigma[j];
501 : }
502 1364056 : *idx_lead = best_idx;
503 1364056 : *idx_scale = best_scale;
504 : }
505 : else
506 : {
507 84546 : for ( j = 0; j < LATTICE_DIM; j++ )
508 : {
509 75152 : qin[j] = 0;
510 : }
511 :
512 9394 : *idx_lead = best_idx;
513 9394 : *idx_scale = best_scale;
514 : }
515 : }
516 : else
517 : {
518 16254 : *idx_lead = 0;
519 16254 : *idx_scale = -1;
520 146286 : for ( j = 0; j < LATTICE_DIM; j++ )
521 : {
522 130032 : cv_out[j] = 0;
523 130032 : qin[j] = 0;
524 : }
525 : }
526 :
527 1389704 : return min_dist;
528 : }
529 :
530 : /*-----------------------------------------------------------------*
531 : * index_lvq()
532 : *
533 : * sorts in descending order and computes indices in the sorted vector
534 : *-----------------------------------------------------------------*/
535 :
536 346808 : void index_lvq(
537 : float *quant, /* i : codevector to be indexed (2 8-dim subvectors) */
538 : int16_t *idx_lead, /* i : leader class index for each subvector */
539 : int16_t *idx_scale, /* i : scale index for each subvector */
540 : const int16_t mode, /* i : integer signaling the quantizer structure for the current bitrate */
541 : int16_t *index, /* o : encoded index (represented on 3 short each with 15 bits ) */
542 : const int16_t prediction_flag )
543 : {
544 : UWord32 index1, index2, tmp, idx[2];
545 : UWord32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
546 :
547 :
548 346808 : index1 = 0;
549 346808 : create_offset( offset_scale1, offset_scale2, mode, prediction_flag );
550 :
551 : /* for first subvector */
552 346808 : if ( idx_scale[0] > -1 )
553 : {
554 : /* create offset */
555 346655 : index1 = encode_comb( quant, idx_lead[0] ) + table_no_cv[idx_lead[0]] + offset_scale1[idx_scale[0]];
556 : }
557 :
558 : /* for second subvector */
559 346808 : index2 = 0;
560 346808 : if ( idx_scale[1] > -1 )
561 : {
562 333277 : index2 = encode_comb( &quant[LATTICE_DIM], idx_lead[1] ) + table_no_cv[idx_lead[1]] + offset_scale2[idx_scale[1]];
563 : }
564 :
565 346808 : multiply32_32_64( index1, offset_scale2[MAX_NO_SCALES], idx );
566 :
567 346808 : tmp = idx[0] + index2;
568 346808 : if ( tmp < idx[0] || tmp < index2 )
569 : {
570 1 : idx[1] += 1;
571 : }
572 :
573 346808 : idx[0] = tmp;
574 :
575 : /* convert to 3 short */
576 346808 : index[0] = (int16_t) ( ( idx[0] ) & ( 0xffff >> 1 ) );
577 346808 : index[1] = (int16_t) ( ( idx[0] ) >> 15 ) & ( 0xffff >> 1 );
578 346808 : index[2] = (int16_t) ( ( idx[0] ) >> 30 ) + ( ( ( idx[1] ) << 2 ) & ( 0xffff >> 1 ) );
579 :
580 346808 : return;
581 : }
582 :
583 :
584 : /*-----------------------------------------------------------------*
585 : * encode_comb()
586 : *
587 : * creates an index for the lattice codevector
588 : *-----------------------------------------------------------------*/
589 :
590 : /*! r: index of the absolute valued codevector */
591 683270 : static UWord32 encode_comb(
592 : float *cv, /* i : codevector to be indexed */
593 : const int16_t idx_lead /* i : leader class index, to know the values */
594 : )
595 : {
596 : UWord32 idx_sign;
597 : UWord32 idx_ld_class;
598 :
599 683270 : idx_sign = encode_sign_pc1( pl_par[idx_lead], cv );
600 683270 : idx_ld_class = index_leaders( cv, idx_lead, LATTICE_DIM );
601 :
602 683270 : return idx_sign * (UWord32) pi0[idx_lead] + idx_ld_class;
603 : }
604 :
605 :
606 : /*-----------------------------------------------------------------*
607 : * index_leaders()
608 : *
609 : * gives the index in a class of leaders without considering the sign yet
610 : *-----------------------------------------------------------------*/
611 :
612 : /*! r: index */
613 683270 : static UWord32 index_leaders(
614 : float *cv, /* i : codevector to be indexed */
615 : int16_t idx_lead, /* i : leader class index */
616 : const int16_t dim /* i : vector dimension */
617 : )
618 : {
619 : UWord32 index;
620 : int16_t p[LATTICE_DIM];
621 : int16_t i, no_vals_loc, nr, dim_loc;
622 : float cv_copy[LATTICE_DIM], val_crt;
623 :
624 683270 : no_vals_loc = no_vals[idx_lead];
625 :
626 683270 : if ( no_vals_loc == 1 )
627 : {
628 71474 : return 0;
629 : }
630 :
631 5506164 : for ( i = 0; i < LATTICE_DIM; i++ )
632 : {
633 4894368 : cv_copy[i] = (float) fabs( cv[i] );
634 : }
635 :
636 611796 : val_crt = vals[idx_lead][0];
637 611796 : nr = find_pos( cv_copy, dim, val_crt, p );
638 611796 : index = c2idx( LATTICE_DIM, p, nr );
639 :
640 611796 : if ( no_vals_loc == 2 )
641 : {
642 423889 : return index;
643 : }
644 :
645 187907 : take_out_val( cv_copy, cv_copy, val_crt, dim );
646 187907 : dim_loc = dim - no_vals_ind[idx_lead][0];
647 187907 : index *= C_VQ[dim_loc][no_vals_ind[idx_lead][1]];
648 187907 : val_crt = vals[idx_lead][1];
649 187907 : nr = find_pos( cv_copy, dim_loc, val_crt, p );
650 187907 : index += c2idx( dim_loc, p, nr );
651 :
652 187907 : if ( no_vals_loc == 3 )
653 : {
654 186539 : return index;
655 : }
656 :
657 1368 : take_out_val( cv_copy, cv_copy, val_crt, dim_loc );
658 1368 : dim_loc = dim_loc - no_vals_ind[idx_lead][1];
659 1368 : index *= C_VQ[dim_loc][no_vals_ind[idx_lead][2]];
660 1368 : val_crt = vals[idx_lead][2];
661 1368 : nr = find_pos( cv_copy, dim_loc, val_crt, p );
662 1368 : index += c2idx( dim_loc, p, nr );
663 : /* maximum 4 values */
664 :
665 1368 : return index;
666 : }
667 :
668 : /*-----------------------------------------------------------------*
669 : * find_pos()
670 : *
671 : * Finds the positions in vector c for which the vector components are equal to 'arg'.
672 : * It returns the number of such positions and their values in the array 'p'.
673 : *-----------------------------------------------------------------*/
674 :
675 : /*! r: number of positions */
676 801071 : int16_t find_pos(
677 : float *c, /* i : input vector */
678 : const int16_t len, /* i : input vector dim */
679 : float arg, /* i : argument to be compared with */
680 : int16_t *p /* o : vector of positions */
681 : )
682 : {
683 801071 : int16_t i = 0, j = 0;
684 :
685 : /* how many (j) and which (p) positions are in the relation pred(arg,c[i]) */
686 6971927 : for ( i = 0; i < len; i++ )
687 : {
688 6170856 : if ( (int16_t) ( arg * 10 ) == (int16_t) ( c[i] * 10 ) )
689 : {
690 2142838 : p[j++] = i;
691 : }
692 : }
693 :
694 801071 : return j;
695 : }
696 :
697 : /*-----------------------------------------------------------------*
698 : * encode_sign_pc1()
699 : *
700 : * Creates an index for signs of the significant codevector components
701 : * Gives the index of the signs - binary representation where negative sign stands for 1
702 : * and positive sign stands for 1.
703 : *-----------------------------------------------------------------*/
704 :
705 : /*! r: index of signs */
706 683270 : static UWord32 encode_sign_pc1(
707 : const int16_t parity, /* i : parity of the leader class to which the codevector belongs */
708 : float *cv /* i : input codevector */
709 : )
710 : {
711 : UWord32 idx_sign;
712 683270 : int16_t cnt, i, len = LATTICE_DIM;
713 :
714 683270 : idx_sign = 0;
715 683270 : cnt = 0;
716 :
717 683270 : if ( parity )
718 : {
719 287828 : len -= 1;
720 : }
721 :
722 5861602 : for ( i = 0; i < len; i++ )
723 : {
724 5178332 : if ( cv[i] < 0 )
725 : {
726 1807244 : idx_sign += ( 1 << cnt );
727 1807244 : cnt++;
728 : }
729 :
730 5178332 : if ( cv[i] > 0 )
731 : {
732 1931696 : cnt++;
733 : }
734 : }
735 :
736 683270 : return idx_sign;
737 : }
738 :
739 : /*-----------------------------------------------------------------*
740 : * take_out_val()
741 : *
742 : * removes the value val from the vector v
743 : *-----------------------------------------------------------------*/
744 :
745 189275 : static void take_out_val(
746 : float *v, /* i : input vector */
747 : float *v_out, /* o : output vector without the value val*/
748 : const float val, /* i : value to be removed */
749 : const int16_t len /* i : input vector length */
750 : )
751 : {
752 : int16_t i, cnt;
753 :
754 189275 : cnt = 0;
755 :
756 1702107 : for ( i = 0; i < len; i++ )
757 : {
758 1512832 : if ( (int16_t) ( v[i] * 10 ) != (int16_t) ( val * 10 ) )
759 : {
760 1276488 : v_out[cnt++] = v[i];
761 : }
762 : }
763 :
764 189275 : return;
765 : }
766 :
767 :
768 : /*-----------------------------------------------------------------*
769 : * c2idx()
770 : *
771 : *-----------------------------------------------------------------*/
772 :
773 2142838 : static UWord32 c2idx(
774 : const int16_t n,
775 : int16_t *p,
776 : const int16_t k )
777 : {
778 : int16_t i, p0;
779 : UWord32 skip;
780 :
781 2142838 : if ( k == 1 )
782 : {
783 801071 : return (UWord32) ( p[0] );
784 : }
785 : else
786 : {
787 1341767 : skip = 0;
788 2412734 : for ( i = 1; i <= p[0]; i++ )
789 : {
790 1070967 : skip += C_VQ[n - i][k - 1];
791 : }
792 :
793 1341767 : p0 = p[0];
794 4072735 : for ( i = 1; i < k; i++ )
795 : {
796 2730968 : p[i] -= p0 + 1;
797 : }
798 :
799 1341767 : return skip + c2idx( n - p0 - 1, p + 1, k - 1 );
800 : }
801 : }
802 :
803 : /*-----------------------------------------------------------------*
804 : * index_lvq_SHB()
805 : *
806 : *-----------------------------------------------------------------*/
807 :
808 3338 : UWord32 index_lvq_SHB(
809 : const int16_t idx_lead,
810 : const int16_t idx_scale,
811 : const int16_t nbits,
812 : float *lat_cv,
813 : const int16_t mode )
814 : {
815 : uint16_t i;
816 : const Word8 *p_no_lead;
817 : UWord32 index;
818 :
819 3338 : if ( mode == 0 )
820 : {
821 3338 : p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3];
822 : }
823 : else
824 : {
825 0 : p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3];
826 : }
827 :
828 3338 : index = 0;
829 3338 : if ( idx_lead > -1 )
830 : {
831 3338 : index = 1;
832 4389 : for ( i = 0; i < idx_scale; i++ )
833 : {
834 1051 : index += table_no_cv[p_no_lead[i]];
835 : }
836 :
837 3338 : if ( idx_lead > 0 )
838 : {
839 3249 : index += table_no_cv[idx_lead];
840 : }
841 :
842 3338 : index += encode_comb( lat_cv, idx_lead );
843 : }
844 :
845 3338 : return index;
846 : }
|