FreeCalypso > hg > efr-experiments
comparison src/c1035pf.c @ 0:56410792419a
src: original EFR source from ETSI
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 03 Apr 2024 05:31:37 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:56410792419a |
---|---|
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 |