comparison libgsmefr/c1035pf.c @ 53:49dd1ac8e75b

libgsmefr: import most *.c files from ETSI source
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 25 Nov 2022 16:18:21 +0000
parents
children e005e7b91f3c
comparison
equal deleted inserted replaced
52:988fd7ff514f 53:49dd1ac8e75b
1 #include "typedef.h"
2 #include "basic_op.h"
3 #include "sig_proc.h"
4 #include "count.h"
5
6 #define L_CODE 40
7 #define NB_TRACK 5
8 #define NB_PULSE 10
9 #define STEP 5
10
11 /* local functions */
12
13 void cor_h_x (
14 Word16 h[], /* (i) : impulse response of weighted synthesis filter */
15 Word16 x[], /* (i) : target */
16 Word16 dn[] /* (o) : correlation between target and h[] */
17 );
18
19 void set_sign (
20 Word16 dn[], /* (i/o) : correlation between target and h[] */
21 Word16 cn[], /* (i) : residual after long term prediction */
22 Word16 sign[], /* (o) : sign of d[n] */
23 Word16 pos_max[], /* (o) : position of maximum of dn[] */
24 Word16 ipos[] /* (o) : starting position for each pulse */
25 );
26
27 void cor_h (
28 Word16 h[], /* (i) : impulse response of weighted synthesis
29 filter */
30 Word16 sign[], /* (i) : sign of d[n] */
31 Word16 rr[][L_CODE] /* (o) : matrix of autocorrelation */
32 );
33 void search_10i40 (
34 Word16 dn[], /* (i) : correlation between target and h[] */
35 Word16 rr[][L_CODE], /* (i) : matrix of autocorrelation */
36 Word16 ipos[], /* (i) : starting position for each pulse */
37 Word16 pos_max[], /* (i) : position of maximum of dn[] */
38 Word16 codvec[] /* (o) : algebraic codebook vector */
39 );
40 void build_code (
41 Word16 codvec[], /* (i) : algebraic codebook vector */
42 Word16 sign[], /* (i) : sign of dn[] */
43 Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */
44 Word16 h[], /* (i) : impulse response of weighted synthesis filter*/
45 Word16 y[], /* (o) : filtered fixed codebook excitation */
46 Word16 indx[] /* (o) : index of 10 pulses (position+sign+ampl)*10 */
47 );
48
49 void q_p (
50 Word16 *ind, /* Pulse position */
51 Word16 n /* Pulse number */
52 );
53
54 /*************************************************************************
55 *
56 * FUNCTION: code_10i40_35bits()
57 *
58 * PURPOSE: Searches a 35 bit algebraic codebook containing 10 pulses
59 * in a frame of 40 samples.
60 *
61 * DESCRIPTION:
62 * The code contains 10 nonzero pulses: i0...i9.
63 * All pulses can have two possible amplitudes: +1 or -1.
64 * The 40 positions in a subframe are divided into 5 tracks of
65 * interleaved positions. Each track contains two pulses.
66 * The pulses can have the following possible positions:
67 *
68 * i0, i5 : 0, 5, 10, 15, 20, 25, 30, 35.
69 * i1, i6 : 1, 6, 11, 16, 21, 26, 31, 36.
70 * i2, i7 : 2, 7, 12, 17, 22, 27, 32, 37.
71 * i3, i8 : 3, 8, 13, 18, 23, 28, 33, 38.
72 * i4, i9 : 4, 9, 14, 19, 24, 29, 34, 39.
73 *
74 * Each pair of pulses require 1 bit for their signs and 6 bits for their
75 * positions (3 bits + 3 bits). This results in a 35 bit codebook.
76 * The function determines the optimal pulse signs and positions, builds
77 * the codevector, and computes the filtered codevector.
78 *
79 *************************************************************************/
80
81 void code_10i40_35bits (
82 Word16 x[], /* (i) : target vector */
83 Word16 cn[], /* (i) : residual after long term prediction */
84 Word16 h[], /* (i) : impulse response of weighted synthesis filter
85 h[-L_subfr..-1] must be set to zero */
86 Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */
87 Word16 y[], /* (o) : filtered fixed codebook excitation */
88 Word16 indx[] /* (o) : index of 10 pulses (sign + position) */
89 )
90 {
91 Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE];
92 Word16 dn[L_CODE], sign[L_CODE];
93 Word16 rr[L_CODE][L_CODE], i;
94
95 cor_h_x (h, x, dn);
96 set_sign (dn, cn, sign, pos_max, ipos);
97 cor_h (h, sign, rr);
98 search_10i40 (dn, rr, ipos, pos_max, codvec);
99 build_code (codvec, sign, cod, h, y, indx);
100 for (i = 0; i < 10; i++)
101 {
102 q_p (&indx[i], i);
103 }
104 return;
105 }
106
107 /*************************************************************************
108 *
109 * FUNCTION: cor_h_x()
110 *
111 * PURPOSE: Computes correlation between target signal "x[]" and
112 * impulse response"h[]".
113 *
114 * DESCRIPTION:
115 * The correlation is given by:
116 * d[n] = sum_{i=n}^{L-1} x[i] h[i-n] n=0,...,L-1
117 *
118 * d[n] is normalized such that the sum of 5 maxima of d[n] corresponding
119 * to each position track does not saturate.
120 *
121 *************************************************************************/
122 void cor_h_x (
123 Word16 h[], /* (i) : impulse response of weighted synthesis filter */
124 Word16 x[], /* (i) : target */
125 Word16 dn[] /* (o) : correlation between target and h[] */
126 )
127 {
128 Word16 i, j, k;
129 Word32 s, y32[L_CODE], max, tot;
130
131 /* first keep the result on 32 bits and find absolute maximum */
132
133 tot = 5; move32 ();
134
135 for (k = 0; k < NB_TRACK; k++)
136 {
137 max = 0; move32 ();
138 for (i = k; i < L_CODE; i += STEP)
139 {
140 s = 0; move32 ();
141 for (j = i; j < L_CODE; j++)
142 s = L_mac (s, x[j], h[j - i]);
143
144 y32[i] = s; move32 ();
145
146 s = L_abs (s);
147 test ();
148 if (L_sub (s, max) > (Word32) 0L)
149 max = s; move32 ();
150 }
151 tot = L_add (tot, L_shr (max, 1));
152 }
153
154 j = sub (norm_l (tot), 2); /* multiply tot by 4 */
155
156 for (i = 0; i < L_CODE; i++)
157 {
158 dn[i] = round (L_shl (y32[i], j)); move16 ();
159 }
160 }
161
162 /*************************************************************************
163 *
164 * FUNCTION set_sign()
165 *
166 * PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]", and modifies
167 * dn[] to include the sign information (dn[i]=sign[i]*dn[i]).
168 * Also finds the position of maximum of correlation in each track
169 * and the starting position for each pulse.
170 *
171 *************************************************************************/
172
173 void set_sign (
174 Word16 dn[], /* (i/o): correlation between target and h[] */
175 Word16 cn[], /* (i) : residual after long term prediction */
176 Word16 sign[], /* (o) : sign of d[n] */
177 Word16 pos_max[], /* (o) : position of maximum correlation */
178 Word16 ipos[] /* (o) : starting position for each pulse */
179 )
180 {
181 Word16 i, j;
182 Word16 val, cor, k_cn, k_dn, max, max_of_all, pos;
183 Word16 en[L_CODE]; /* correlation vector */
184 Word32 s;
185
186 /* calculate energy for normalization of cn[] and dn[] */
187
188 s = 256; move32 ();
189 for (i = 0; i < L_CODE; i++)
190 {
191 s = L_mac (s, cn[i], cn[i]);
192 }
193 s = Inv_sqrt (s); move32 ();
194 k_cn = extract_h (L_shl (s, 5));
195
196 s = 256; move32 ();
197 for (i = 0; i < L_CODE; i++)
198 {
199 s = L_mac (s, dn[i], dn[i]);
200 }
201 s = Inv_sqrt (s); move32 ();
202 k_dn = extract_h (L_shl (s, 5));
203
204 for (i = 0; i < L_CODE; i++)
205 {
206 val = dn[i]; move16 ();
207 cor = round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10));
208
209 test ();
210 if (cor >= 0)
211 {
212 sign[i] = 32767; move16 (); /* sign = +1 */
213 }
214 else
215 {
216 sign[i] = -32767; move16 (); /* sign = -1 */
217 cor = negate (cor);
218 val = negate (val);
219 }
220 /* modify dn[] according to the fixed sign */
221 dn[i] = val; move16 ();
222 en[i] = cor; move16 ();
223 }
224
225 max_of_all = -1; move16 ();
226 for (i = 0; i < NB_TRACK; i++)
227 {
228 max = -1; move16 ();
229
230 for (j = i; j < L_CODE; j += STEP)
231 {
232 cor = en[j]; move16 ();
233 val = sub (cor, max);
234 test ();
235 if (val > 0)
236 {
237 max = cor; move16 ();
238 pos = j; move16 ();
239 }
240 }
241 /* store maximum correlation position */
242 pos_max[i] = pos; move16 ();
243 val = sub (max, max_of_all);
244 test ();
245 if (val > 0)
246 {
247 max_of_all = max; move16 ();
248 /* starting position for i0 */
249 ipos[0] = i; move16 ();
250 }
251 }
252
253 /*----------------------------------------------------------------*
254 * Set starting position of each pulse. *
255 *----------------------------------------------------------------*/
256
257 pos = ipos[0]; move16 ();
258 ipos[5] = pos; move16 ();
259
260 for (i = 1; i < NB_TRACK; i++)
261 {
262 pos = add (pos, 1);
263 if (sub (pos, NB_TRACK) >= 0)
264 {
265 pos = 0; move16 ();
266 }
267 ipos[i] = pos; move16 ();
268 ipos[i + 5] = pos; move16 ();
269 }
270 }
271
272 void q_p (
273 Word16 *ind, /* Pulse position */
274 Word16 n /* Pulse number */
275 )
276 {
277 static const Word16 gray[8] = {0, 1, 3, 2, 6, 4, 5, 7};
278 Word16 tmp;
279
280 tmp = *ind; move16 ();
281
282 test ();
283 if (sub (n, 5) < 0)
284 {
285 tmp = (tmp & 0x8) | gray[tmp & 0x7]; logic16 (); logic16 ();
286 logic16 ();
287 }
288 else
289 {
290 tmp = gray[tmp & 0x7]; logic16 (); move16 ();
291 }
292
293 *ind = tmp; move16 ();
294 }
295
296 /*************************************************************************
297 *
298 * FUNCTION: cor_h()
299 *
300 * PURPOSE: Computes correlations of h[] needed for the codebook search;
301 * and includes the sign information into the correlations.
302 *
303 * DESCRIPTION: The correlations are given by
304 * rr[i][j] = sum_{n=i}^{L-1} h[n-i] h[n-j]; i>=j; i,j=0,...,L-1
305 *
306 * and the sign information is included by
307 * rr[i][j] = rr[i][j]*sign[i]*sign[j]
308 *
309 *************************************************************************/
310
311 void cor_h (
312 Word16 h[], /* (i) : impulse response of weighted synthesis
313 filter */
314 Word16 sign[], /* (i) : sign of d[n] */
315 Word16 rr[][L_CODE] /* (o) : matrix of autocorrelation */
316 )
317 {
318 Word16 i, j, k, dec, h2[L_CODE];
319 Word32 s;
320
321 /* Scaling for maximum precision */
322
323 s = 2; move32 ();
324 for (i = 0; i < L_CODE; i++)
325 s = L_mac (s, h[i], h[i]);
326
327 j = sub (extract_h (s), 32767);
328 test ();
329 if (j == 0)
330 {
331 for (i = 0; i < L_CODE; i++)
332 {
333 h2[i] = shr (h[i], 1); move16 ();
334 }
335 }
336 else
337 {
338 s = L_shr (s, 1);
339 k = extract_h (L_shl (Inv_sqrt (s), 7));
340 k = mult (k, 32440); /* k = 0.99*k */
341
342 for (i = 0; i < L_CODE; i++)
343 {
344 h2[i] = round (L_shl (L_mult (h[i], k), 9));
345 move16 ();
346 }
347 }
348
349 /* build matrix rr[] */
350 s = 0; move32 ();
351 i = L_CODE - 1;
352 for (k = 0; k < L_CODE; k++, i--)
353 {
354 s = L_mac (s, h2[k], h2[k]);
355 rr[i][i] = round (s); move16 ();
356 }
357
358 for (dec = 1; dec < L_CODE; dec++)
359 {
360 s = 0; move32 ();
361 j = L_CODE - 1;
362 i = sub (j, dec);
363 for (k = 0; k < (L_CODE - dec); k++, i--, j--)
364 {
365 s = L_mac (s, h2[k], h2[k + dec]);
366 rr[j][i] = mult (round (s), mult (sign[i], sign[j]));
367 move16 ();
368 rr[i][j] = rr[j][i]; move16 ();
369 }
370 }
371 }
372
373 /*************************************************************************
374 *
375 * FUNCTION search_10i40()
376 *
377 * PURPOSE: Search the best codevector; determine positions of the 10 pulses
378 * in the 40-sample frame.
379 *
380 *************************************************************************/
381
382 #define _1_2 (Word16)(32768L/2)
383 #define _1_4 (Word16)(32768L/4)
384 #define _1_8 (Word16)(32768L/8)
385 #define _1_16 (Word16)(32768L/16)
386 #define _1_32 (Word16)(32768L/32)
387 #define _1_64 (Word16)(32768L/64)
388 #define _1_128 (Word16)(32768L/128)
389
390 void search_10i40 (
391 Word16 dn[], /* (i) : correlation between target and h[] */
392 Word16 rr[][L_CODE], /* (i) : matrix of autocorrelation */
393 Word16 ipos[], /* (i) : starting position for each pulse */
394 Word16 pos_max[], /* (i) : position of maximum of dn[] */
395 Word16 codvec[] /* (o) : algebraic codebook vector */
396 )
397 {
398 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
399 Word16 i, j, k, pos, ia, ib;
400 Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
401 Word16 alpk, alp, alp_16;
402 Word16 rrv[L_CODE];
403 Word32 s, alp0, alp1, alp2;
404
405 /* fix i0 on maximum of correlation position */
406
407 i0 = pos_max[ipos[0]]; move16 ();
408
409 /*------------------------------------------------------------------*
410 * i1 loop: *
411 *------------------------------------------------------------------*/
412
413 /* Default value */
414 psk = -1; move16 ();
415 alpk = 1; move16 ();
416 for (i = 0; i < NB_PULSE; i++)
417 {
418 codvec[i] = i; move16 ();
419 }
420
421 for (i = 1; i < NB_TRACK; i++)
422 {
423 i1 = pos_max[ipos[1]]; move16 ();
424 ps0 = add (dn[i0], dn[i1]);
425 alp0 = L_mult (rr[i0][i0], _1_16);
426 alp0 = L_mac (alp0, rr[i1][i1], _1_16);
427 alp0 = L_mac (alp0, rr[i0][i1], _1_8);
428
429 /*----------------------------------------------------------------*
430 * i2 and i3 loop: *
431 *----------------------------------------------------------------*/
432
433 /* initialize 4 indices for next loop. */
434 move16 (); /* initialize "rr[i3][i3]" pointer */
435 move16 (); /* initialize "rr[i0][i3]" pointer */
436 move16 (); /* initialize "rr[i1][i3]" pointer */
437 move16 (); /* initialize "rrv[i3]" pointer */
438
439 for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP)
440 {
441 s = L_mult (rr[i3][i3], _1_8); /* index incr= STEP+L_CODE */
442 s = L_mac (s, rr[i0][i3], _1_4); /* index increment = STEP */
443 s = L_mac (s, rr[i1][i3], _1_4); /* index increment = STEP */
444 rrv[i3] = round (s); move16 ();
445 }
446
447 /* Default value */
448 sq = -1; move16 ();
449 alp = 1; move16 ();
450 ps = 0; move16 ();
451 ia = ipos[2]; move16 ();
452 ib = ipos[3]; move16 ();
453
454 /* initialize 4 indices for i2 loop. */
455 move16 (); /* initialize "dn[i2]" pointer */
456 move16 (); /* initialize "rr[i2][i2]" pointer */
457 move16 (); /* initialize "rr[i0][i2]" pointer */
458 move16 (); /* initialize "rr[i1][i2]" pointer */
459
460 for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP)
461 {
462 /* index increment = STEP */
463 ps1 = add (ps0, dn[i2]);
464
465 /* index incr= STEP+L_CODE */
466 alp1 = L_mac (alp0, rr[i2][i2], _1_16);
467 /* index increment = STEP */
468 alp1 = L_mac (alp1, rr[i0][i2], _1_8);
469 /* index increment = STEP */
470 alp1 = L_mac (alp1, rr[i1][i2], _1_8);
471
472 /* initialize 3 indices for i3 inner loop */
473 move16 (); /* initialize "dn[i3]" pointer */
474 move16 (); /* initialize "rrv[i3]" pointer */
475 move16 (); /* initialize "rr[i2][i3]" pointer */
476
477 for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP)
478 {
479 /* index increment = STEP */
480 ps2 = add (ps1, dn[i3]);
481
482 /* index increment = STEP */
483 alp2 = L_mac (alp1, rrv[i3], _1_2);
484 /* index increment = STEP */
485 alp2 = L_mac (alp2, rr[i2][i3], _1_8);
486
487 sq2 = mult (ps2, ps2);
488
489 alp_16 = round (alp2);
490
491 s = L_msu (L_mult (alp, sq2), sq, alp_16);
492
493 test ();
494 if (s > 0)
495 {
496 sq = sq2; move16 ();
497 ps = ps2; move16 ();
498 alp = alp_16; move16 ();
499 ia = i2; move16 ();
500 ib = i3; move16 ();
501 }
502 }
503 }
504 i2 = ia; move16 ();
505 i3 = ib; move16 ();
506
507 /*----------------------------------------------------------------*
508 * i4 and i5 loop: *
509 *----------------------------------------------------------------*/
510
511 ps0 = ps; move16 ();
512 alp0 = L_mult (alp, _1_2);
513
514 /* initialize 6 indices for next loop (see i2-i3 loop) */
515 move16 (); move16 (); move16 (); move16 (); move16 (); move16 ();
516
517 for (i5 = ipos[5]; i5 < L_CODE; i5 += STEP)
518 {
519 s = L_mult (rr[i5][i5], _1_8);
520 s = L_mac (s, rr[i0][i5], _1_4);
521 s = L_mac (s, rr[i1][i5], _1_4);
522 s = L_mac (s, rr[i2][i5], _1_4);
523 s = L_mac (s, rr[i3][i5], _1_4);
524 rrv[i5] = round (s); move16 ();
525 }
526
527 /* Default value */
528 sq = -1; move16 ();
529 alp = 1; move16 ();
530 ps = 0; move16 ();
531 ia = ipos[4]; move16 ();
532 ib = ipos[5]; move16 ();
533
534 /* initialize 6 indices for i4 loop (see i2-i3 loop) */
535 move16 (); move16 (); move16 (); move16 (); move16 (); move16 ();
536
537 for (i4 = ipos[4]; i4 < L_CODE; i4 += STEP)
538 {
539 ps1 = add (ps0, dn[i4]);
540
541 alp1 = L_mac (alp0, rr[i4][i4], _1_32);
542 alp1 = L_mac (alp1, rr[i0][i4], _1_16);
543 alp1 = L_mac (alp1, rr[i1][i4], _1_16);
544 alp1 = L_mac (alp1, rr[i2][i4], _1_16);
545 alp1 = L_mac (alp1, rr[i3][i4], _1_16);
546
547 /* initialize 3 indices for i5 inner loop (see i2-i3 loop) */
548 move16 (); move16 (); move16 ();
549
550 for (i5 = ipos[5]; i5 < L_CODE; i5 += STEP)
551 {
552 ps2 = add (ps1, dn[i5]);
553
554 alp2 = L_mac (alp1, rrv[i5], _1_4);
555 alp2 = L_mac (alp2, rr[i4][i5], _1_16);
556
557 sq2 = mult (ps2, ps2);
558
559 alp_16 = round (alp2);
560
561 s = L_msu (L_mult (alp, sq2), sq, alp_16);
562
563 test ();
564 if (s > 0)
565 {
566 sq = sq2; move16 ();
567 ps = ps2; move16 ();
568 alp = alp_16; move16 ();
569 ia = i4; move16 ();
570 ib = i5; move16 ();
571 }
572 }
573 }
574 i4 = ia; move16 ();
575 i5 = ib; move16 ();
576
577 /*----------------------------------------------------------------*
578 * i6 and i7 loop: *
579 *----------------------------------------------------------------*/
580
581 ps0 = ps; move16 ();
582 alp0 = L_mult (alp, _1_2);
583
584 /* initialize 8 indices for next loop (see i2-i3 loop) */
585 move16 (); move16 (); move16 (); move16 ();
586 move16 (); move16 (); move16 (); move16 ();
587
588 for (i7 = ipos[7]; i7 < L_CODE; i7 += STEP)
589 {
590 s = L_mult (rr[i7][i7], _1_16);
591 s = L_mac (s, rr[i0][i7], _1_8);
592 s = L_mac (s, rr[i1][i7], _1_8);
593 s = L_mac (s, rr[i2][i7], _1_8);
594 s = L_mac (s, rr[i3][i7], _1_8);
595 s = L_mac (s, rr[i4][i7], _1_8);
596 s = L_mac (s, rr[i5][i7], _1_8);
597 rrv[i7] = round (s); move16 ();
598 }
599
600 /* Default value */
601 sq = -1; move16 ();
602 alp = 1; move16 ();
603 ps = 0; move16 ();
604 ia = ipos[6]; move16 ();
605 ib = ipos[7]; move16 ();
606
607 /* initialize 8 indices for i6 loop (see i2-i3 loop) */
608 move16 (); move16 (); move16 (); move16 ();
609 move16 (); move16 (); move16 (); move16 ();
610
611 for (i6 = ipos[6]; i6 < L_CODE; i6 += STEP)
612 {
613 ps1 = add (ps0, dn[i6]);
614
615 alp1 = L_mac (alp0, rr[i6][i6], _1_64);
616 alp1 = L_mac (alp1, rr[i0][i6], _1_32);
617 alp1 = L_mac (alp1, rr[i1][i6], _1_32);
618 alp1 = L_mac (alp1, rr[i2][i6], _1_32);
619 alp1 = L_mac (alp1, rr[i3][i6], _1_32);
620 alp1 = L_mac (alp1, rr[i4][i6], _1_32);
621 alp1 = L_mac (alp1, rr[i5][i6], _1_32);
622
623 /* initialize 3 indices for i7 inner loop (see i2-i3 loop) */
624 move16 (); move16 (); move16 ();
625
626 for (i7 = ipos[7]; i7 < L_CODE; i7 += STEP)
627 {
628 ps2 = add (ps1, dn[i7]);
629
630 alp2 = L_mac (alp1, rrv[i7], _1_4);
631 alp2 = L_mac (alp2, rr[i6][i7], _1_32);
632
633 sq2 = mult (ps2, ps2);
634
635 alp_16 = round (alp2);
636
637 s = L_msu (L_mult (alp, sq2), sq, alp_16);
638
639 test ();
640 if (s > 0)
641 {
642 sq = sq2; move16 ();
643 ps = ps2; move16 ();
644 alp = alp_16; move16 ();
645 ia = i6; move16 ();
646 ib = i7; move16 ();
647 }
648 }
649 }
650 i6 = ia; move16 ();
651 i7 = ib; move16 ();
652
653 /*----------------------------------------------------------------*
654 * i8 and i9 loop: *
655 *----------------------------------------------------------------*/
656
657 ps0 = ps; move16 ();
658 alp0 = L_mult (alp, _1_2);
659
660 /* initialize 10 indices for next loop (see i2-i3 loop) */
661 move16 (); move16 (); move16 (); move16 (); move16 ();
662 move16 (); move16 (); move16 (); move16 (); move16 ();
663
664 for (i9 = ipos[9]; i9 < L_CODE; i9 += STEP)
665 {
666 s = L_mult (rr[i9][i9], _1_16);
667 s = L_mac (s, rr[i0][i9], _1_8);
668 s = L_mac (s, rr[i1][i9], _1_8);
669 s = L_mac (s, rr[i2][i9], _1_8);
670 s = L_mac (s, rr[i3][i9], _1_8);
671 s = L_mac (s, rr[i4][i9], _1_8);
672 s = L_mac (s, rr[i5][i9], _1_8);
673 s = L_mac (s, rr[i6][i9], _1_8);
674 s = L_mac (s, rr[i7][i9], _1_8);
675 rrv[i9] = round (s); move16 ();
676 }
677
678 /* Default value */
679 sq = -1; move16 ();
680 alp = 1; move16 ();
681 ps = 0; move16 ();
682 ia = ipos[8]; move16 ();
683 ib = ipos[9]; move16 ();
684
685 /* initialize 10 indices for i8 loop (see i2-i3 loop) */
686 move16 (); move16 (); move16 (); move16 (); move16 ();
687 move16 (); move16 (); move16 (); move16 (); move16 ();
688
689 for (i8 = ipos[8]; i8 < L_CODE; i8 += STEP)
690 {
691 ps1 = add (ps0, dn[i8]);
692
693 alp1 = L_mac (alp0, rr[i8][i8], _1_128);
694 alp1 = L_mac (alp1, rr[i0][i8], _1_64);
695 alp1 = L_mac (alp1, rr[i1][i8], _1_64);
696 alp1 = L_mac (alp1, rr[i2][i8], _1_64);
697 alp1 = L_mac (alp1, rr[i3][i8], _1_64);
698 alp1 = L_mac (alp1, rr[i4][i8], _1_64);
699 alp1 = L_mac (alp1, rr[i5][i8], _1_64);
700 alp1 = L_mac (alp1, rr[i6][i8], _1_64);
701 alp1 = L_mac (alp1, rr[i7][i8], _1_64);
702
703 /* initialize 3 indices for i9 inner loop (see i2-i3 loop) */
704 move16 (); move16 (); move16 ();
705
706 for (i9 = ipos[9]; i9 < L_CODE; i9 += STEP)
707 {
708 ps2 = add (ps1, dn[i9]);
709
710 alp2 = L_mac (alp1, rrv[i9], _1_8);
711 alp2 = L_mac (alp2, rr[i8][i9], _1_64);
712
713 sq2 = mult (ps2, ps2);
714
715 alp_16 = round (alp2);
716
717 s = L_msu (L_mult (alp, sq2), sq, alp_16);
718
719 test ();
720 if (s > 0)
721 {
722 sq = sq2; move16 ();
723 ps = ps2; move16 ();
724 alp = alp_16; move16 ();
725 ia = i8; move16 ();
726 ib = i9; move16 ();
727 }
728 }
729 }
730
731 /*----------------------------------------------------------------*
732 * memorise codevector if this one is better than the last one. *
733 *----------------------------------------------------------------*/
734
735 s = L_msu (L_mult (alpk, sq), psk, alp);
736
737 test ();
738 if (s > 0)
739 {
740 psk = sq; move16 ();
741 alpk = alp; move16 ();
742 codvec[0] = i0; move16 ();
743 codvec[1] = i1; move16 ();
744 codvec[2] = i2; move16 ();
745 codvec[3] = i3; move16 ();
746 codvec[4] = i4; move16 ();
747 codvec[5] = i5; move16 ();
748 codvec[6] = i6; move16 ();
749 codvec[7] = i7; move16 ();
750 codvec[8] = ia; move16 ();
751 codvec[9] = ib; move16 ();
752 }
753 /*----------------------------------------------------------------*
754 * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,i8 and i9. *
755 *----------------------------------------------------------------*/
756
757 pos = ipos[1]; move16 ();
758 for (j = 1, k = 2; k < NB_PULSE; j++, k++)
759 {
760 ipos[j] = ipos[k]; move16 ();
761 }
762 ipos[NB_PULSE - 1] = pos; move16 ();
763 }
764 }
765
766 /*************************************************************************
767 *
768 * FUNCTION: build_code()
769 *
770 * PURPOSE: Builds the codeword, the filtered codeword and index of the
771 * codevector, based on the signs and positions of 10 pulses.
772 *
773 *************************************************************************/
774
775 void build_code (
776 Word16 codvec[], /* (i) : position of pulses */
777 Word16 sign[], /* (i) : sign of d[n] */
778 Word16 cod[], /* (o) : innovative code vector */
779 Word16 h[], /* (i) : impulse response of weighted synthesis filter*/
780 Word16 y[], /* (o) : filtered innovative code */
781 Word16 indx[] /* (o) : index of 10 pulses (sign+position) */
782 )
783 {
784 Word16 i, j, k, track, index, _sign[NB_PULSE];
785 Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
786 Word32 s;
787
788 for (i = 0; i < L_CODE; i++)
789 {
790 cod[i] = 0; move16 ();
791 }
792 for (i = 0; i < NB_TRACK; i++)
793 {
794 indx[i] = -1; move16 ();
795 }
796
797 for (k = 0; k < NB_PULSE; k++)
798 {
799 /* read pulse position */
800 i = codvec[k]; move16 ();
801 /* read sign */
802 j = sign[i]; move16 ();
803
804 index = mult (i, 6554); /* index = pos/5 */
805 /* track = pos%5 */
806 track = sub (i, extract_l (L_shr (L_mult (index, 5), 1)));
807 test ();
808 if (j > 0)
809 {
810 cod[i] = add (cod[i], 4096);
811 _sign[k] = 8192; move16 ();
812
813 }
814 else
815 {
816 cod[i] = sub (cod[i], 4096);
817 _sign[k] = -8192; move16 ();
818 index = add (index, 8);
819 }
820
821 test ();
822 if (indx[track] < 0)
823 {
824 indx[track] = index; move16 ();
825 }
826 else
827 {
828 test (); logic16 (); logic16 ();
829 if (((index ^ indx[track]) & 8) == 0)
830 {
831 /* sign of 1st pulse == sign of 2nd pulse */
832
833 test ();
834 if (sub (indx[track], index) <= 0)
835 {
836 indx[track + 5] = index; move16 ();
837 }
838 else
839 {
840 indx[track + 5] = indx[track];
841 move16 ();
842 indx[track] = index; move16 ();
843 }
844 }
845 else
846 {
847 /* sign of 1st pulse != sign of 2nd pulse */
848
849 test (); logic16 (); logic16 ();
850 if (sub ((indx[track] & 7), (index & 7)) <= 0)
851 {
852 indx[track + 5] = indx[track];
853 move16 ();
854 indx[track] = index; move16 ();
855 }
856 else
857 {
858 indx[track + 5] = index; move16 ();
859 }
860 }
861 }
862 }
863
864 p0 = h - codvec[0]; move16 ();
865 p1 = h - codvec[1]; move16 ();
866 p2 = h - codvec[2]; move16 ();
867 p3 = h - codvec[3]; move16 ();
868 p4 = h - codvec[4]; move16 ();
869 p5 = h - codvec[5]; move16 ();
870 p6 = h - codvec[6]; move16 ();
871 p7 = h - codvec[7]; move16 ();
872 p8 = h - codvec[8]; move16 ();
873 p9 = h - codvec[9]; move16 ();
874
875 for (i = 0; i < L_CODE; i++)
876 {
877 s = 0; move32 ();
878 s = L_mac (s, *p0++, _sign[0]);
879 s = L_mac (s, *p1++, _sign[1]);
880 s = L_mac (s, *p2++, _sign[2]);
881 s = L_mac (s, *p3++, _sign[3]);
882 s = L_mac (s, *p4++, _sign[4]);
883 s = L_mac (s, *p5++, _sign[5]);
884 s = L_mac (s, *p6++, _sign[6]);
885 s = L_mac (s, *p7++, _sign[7]);
886 s = L_mac (s, *p8++, _sign[8]);
887 s = L_mac (s, *p9++, _sign[9]);
888 y[i] = round (s); move16 ();
889 }
890 }
891