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" /* Compilation switches */
35 : #include "cnst.h" /* Common constants */
36 : #include "rom_com.h" /* Static table prototypes */
37 : #include "prot_fx.h" /* Function prototypes */
38 : #include "prot_fx_enc.h" /* Function prototypes */
39 :
40 :
41 : /*-----------------------------------------------------------------*
42 : * Local constants
43 : *-----------------------------------------------------------------*/
44 :
45 : #define DICO1_NS_19b 16 /* codebook dimensions for SID ISF quantizers */
46 : #define DICO2_NS_19b 16
47 : #define DICO3_NS_19b 16
48 : #define DICO4_NS_19b 8
49 : #define DICO5_NS_19b 16
50 :
51 : #define DICO1_NS_28b 64
52 : #define DICO2_NS_28b 64
53 : #define DICO3_NS_28b 64
54 : #define DICO4_NS_28b 32
55 : #define DICO5_NS_28b 32
56 :
57 : #define N_SURV_MAX 4 /* maximum number of survivors */
58 :
59 : /*---------------------------------------------------------------------*
60 : * Local function prototypes
61 : *---------------------------------------------------------------------*/
62 :
63 : static void qisf_ns_28b_fx( BSTR_ENC_HANDLE hBstr, Word16 *isf );
64 : static void qisf_2s_46b_fx( BSTR_ENC_HANDLE hBstr, Word16 *isf, Word16 nb_surv, Word16 *mem_AR, Word16 *mem_MA );
65 : static void qisf_2s_36b_fx( BSTR_ENC_HANDLE hBstr, Word16 *isf, Word16 nb_surv, Word16 *mem_AR, Word16 *mem_MA );
66 : static void VQ_stage1_fx( const Word16 *x, const Word16 *dico, const Word16 dim, const Word16 dico_size, Word16 *index, const Word16 surv );
67 : static Word16 sub_VQ_fx( Word16 *x, const Word16 *dico, const Word16 dim, const Word16 dico_size, Word32 *distance );
68 :
69 : /*-------------------------------------------------------------------*
70 : * isf_enc_amr_wb()
71 : *
72 : * Quantization of ISF parameters in AMR-WB IO mode
73 : *-------------------------------------------------------------------*/
74 :
75 0 : void isf_enc_amr_wb_fx(
76 : Encoder_State *st, /* i/o: state structure */
77 : Word16 *isf_new, /* i/o: quantized ISF vector */
78 : Word16 *isp_new, /* i/o: ISP vector to quantize/quantized */
79 : Word16 *Aq /* o : quantized A(z) for 4 subframes */
80 : )
81 : {
82 0 : BSTR_ENC_HANDLE hBstr = st->hBstr;
83 :
84 : /*---------------------------------*
85 : * ISF quantization of SID frames
86 : *---------------------------------*/
87 :
88 0 : IF( EQ_32( st->core_brate, SID_1k75 ) )
89 : {
90 0 : qisf_ns_28b_fx( hBstr, isf_new );
91 :
92 0 : reorder_isf_fx( isf_new, ISF_GAP_FX, M, Fs_2 );
93 :
94 0 : E_LPC_isf_isp_conversion( isf_new, isp_new, M );
95 :
96 : /* return if SID frame (conversion to A(z) done in the calling function) */
97 0 : return;
98 : }
99 :
100 : /* check resonance for pitch clipping algorithm */
101 0 : gp_clip_test_isf_fx( st->element_mode, st->core_brate, isf_new, st->clip_var_fx, 1 );
102 :
103 : /*---------------------------------------*
104 : * ISF quantization of all other frames
105 : *---------------------------------------*/
106 :
107 0 : IF( EQ_32( st->core_brate, ACELP_6k60 ) )
108 : {
109 0 : qisf_2s_36b_fx( hBstr, isf_new, 4, st->mem_AR_fx, st->mem_MA_fx );
110 : }
111 0 : ELSE IF( GE_32( st->core_brate, ACELP_8k85 ) )
112 : {
113 0 : qisf_2s_46b_fx( hBstr, isf_new, 4, st->mem_AR_fx, st->mem_MA_fx );
114 : }
115 :
116 0 : reorder_isf_fx( isf_new, ISF_GAP_FX, M, Fs_2 );
117 : /* convert quantized ISFs back to ISPs */
118 0 : E_LPC_isf_isp_conversion( isf_new, isp_new, M );
119 :
120 : /*-------------------------------------------------------------------------------------*
121 : * ISP interpolation
122 : * A(z) calculation
123 : *-------------------------------------------------------------------------------------*/
124 :
125 0 : IF( st->rate_switching_reset )
126 : {
127 0 : Copy( isf_new, st->lsf_old_fx, M );
128 0 : Copy( isp_new, st->lsp_old_fx, M );
129 : }
130 :
131 0 : int_lsp_fx( L_FRAME, st->lsp_old_fx, isp_new, Aq, M, interpol_isp_amr_wb_fx, 1 );
132 :
133 : /*------------------------------------------------------------------*
134 : * Calculate ISF stability (distance between old ISF and current ISF)
135 : *------------------------------------------------------------------*/
136 0 : IF( NE_32( st->last_core_brate, SID_1k75 ) )
137 : {
138 0 : st->stab_fac_fx = lsf_stab_fx( isf_new, st->lsf_old_fx, 1, L_FRAME );
139 : }
140 :
141 0 : return;
142 : }
143 :
144 : /*-------------------------------------------------------------------*
145 : * qisf_ns_28b()
146 : *
147 : * ISF quantizer for SID frames (only in AMR-WB IO mode)
148 : *-------------------------------------------------------------------*/
149 :
150 0 : static void qisf_ns_28b_fx(
151 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */
152 : Word16 *isf /* i/o: unquantized/quantized ISF vector */
153 : )
154 : {
155 : Word16 i, indice[5];
156 : Word32 tmp;
157 :
158 0 : FOR( i = 0; i < M; i++ )
159 : {
160 : /*isf[i] -= mean_isf_noise_amr_wb[i];*/
161 0 : isf[i] = sub( isf[i], mean_isf_noise_amr_wb_fx[i] );
162 0 : move16();
163 : }
164 :
165 0 : indice[0] = sub_VQ_fx( &isf[0], dico1_ns_28b_fx, 2, DICO1_NS_28b, &tmp );
166 0 : move16();
167 0 : indice[1] = sub_VQ_fx( &isf[2], dico2_ns_28b_fx, 3, DICO2_NS_28b, &tmp );
168 0 : move16();
169 0 : indice[2] = sub_VQ_fx( &isf[5], dico3_ns_28b_fx, 3, DICO3_NS_28b, &tmp );
170 0 : move16();
171 0 : indice[3] = sub_VQ_fx( &isf[8], dico4_ns_28b_fx, 4, DICO4_NS_28b, &tmp );
172 0 : move16();
173 0 : indice[4] = add( sub_VQ_fx( &isf[12], dico5_ns_28b_fx + 4, 4, DICO5_NS_28b - 1, &tmp ), 1 ); /* First vector has a problem -> do not allow */
174 0 : move16();
175 : /* write indices to array */
176 0 : push_indice( hBstr, IND_ISF_0_0, indice[0], 6 );
177 0 : push_indice( hBstr, IND_ISF_0_1, indice[1], 6 );
178 0 : push_indice( hBstr, IND_ISF_0_2, indice[2], 6 );
179 0 : push_indice( hBstr, IND_ISF_0_3, indice[3], 5 );
180 0 : push_indice( hBstr, IND_ISF_0_4, indice[4], 5 );
181 :
182 : /* decoding the ISFs */
183 0 : disf_ns_28b_fx( indice, isf );
184 :
185 0 : return;
186 : }
187 :
188 :
189 : /*---------------------------------------------------------------------*
190 : * qisf_2s_36b()
191 : *
192 : * ISF quantizer for AMR-WB 6k60 frames
193 : *
194 : * The ISF vector is quantized using two-stage MA-prediction VQ with split-by-2
195 : * in 1st stage and split-by-3 in the second stage.
196 : *---------------------------------------------------------------------*/
197 :
198 0 : static void qisf_2s_36b_fx(
199 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */
200 : Word16 *isf, /* i/o: unquantized/quantized ISF vector */
201 : Word16 nb_surv, /* i : number of survivors (1, 2, 3 or 4) */
202 : Word16 *mem_AR, /* o : quantizer memory for AR model */
203 : Word16 *mem_MA /* i/o: quantizer memory for MA model */
204 : )
205 : {
206 : Word16 i, k, indice[5], tmp_ind[2];
207 : Word16 surv1[N_SURV_MAX], tmp16; /* indices of survivors from 1st stage */
208 : Word32 temp, min_err, distance;
209 : Word16 isf2[M];
210 :
211 : /*------------------------------------------------------------------------*
212 : * Subtract mean
213 : *------------------------------------------------------------------------*/
214 :
215 0 : FOR( i = 0; i < M; i++ )
216 : {
217 : /*isf[i] -= mean_isf_amr_wb[i] + MU_MA * mem_MA[i];*/
218 0 : tmp16 = sub( isf[i], mean_isf_amr_wb_fx[i] );
219 0 : isf[i] = sub( tmp16, mult( MU_MA_FX, mem_MA[i] ) );
220 0 : move16();
221 : }
222 :
223 : /*------------------------------------------------------------------------*
224 : * Quantize ISFs 0 - 8
225 : *------------------------------------------------------------------------*/
226 :
227 0 : VQ_stage1_fx( &isf[0], dico1_isf_fx, 9, SIZE_BK1, surv1, nb_surv );
228 :
229 0 : distance = MAX_32;
230 0 : move32();
231 0 : nb_surv = s_min( nb_surv, N_SURV_MAX );
232 :
233 0 : FOR( k = 0; k < nb_surv; k++ )
234 : {
235 0 : tmp16 = i_mult2( surv1[k], 9 );
236 0 : FOR( i = 0; i < 9; i++ )
237 : {
238 : /*isf2[i] = isf[i] - dico1_isf[i+surv1[k]*9];*/
239 0 : isf2[i] = sub( isf[i], dico1_isf_fx[i + tmp16] );
240 0 : move16();
241 : }
242 :
243 0 : tmp_ind[0] = sub_VQ_fx( &isf2[0], dico21_isf_36b_fx, 5, SIZE_BK21_36b, &min_err );
244 0 : move16();
245 0 : temp = L_add( min_err, 0 );
246 :
247 0 : tmp_ind[1] = sub_VQ_fx( &isf2[5], dico22_isf_36b_fx, 4, SIZE_BK22_36b, &min_err );
248 0 : move16();
249 0 : temp = L_add( temp, min_err );
250 :
251 0 : IF( LT_32( temp, distance ) )
252 : {
253 0 : distance = L_add( temp, 0 );
254 0 : indice[0] = surv1[k];
255 0 : move16();
256 0 : FOR( i = 0; i < 2; i++ )
257 : {
258 0 : indice[i + 2] = tmp_ind[i];
259 0 : move16();
260 : }
261 : }
262 : }
263 :
264 : /*------------------------------------------------------------------------*
265 : * Quantize ISFs 9 - 15
266 : *------------------------------------------------------------------------*/
267 :
268 0 : VQ_stage1_fx( &isf[9], dico2_isf_fx, 7, SIZE_BK2, surv1, nb_surv );
269 :
270 0 : distance = MAX_32;
271 0 : move32();
272 0 : FOR( k = 0; k < nb_surv; k++ )
273 : {
274 0 : tmp16 = i_mult2( surv1[k], 7 );
275 0 : FOR( i = 0; i < 7; i++ )
276 : {
277 : /*isf2[9+i] = isf[9+i] - dico2_isf[i+surv1[k]*7];*/
278 0 : isf2[i + 9] = sub( isf[9 + i], dico2_isf_fx[i + tmp16] );
279 0 : move16();
280 : }
281 :
282 0 : tmp_ind[0] = sub_VQ_fx( &isf2[9], dico23_isf_36b_fx, 3, SIZE_BK23_36b, &min_err );
283 0 : move16();
284 0 : temp = L_add( min_err, 0 );
285 0 : IF( LT_32( temp, distance ) )
286 : {
287 0 : distance = L_add( temp, 0 );
288 0 : indice[1] = surv1[k];
289 0 : move16();
290 0 : indice[4] = tmp_ind[0];
291 0 : move16();
292 : }
293 : }
294 :
295 : /*------------------------------------------------------------------------*
296 : * decoding the ISFs
297 : *------------------------------------------------------------------------*/
298 :
299 0 : disf_2s_36b_fx( indice, isf, mem_AR, mem_MA, 0 );
300 :
301 : /*------------------------------------------------------------------------*
302 : * write indices to array
303 : *------------------------------------------------------------------------*/
304 :
305 0 : indice[0] = Indirect_dico1[indice[0]];
306 0 : move16(); /* Make interoperable with G722.2 */
307 :
308 0 : push_indice( hBstr, IND_ISF_0_0, indice[0], 8 );
309 0 : push_indice( hBstr, IND_ISF_0_1, indice[1], 8 );
310 0 : push_indice( hBstr, IND_ISF_1_0, indice[2], 7 );
311 0 : push_indice( hBstr, IND_ISF_1_1, indice[3], 7 );
312 0 : push_indice( hBstr, IND_ISF_1_2, indice[4], 6 );
313 :
314 0 : return;
315 : }
316 :
317 :
318 : /*-------------------------------------------------------------------*
319 : * qisf_2s_46b()
320 : *
321 : * ISF quantizer for all other AMR-WB frames
322 : *
323 : * The ISF vector is quantized using two-stage VQ with split-by-2
324 : * in 1st stage and split-by-5 in the second stage.
325 : *-------------------------------------------------------------------*/
326 :
327 0 : static void qisf_2s_46b_fx(
328 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */
329 : Word16 *isf, /* i/o: unquantized/quantized ISF vector */
330 : Word16 nb_surv, /* i : number of survivors (1, 2, 3 or 4) */
331 : Word16 *mem_AR, /* o : quantizer memory for AR model */
332 : Word16 *mem_MA /* i/o: quantizer memory for MA model */
333 : )
334 : {
335 : Word16 i, k, indice[7], tmp_ind[5];
336 : Word16 surv1[N_SURV_MAX]; /* indices of survivors from 1st stage */
337 : Word32 temp, min_err, distance;
338 : Word16 tmp16, isf2[M];
339 :
340 :
341 : /*------------------------------------------------------------------------*
342 : * Subtract mean
343 : *------------------------------------------------------------------------*/
344 :
345 0 : FOR( i = 0; i < M; i++ )
346 : {
347 : /*isf[i] -= mean_isf_amr_wb[i] + MU_MA * mem_MA[i];*/
348 0 : tmp16 = sub( isf[i], mean_isf_amr_wb_fx[i] );
349 0 : isf[i] = sub( tmp16, mult( MU_MA_FX, mem_MA[i] ) );
350 0 : move16();
351 : }
352 :
353 : /*------------------------------------------------------------------------*
354 : * Quantize ISFs 0 - 8
355 : *------------------------------------------------------------------------*/
356 :
357 0 : VQ_stage1_fx( &isf[0], dico1_isf_fx, 9, SIZE_BK1, surv1, nb_surv );
358 :
359 0 : distance = MAX_32;
360 0 : move32();
361 0 : nb_surv = s_min( nb_surv, N_SURV_MAX );
362 :
363 0 : FOR( k = 0; k < nb_surv; k++ )
364 : {
365 0 : tmp16 = i_mult2( surv1[k], 9 );
366 0 : FOR( i = 0; i < 9; i++ )
367 : {
368 : /*isf2[i] = isf[i] - dico1_isf[i+surv1[k]*9];*/
369 0 : isf2[i] = sub( isf[i], dico1_isf_fx[i + tmp16] );
370 0 : move16();
371 : }
372 :
373 0 : tmp_ind[0] = sub_VQ_fx( &isf2[0], dico21_isf_46b_fx, 3, SIZE_BK21, &min_err );
374 0 : move16();
375 0 : temp = L_add( min_err, 0 );
376 0 : tmp_ind[1] = sub_VQ_fx( &isf2[3], dico22_isf_46b_fx, 3, SIZE_BK22, &min_err );
377 0 : move16();
378 0 : temp = L_add( temp, min_err );
379 0 : tmp_ind[2] = sub_VQ_fx( &isf2[6], dico23_isf_46b_fx, 3, SIZE_BK23, &min_err );
380 0 : move16();
381 0 : temp = L_add( temp, min_err );
382 0 : IF( LT_32( temp, distance ) )
383 : {
384 0 : distance = L_add( temp, 0 );
385 0 : indice[0] = surv1[k];
386 0 : move16();
387 0 : FOR( i = 0; i < 3; i++ )
388 : {
389 0 : indice[i + 2] = tmp_ind[i];
390 0 : move16();
391 : }
392 : }
393 : }
394 :
395 : /*------------------------------------------------------------------------*
396 : * Quantize ISFs 9 - 15
397 : *------------------------------------------------------------------------*/
398 :
399 0 : VQ_stage1_fx( &isf[9], dico2_isf_fx, 7, SIZE_BK2, surv1, nb_surv );
400 :
401 0 : distance = MAX_32;
402 0 : move32();
403 0 : FOR( k = 0; k < nb_surv; k++ )
404 : {
405 0 : tmp16 = i_mult2( surv1[k], 7 );
406 0 : FOR( i = 0; i < 7; i++ )
407 : {
408 : /*isf2[9+i] = isf[9+i] - dico2_isf[i+surv1[k]*7];*/
409 0 : isf2[i + 9] = sub( isf[9 + i], dico2_isf_fx[i + tmp16] );
410 0 : move16();
411 : }
412 0 : tmp_ind[0] = sub_VQ_fx( &isf2[9], dico24_isf_46b_fx, 3, SIZE_BK24, &min_err );
413 0 : move16();
414 0 : temp = L_add( min_err, 0 );
415 :
416 0 : tmp_ind[1] = sub_VQ_fx( &isf2[12], dico25_isf_46b_fx, 4, SIZE_BK25, &min_err );
417 0 : move16();
418 0 : temp = L_add( temp, min_err );
419 :
420 0 : IF( LT_32( temp, distance ) )
421 : {
422 0 : distance = L_add( temp, 0 );
423 0 : indice[1] = surv1[k];
424 0 : move16();
425 0 : FOR( i = 0; i < 2; i++ )
426 : {
427 0 : indice[i + 5] = tmp_ind[i];
428 0 : move16();
429 : }
430 : }
431 : }
432 :
433 : /*------------------------------------------------------------------------*
434 : * decoding the ISFs
435 : *------------------------------------------------------------------------*/
436 :
437 0 : disf_2s_46b_fx( indice, isf, mem_AR, mem_MA, 0 );
438 :
439 : /*------------------------------------------------------------------------*
440 : * write indices to array
441 : *------------------------------------------------------------------------*/
442 0 : indice[0] = Indirect_dico1[indice[0]];
443 0 : move16(); /* Make interoperable with G722.2 */
444 :
445 0 : push_indice( hBstr, IND_ISF_0_0, indice[0], 8 );
446 0 : push_indice( hBstr, IND_ISF_0_1, indice[1], 8 );
447 0 : push_indice( hBstr, IND_ISF_1_0, indice[2], 6 );
448 0 : push_indice( hBstr, IND_ISF_1_1, indice[3], 7 );
449 0 : push_indice( hBstr, IND_ISF_1_2, indice[4], 7 );
450 0 : push_indice( hBstr, IND_ISF_1_3, indice[5], 5 );
451 0 : push_indice( hBstr, IND_ISF_1_4, indice[6], 5 );
452 :
453 0 : return;
454 : }
455 :
456 : /*-------------------------------------------------------------------*
457 : * VQ_stage1()
458 : *
459 : * 1st stage of ISF quantization
460 : *-------------------------------------------------------------------*/
461 :
462 0 : static void VQ_stage1_fx(
463 : const Word16 *x, /* i : ISF vector */
464 : const Word16 *dico, /* i : ISF codebook */
465 : const Word16 dim, /* i : codebook dimension */
466 : const Word16 dico_size, /* i : codebook size */
467 : Word16 *index, /* o : indices of best vector candidates */
468 : const Word16 surv /* i : nb of surviving best candidates */
469 : )
470 : {
471 : Word32 dist_min[N_SURV_MAX];
472 : Word32 dist;
473 : const Word16 *p_dico;
474 : Word16 i, j, k, l, temp;
475 :
476 :
477 0 : FOR( i = 0; i < surv; i++ )
478 : {
479 0 : dist_min[i] = MAX_32;
480 0 : move32();
481 0 : index[i] = i;
482 0 : move16();
483 : }
484 :
485 0 : p_dico = dico;
486 :
487 0 : FOR( i = 0; i < dico_size; i++ )
488 : {
489 0 : dist = L_deposit_l( 0 );
490 0 : FOR( j = 0; j < dim; j++ )
491 : {
492 : /*temp = x[j] - *p_dico++;*/
493 0 : temp = sub( x[j], *p_dico++ );
494 : /*dist += temp * temp;*/
495 0 : dist = L_mac( dist, temp, temp );
496 : }
497 :
498 0 : FOR( k = 0; k < surv; k++ )
499 : {
500 0 : IF( LT_32( dist, dist_min[k] ) )
501 : {
502 0 : FOR( l = sub( surv, 1 ); l > k; l-- )
503 : {
504 0 : dist_min[l] = dist_min[l - 1];
505 0 : move32();
506 0 : index[l] = index[l - 1];
507 0 : move16();
508 : }
509 0 : dist_min[k] = dist;
510 0 : move32();
511 0 : index[k] = i;
512 0 : move16();
513 0 : BREAK;
514 : }
515 : }
516 : }
517 0 : return;
518 : }
519 :
520 : /*-------------------------------------------------------------------*
521 : * sub_VQ_fx()
522 : *
523 : * Quantization of a subvector in Split-VQ of ISFs
524 : *-------------------------------------------------------------------*/
525 :
526 0 : static Word16 sub_VQ_fx( /* o : selected codebook vector index */
527 : Word16 *x, /* i/o: ISF vector */
528 : const Word16 *dico, /* i : ISF codebook */
529 : const Word16 dim, /* i : codebook dimension */
530 : const Word16 dico_size, /* i : codebook size */
531 : Word32 *distance /* o : quantization error (min. distance) */
532 : )
533 : {
534 : Word32 dist_min, dist;
535 : const Word16 *p_dico;
536 : Word16 i, j, index, temp;
537 :
538 :
539 0 : dist_min = MAX_32;
540 0 : move32();
541 0 : p_dico = dico;
542 0 : move16();
543 :
544 0 : index = 0;
545 0 : move16();
546 0 : FOR( i = 0; i < dico_size; i++ )
547 : {
548 0 : dist = L_deposit_l( 0 );
549 0 : FOR( j = 0; j < dim; j++ )
550 : {
551 : /*temp = x[j] - *p_dico++;*/
552 0 : temp = sub( x[j], *p_dico++ );
553 : /*dist += temp * temp;*/
554 0 : dist = L_mac( dist, temp, temp );
555 : }
556 :
557 0 : IF( LT_32( dist, dist_min ) )
558 : {
559 0 : dist_min = L_add( dist, 0 );
560 0 : index = i;
561 0 : move16();
562 : }
563 : }
564 :
565 0 : *distance = dist_min;
566 0 : move32();
567 :
568 : /* Reading the selected vector */
569 0 : p_dico = &dico[i_mult2( index, dim )];
570 0 : FOR( j = 0; j < dim; j++ )
571 : {
572 0 : x[j] = *p_dico++;
573 0 : move16();
574 : }
575 0 : return index;
576 : }
|