1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21 3GPP TS 26.073
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/s10_8pf.c
35 Funtions: search_10and8i40
36
37 Date: 04/18/2000
38
39 ------------------------------------------------------------------------------
40 REVISION HISTORY
41
42 Description: Adding pOverflow to the functions to remove global variables.
43 These changes are needed for the EPOC releases. Cleaned up code.
44 Updated template.
45
46 Description: Changed temp to temp32. When temp was only 16 bits it was not
47 holding the 32 bit value returned from the functions. Some
48 variables were also being declared as Word16 rather than Word32
49 as they were suposed to be.
50
51 Description: Changed copyright year. Removed all calls to math functions by
52 inlining them, and removed all unnecessary files in the Include
53 section.
54
55 Description: Made the following changes per comments from Phase 2/3 review:
56 1. Removed all #defines.
57 2. Used a pointer to &codvec[0] instead of array indexing.
58 3. Removed multiple data casting in the code.
59
60 Description:
61 1. Eliminated unused include files.
62 2. Replaced array addressing by pointers, this by taking
63 advantage of the fact that the autocrrelation matrix is
64 a toeplitz matrix, so r[i][j] = r[j][i], then a single
65 pointer can be used to address a matrix. The use of this
66 is not uniform along the function (due to compiler limitations:
67 handling so many variables in this file) so the use
68 of this is pointer optimizations is limited to places
69 where the ARM compiler provides the lesses numer of cycles
70 3. Eliminated use of intermediate variables to accelerate
71 comparisons (like in the nested loops)
72 4. Introduced array temp1[], to pre-calculate the elements
73 used in the nested loops, in this way the calculation is
74 not repeated in every loop iteration. This is done for
75 loops i3-i5-i7 and i9
76 5. Use array Index[] to store indexes i1:i9, and then use memcpy
77 to update indexes.
78 6. Eliminated shifts by modifying the way number are rounded,
79 this does not have any effect in ARM processors but may help
80 other compilers
81
82 Description:
83 1. When storing indexes, added memcpy() to support the rates
84 that use this function: 12.2 (already done) and 10.2 (missing).
85
86 Description: Replaced OSCL mem type functions and eliminated include
87 files that now are chosen by OSCL definitions
88
89 Description: Changed round function name to pv_round to avoid conflict with
90 round function in C standard library.
91
92 Description:
93
94 ------------------------------------------------------------------------------
95 */
96
97 /*----------------------------------------------------------------------------
98 ; INCLUDES
99 ----------------------------------------------------------------------------*/
100 #include <string.h>
101
102 #include "s10_8pf.h"
103 #include "cnst.h"
104
105 /*----------------------------------------------------------------------------
106 ; MACROS
107 ; Define module specific macros here
108 ----------------------------------------------------------------------------*/
109
110 /*----------------------------------------------------------------------------
111 ; DEFINES
112 ; Include all pre-processor statements here. Include conditional
113 ; compile variables also.
114 ----------------------------------------------------------------------------*/
115
116 /*----------------------------------------------------------------------------
117 ; LOCAL FUNCTION DEFINITIONS
118 ; Function Prototype declaration
119 ----------------------------------------------------------------------------*/
120
121 /*----------------------------------------------------------------------------
122 ; LOCAL VARIABLE DEFINITIONS
123 ; Variable declaration - defined here and used outside this module
124 ----------------------------------------------------------------------------*/
125
126 /*
127 ------------------------------------------------------------------------------
128 FUNCTION NAME: search_10and8i40
129 ------------------------------------------------------------------------------
130 INPUT AND OUTPUT DEFINITIONS
131
132 Inputs:
133 nbPulse = nbPulses to find (Word16)
134 step = step size (Word16)
135 nbTracks = nbTracks (Word16)
136 dn[] = correlation between target and h[] (Word16)
137 rr[][] = matrix of autocorrelation (Word16)
138 ipos[] = starting position of each pulse (Word16)
139 pos_max[] = Position of maximum dn[] (Word16)
140 codvec[] = Algebraic codebook vector (Word16)
141 pOverflow = pointer to Overflow flag (Flag)
142
143 Outputs:
144 codvec[] = Algebraic codebook vector (Word16)
145 pOverflow -> 1 if processing this funvction results in satuaration
146
147 Returns:
148 None
149
150 Global Variables Used:
151 None
152
153 Local Variables Needed:
154 None
155
156 ------------------------------------------------------------------------------
157 FUNCTION DESCRIPTION
158
159 This function searches for the best codevector; It determines the positions
160 of the 10/8 pulses in the 40-sample frame.
161
162 search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec); for GSMEFR
163 search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec); for 10.2
164
165
166 ------------------------------------------------------------------------------
167 REQUIREMENTS
168
169 None
170
171 ------------------------------------------------------------------------------
172 REFERENCES
173
174 s10_8pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
175
176 ------------------------------------------------------------------------------
177 PSEUDO-CODE
178
179 void search_10and8i40 (
180 Word16 nbPulse, // i : nbpulses to find
181 Word16 step, // i : stepsize
182 Word16 nbTracks, // i : nbTracks
183 Word16 dn[], // i : correlation between target and h[]
184 Word16 rr[][L_CODE], // i : matrix of autocorrelation
185 Word16 ipos[], // i : starting position for each pulse
186 Word16 pos_max[], // i : position of maximum of dn[]
187 Word16 codvec[] // o : algebraic codebook vector
188 )
189 {
190 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
191 Word16 i, j, k, pos, ia, ib;
192 Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
193 Word16 alpk, alp, alp_16;
194 Word16 rrv[L_CODE];
195 Word32 s, alp0, alp1, alp2;
196 Word16 gsmefrFlag;
197
198
199 if (sub(nbPulse, 10) == 0)
200 {
201 gsmefrFlag=1;
202 }
203 else
204 {
205 gsmefrFlag=0;
206 }
207
208 // fix i0 on maximum of correlation position
209 i0 = pos_max[ipos[0]];
210
211 //
212 // i1 loop: *
213 //
214
215 // Default value
216
217 psk = -1;
218 alpk = 1;
219 for (i = 0; i < nbPulse; i++)
220 {
221 codvec[i] = i;
222 }
223
224 for (i = 1; i < nbTracks; i++)
225 {
226 i1 = pos_max[ipos[1]];
227 ps0 = add (dn[i0], dn[i1]);
228 alp0 = L_mult (rr[i0][i0], _1_16);
229 alp0 = L_mac (alp0, rr[i1][i1], _1_16);
230 alp0 = L_mac (alp0, rr[i0][i1], _1_8);
231
232 //
233 // i2 and i3 loop
234 //
235
236 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
237 {
238 s = L_mult (rr[i3][i3], _1_8); // index incr= step+L_CODE
239 s = L_mac (s, rr[i0][i3], _1_4); // index increment = step
240 s = L_mac (s, rr[i1][i3], _1_4); // index increment = step
241 rrv[i3] = pv_round (s);
242 }
243
244 // Default value
245 sq = -1;
246 alp = 1;
247 ps = 0;
248 ia = ipos[2];
249 ib = ipos[3];
250
251 for (i2 = ipos[2]; i2 < L_CODE; i2 += step)
252 {
253 // index increment = step
254 ps1 = add (ps0, dn[i2]);
255
256 // index incr= step+L_CODE
257 alp1 = L_mac (alp0, rr[i2][i2], _1_16);
258
259 // index increment = step
260 alp1 = L_mac (alp1, rr[i0][i2], _1_8);
261
262 // index increment = step
263 alp1 = L_mac (alp1, rr[i1][i2], _1_8);
264
265 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
266 {
267 // index increment = step
268 ps2 = add (ps1, dn[i3]);
269
270 // index increment = step
271 alp2 = L_mac (alp1, rrv[i3], _1_2);
272
273 // index increment = step
274 alp2 = L_mac (alp2, rr[i2][i3], _1_8);
275
276 sq2 = mult (ps2, ps2);
277
278 alp_16 = pv_round (alp2);
279
280 s = L_msu (L_mult (alp, sq2), sq, alp_16);
281
282 if (s > 0)
283 {
284 sq = sq2;
285 ps = ps2;
286 alp = alp_16;
287 ia = i2;
288 ib = i3;
289 }
290 }
291 }
292 i2 = ia;
293 i3 = ib;
294
295 //
296 // i4 and i5 loop:
297 //
298
299 ps0 = ps;
300 alp0 = L_mult (alp, _1_2);
301
302 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
303 {
304 s = L_mult (rr[i5][i5], _1_8);
305 s = L_mac (s, rr[i0][i5], _1_4);
306 s = L_mac (s, rr[i1][i5], _1_4);
307 s = L_mac (s, rr[i2][i5], _1_4);
308 s = L_mac (s, rr[i3][i5], _1_4);
309 rrv[i5] = pv_round (s);
310 }
311
312 // Default value
313 sq = -1;
314 alp = 1;
315 ps = 0;
316 ia = ipos[4];
317 ib = ipos[5];
318
319 for (i4 = ipos[4]; i4 < L_CODE; i4 += step)
320 {
321 ps1 = add (ps0, dn[i4]);
322
323 alp1 = L_mac (alp0, rr[i4][i4], _1_32);
324 alp1 = L_mac (alp1, rr[i0][i4], _1_16);
325 alp1 = L_mac (alp1, rr[i1][i4], _1_16);
326 alp1 = L_mac (alp1, rr[i2][i4], _1_16);
327 alp1 = L_mac (alp1, rr[i3][i4], _1_16);
328
329 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
330 {
331 ps2 = add (ps1, dn[i5]);
332
333 alp2 = L_mac (alp1, rrv[i5], _1_4);
334 alp2 = L_mac (alp2, rr[i4][i5], _1_16);
335
336 sq2 = mult (ps2, ps2);
337
338 alp_16 = pv_round (alp2);
339
340 s = L_msu (L_mult (alp, sq2), sq, alp_16);
341
342 if (s > 0)
343 {
344 sq = sq2;
345 ps = ps2;
346 alp = alp_16;
347 ia = i4;
348 ib = i5;
349 }
350 }
351 }
352 i4 = ia;
353 i5 = ib;
354
355 //
356 // i6 and i7 loop:
357 //
358
359 ps0 = ps;
360 alp0 = L_mult (alp, _1_2);
361
362 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
363 {
364 s = L_mult (rr[i7][i7], _1_16);
365 s = L_mac (s, rr[i0][i7], _1_8);
366 s = L_mac (s, rr[i1][i7], _1_8);
367 s = L_mac (s, rr[i2][i7], _1_8);
368 s = L_mac (s, rr[i3][i7], _1_8);
369 s = L_mac (s, rr[i4][i7], _1_8);
370 s = L_mac (s, rr[i5][i7], _1_8);
371 rrv[i7] = pv_round (s);
372 }
373
374 // Default value
375 sq = -1;
376 alp = 1;
377 ps = 0;
378 ia = ipos[6];
379 ib = ipos[7];
380
381 for (i6 = ipos[6]; i6 < L_CODE; i6 += step)
382 {
383 ps1 = add (ps0, dn[i6]);
384
385 alp1 = L_mac (alp0, rr[i6][i6], _1_64);
386 alp1 = L_mac (alp1, rr[i0][i6], _1_32);
387 alp1 = L_mac (alp1, rr[i1][i6], _1_32);
388 alp1 = L_mac (alp1, rr[i2][i6], _1_32);
389 alp1 = L_mac (alp1, rr[i3][i6], _1_32);
390 alp1 = L_mac (alp1, rr[i4][i6], _1_32);
391 alp1 = L_mac (alp1, rr[i5][i6], _1_32);
392
393 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
394 {
395 ps2 = add (ps1, dn[i7]);
396
397 alp2 = L_mac (alp1, rrv[i7], _1_4);
398 alp2 = L_mac (alp2, rr[i6][i7], _1_32);
399
400 sq2 = mult (ps2, ps2);
401
402 alp_16 = pv_round (alp2);
403
404 s = L_msu (L_mult (alp, sq2), sq, alp_16);
405
406 if (s > 0)
407 {
408 sq = sq2;
409 ps = ps2;
410 alp = alp_16;
411 ia = i6;
412 ib = i7;
413 }
414 }
415 }
416 i6 = ia;
417 i7 = ib;
418
419 // now finished searching a set of 8 pulses
420
421 if(gsmefrFlag != 0){
422 // go on with the two last pulses for GSMEFR
423 //
424 // i8 and i9 loop:
425 //
426
427 ps0 = ps;
428 alp0 = L_mult (alp, _1_2);
429
430 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
431 {
432 s = L_mult (rr[i9][i9], _1_16);
433 s = L_mac (s, rr[i0][i9], _1_8);
434 s = L_mac (s, rr[i1][i9], _1_8);
435 s = L_mac (s, rr[i2][i9], _1_8);
436 s = L_mac (s, rr[i3][i9], _1_8);
437 s = L_mac (s, rr[i4][i9], _1_8);
438 s = L_mac (s, rr[i5][i9], _1_8);
439 s = L_mac (s, rr[i6][i9], _1_8);
440 s = L_mac (s, rr[i7][i9], _1_8);
441 rrv[i9] = pv_round (s);
442 }
443
444 // Default value
445 sq = -1;
446 alp = 1;
447 ps = 0;
448 ia = ipos[8];
449 ib = ipos[9];
450
451 for (i8 = ipos[8]; i8 < L_CODE; i8 += step)
452 {
453 ps1 = add (ps0, dn[i8]);
454
455 alp1 = L_mac (alp0, rr[i8][i8], _1_128);
456 alp1 = L_mac (alp1, rr[i0][i8], _1_64);
457 alp1 = L_mac (alp1, rr[i1][i8], _1_64);
458 alp1 = L_mac (alp1, rr[i2][i8], _1_64);
459 alp1 = L_mac (alp1, rr[i3][i8], _1_64);
460 alp1 = L_mac (alp1, rr[i4][i8], _1_64);
461 alp1 = L_mac (alp1, rr[i5][i8], _1_64);
462 alp1 = L_mac (alp1, rr[i6][i8], _1_64);
463 alp1 = L_mac (alp1, rr[i7][i8], _1_64);
464
465 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
466 {
467 ps2 = add (ps1, dn[i9]);
468
469 alp2 = L_mac (alp1, rrv[i9], _1_8);
470 alp2 = L_mac (alp2, rr[i8][i9], _1_64);
471
472 sq2 = mult (ps2, ps2);
473
474 alp_16 = pv_round (alp2);
475
476 s = L_msu (L_mult (alp, sq2), sq, alp_16);
477
478 if (s > 0)
479 {
480 sq = sq2;
481 ps = ps2;
482 alp = alp_16;
483 ia = i8;
484 ib = i9;
485 }
486 }
487 }
488 } // end gsmefrFlag
489
490 //
491 // test and memorise if this combination is better than the last one/
492 //
493
494 s = L_msu (L_mult (alpk, sq), psk, alp);
495
496 if (s > 0)
497 {
498 psk = sq;
499 alpk = alp;
500 codvec[0] = i0;
501 codvec[1] = i1;
502 codvec[2] = i2;
503 codvec[3] = i3;
504 codvec[4] = i4;
505 codvec[5] = i5;
506 codvec[6] = i6;
507 codvec[7] = i7;
508
509 if (gsmefrFlag != 0)
510 {
511 codvec[8] = ia;
512 codvec[9] = ib;
513 }
514 }
515
516 //
517 // Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9)/
518 //
519
520 pos = ipos[1];
521 for (j = 1, k = 2; k < nbPulse; j++, k++)
522 {
523 ipos[j] = ipos[k];
524 }
525 ipos[sub(nbPulse,1)] = pos;
526 } // end 1..nbTracks loop
527 }
528
529 ------------------------------------------------------------------------------
530 RESOURCES USED [optional]
531
532 When the code is written for a specific target processor the
533 the resources used should be documented below.
534
535 HEAP MEMORY USED: x bytes
536
537 STACK MEMORY USED: x bytes
538
539 CLOCK CYCLES: (cycle count equation for this function) + (variable
540 used to represent cycle count for each subroutine
541 called)
542 where: (cycle count variable) = cycle count for [subroutine
543 name]
544
545 ------------------------------------------------------------------------------
546 CAUTION [optional]
547 [State any special notes, constraints or cautions for users of this function]
548
549 ------------------------------------------------------------------------------
550 */
551
552
553 /*----------------------------------------------------------------------------
554 ; FUNCTION CODE
555 ----------------------------------------------------------------------------*/
search_10and8i40(Word16 nbPulse,Word16 step,Word16 nbTracks,Word16 dn[],Word16 rr[][L_CODE],Word16 ipos[],Word16 pos_max[],Word16 codvec[],Flag * pOverflow)556 void search_10and8i40(
557 Word16 nbPulse, /* i : nbpulses to find */
558 Word16 step, /* i : stepsize */
559 Word16 nbTracks, /* i : nbTracks */
560 Word16 dn[], /* i : correlation between target and h[] */
561 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
562 Word16 ipos[], /* i : starting position for each pulse */
563 Word16 pos_max[], /* i : position of maximum of dn[] */
564 Word16 codvec[], /* o : algebraic codebook vector */
565 Flag *pOverflow /* i/o : overflow flag */
566 )
567 {
568 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i9;
569 Word16 i, j, k/*, m*/;
570 Word16 pos, ia, ib;
571 Word16 psk;
572 Word16 sq, sq2;
573 Word16 alpk, alp, alp_16;
574 Word32 s;
575 Word32 alp0, alp1, alp2;
576 Word16 gsmefrFlag;
577 Word16 *p_codvec = codvec;
578 Word16 *p_temp2;
579
580 Word16 temp1[2*L_CODE];
581 Word16 *p_temp1;
582 Word16 ps2;
583 Word16 ps1;
584 Word16 ps;
585 Word16 ps0;
586
587 Word16 index[10];
588
589 OSCL_UNUSED_ARG(pOverflow);
590
591 if (nbPulse == 10)
592 {
593 gsmefrFlag = 1;
594 }
595 else
596 {
597 gsmefrFlag = 0;
598 }
599
600 /* fix i0 on maximum of correlation position */
601 i0 = pos_max[ipos[0]];
602 index[0] = i0;
603 /*------------------------------------------------------------------*
604 * i1 loop: *
605 *------------------------------------------------------------------*/
606
607 /* Default value */
608 psk = -1;
609 alpk = 1;
610 for (i = 0; i < nbPulse; i++)
611 {
612 *(p_codvec++) = i;
613 }
614
615 for (i = 1; i < nbTracks; i++)
616 {
617 i1 = pos_max[ipos[1]];
618 index[1] = i1;
619
620 /* ps0 = add (dn[i0], dn[i1], pOverflow);*/
621 ps0 = (Word16)((Word32) dn[i0] + dn[i1]);
622
623 /* alp0 = L_mult (rr[i0][i0], _1_16, pOverflow); */
624 alp0 = (Word32) rr[i0][i0] << 12;
625
626 /* alp0 = L_mac (alp0, rr[i1][i1], _1_16, pOverflow); */
627 alp0 += (Word32) rr[i1][i1] << 12;
628
629 /* alp0 = L_mac (alp0, rr[i0][i1], _1_8, pOverflow); */
630 alp0 += (Word32) rr[i0][i1] << 13;
631 alp0 += 0x00008000L;
632
633 /*----------------------------------------------------------------*
634 * i2 and i3 loop: *
635 *----------------------------------------------------------------*/
636
637 p_temp1 = temp1;
638 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
639 {
640 p_temp2 = &rr[i3][0];
641 s = (Word32) * (p_temp2 + i3) >> 1;
642 s += (Word32) * (p_temp2 + i0);
643 s += (Word32) * (p_temp2 + i1);
644 *(p_temp1++) = ps0 + dn[i3];
645 *(p_temp1++) = (Word16)((s + 2) >> 2);
646 }
647
648 /* Default value */
649 sq = -1;
650 alp = 1;
651 ps = 0;
652 ia = ipos[2];
653 ib = ipos[3];
654
655 s = (alp0 >> 12);
656
657 for (j = ipos[2]; j < L_CODE; j += step)
658 {
659 /* index increment = step */
660 p_temp2 = &rr[j][0];
661
662 alp1 = (s + (Word32) * (p_temp2 + j)) >> 1;
663
664 alp1 += (Word32) * (p_temp2 + i0);
665
666 alp1 += (Word32) * (p_temp2 + i1);
667
668 p_temp1 = temp1;
669 ps1 = dn[j];
670
671
672 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
673 {
674 /* index increment = step */
675 ps2 = ps1 + *(p_temp1++);
676
677 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
678
679 alp2 = (alp1 + p_temp2[i3]) >> 2;
680 alp2 = (alp2 + *(p_temp1++)) >> 1; /* alp2 is always > 0 */
681 if (((Word32) sq2 * alp) > ((Word32) sq * alp2))
682 {
683 sq = sq2;
684 ps = ps2;
685 alp = (Word16)alp2;
686 ia = j;
687 ib = i3;
688 }
689 }
690
691 }
692 i2 = ia;
693 i3 = ib;
694 index[2] = ia;
695 index[3] = ib;
696
697 /*----------------------------------------------------------------*
698 * i4 and i5 loop: *
699 *----------------------------------------------------------------*/
700
701 alp0 = ((Word32) alp << 15) + 0x00008000L;
702 p_temp1 = temp1;
703
704 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
705 {
706 p_temp2 = &rr[i5][0];
707 s = (Word32) * (p_temp2 + i5) >> 1;
708 s += (Word32) * (p_temp2 + i0);
709 s += (Word32) * (p_temp2 + i1);
710 s += (Word32) * (p_temp2 + i2);
711 s += (Word32) * (p_temp2 + i3);
712
713 *(p_temp1++) = ps + dn[i5];
714 *(p_temp1++) = (Word16)((s + 2) >> 2);
715 }
716
717 /* Default value */
718 sq = -1;
719 alp = 1;
720 ps = 0;
721 ia = ipos[4];
722 ib = ipos[5];
723
724 for (j = ipos[4]; j < L_CODE; j += step)
725 {
726 /* ps1 = add (ps0, dn[i4], pOverflow); */
727 p_temp2 = &rr[j][0];
728
729 /* alp1 = L_mac (alp0, rr[i4][i4], _1_32, pOverflow); */
730 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 11);
731
732 /* alp1 = L_mac (alp1, rr[i0][i4], _1_16, pOverflow); */
733 alp1 += (Word32) * (p_temp2 + i0) << 12;
734
735 /* alp1 = L_mac (alp1, rr[i1][i4], _1_16, pOverflow); */
736 alp1 += (Word32) * (p_temp2 + i1) << 12;
737
738 /* alp1 = L_mac (alp1, rr[i2][i4], _1_16, pOverflow); */
739 alp1 += (Word32) * (p_temp2 + i2) << 12;
740
741 /* alp1 = L_mac (alp1, rr[i3][i4], _1_16, pOverflow); */
742 alp1 += (Word32) * (p_temp2 + i3) << 12;
743
744 p_temp1 = temp1;
745 ps1 = dn[j];
746
747 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
748 {
749 ps2 = ps1 + *(p_temp1++);
750
751 alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12);
752
753 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
754 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
755
756 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
757 {
758 sq = sq2;
759 ps = ps2;
760 alp = alp_16;
761 ia = j;
762 ib = i5;
763 }
764
765 }
766 }
767 i4 = ia;
768 i5 = ib;
769 index[4] = ia;
770 index[5] = ib;
771
772 /*----------------------------------------------------------------*
773 * i6 and i7 loop: *
774 *----------------------------------------------------------------*/
775
776 alp0 = ((Word32) alp << 15) + 0x00008000L;
777
778 p_temp1 = temp1;
779
780 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
781 {
782 s = (Word32) rr[i7][i7] >> 1;
783 s += (Word32) rr[i0][i7];
784 s += (Word32) rr[i1][i7];
785 s += (Word32) rr[i2][i7];
786 s += (Word32) rr[i3][i7];
787 s += (Word32) rr[i4][i7];
788 s += (Word32) rr[i5][i7];
789 *(p_temp1++) = ps + dn[i7];
790 *(p_temp1++) = (Word16)((s + 4) >> 3);
791 }
792
793
794 /* Default value */
795 sq = -1;
796 alp = 1;
797 ps = 0;
798 ia = ipos[6];
799 ib = ipos[7];
800
801 for (j = ipos[6]; j < L_CODE; j += step)
802 {
803 /* ps1 = add (ps0, dn[i6], pOverflow); */
804
805 p_temp2 = (Word16 *) & rr[j];
806
807 /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */
808 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10);
809
810 /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */
811 alp1 += (Word32) * (p_temp2 + i0) << 11;
812
813
814 /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */
815 alp1 += (Word32) * (p_temp2 + i1) << 11;
816
817 /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */
818 alp1 += (Word32) * (p_temp2 + i2) << 11;
819
820 /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */
821 alp1 += (Word32) * (p_temp2 + i3) << 11;
822
823 /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */
824 alp1 += (Word32) * (p_temp2 + i4) << 11;
825
826 /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */
827 alp1 += (Word32) * (p_temp2 + i5) << 11;
828
829 p_temp1 = temp1;
830 ps1 = dn[j];
831
832 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
833 {
834 ps2 = ps1 + *(p_temp1++);
835
836 alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11);
837
838 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
839
840 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
841
842 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
843 {
844 sq = sq2;
845 ps = ps2;
846 alp = alp_16;
847 ia = j;
848 ib = i7;
849 }
850 }
851 }
852
853 i6 = ia;
854 i7 = ib;
855 index[6] = ia;
856 index[7] = ib;
857
858 /* now finished searching a set of 8 pulses */
859
860 if (gsmefrFlag != 0)
861 {
862 /* go on with the two last pulses for GSMEFR */
863 /*----------------------------------------------------------------*
864 * i8 and i9 loop: *
865 *----------------------------------------------------------------*/
866
867 alp0 = ((Word32) alp << 15) + 0x00008000L;
868
869 p_temp1 = temp1;
870
871 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
872 {
873 s = (Word32) rr[i9][i9] >> 1;
874 s += (Word32) rr[i0][i9];
875 s += (Word32) rr[i1][i9];
876 s += (Word32) rr[i2][i9];
877 s += (Word32) rr[i3][i9];
878 s += (Word32) rr[i4][i9];
879 s += (Word32) rr[i5][i9];
880 s += (Word32) rr[i6][i9];
881 s += (Word32) rr[i7][i9];
882
883 *(p_temp1++) = ps + dn[i9];
884 *(p_temp1++) = (Word16)((s + 4) >> 3);
885 }
886
887 /* Default value */
888 sq = -1;
889 alp = 1;
890 ps = 0;
891 ia = ipos[8];
892 ib = ipos[9];
893
894 for (j = ipos[8]; j < L_CODE; j += step)
895 {
896 /* ps1 = add (ps0, dn[i8], pOverflow); */
897 p_temp2 = &rr[j][0];
898
899 /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */
900 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9);
901
902 /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */
903 alp1 += (Word32) rr[i0][j] << 10;
904
905 /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */
906 alp1 += (Word32) rr[i1][j] << 10;
907
908 /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */
909 alp1 += (Word32) rr[i2][j] << 10;
910
911 /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */
912 alp1 += (Word32) rr[i3][j] << 10;
913
914 /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */
915 alp1 += (Word32) rr[i4][j] << 10;
916
917 /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */
918 alp1 += (Word32) rr[i5][j] << 10;
919
920 /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */
921 alp1 += (Word32) rr[i6][j] << 10;
922
923 /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */
924 alp1 += (Word32) rr[i7][j] << 10;
925
926 p_temp1 = temp1;
927 ps1 = dn[j];
928
929 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
930 {
931 /* ps2 = add (ps1, dn[i9], pOverflow); */
932 ps2 = ps1 + *(p_temp1++);
933
934 /* sq2 = mult (ps2, ps2, pOverflow); */
935 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
936
937 /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */
938 alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ;
939
940 /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */
941 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16);
942
943 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
944 {
945 sq = sq2;
946 ps = ps2;
947 alp = alp_16;
948 ia = j;
949 ib = i9;
950 }
951 }
952 }
953
954 index[8] = ia;
955 index[9] = ib;
956
957 }/* end gsmefrFlag */
958
959 /*---------------------------------------------------------------- *
960 * test and memorise if this combination is better than the last one.*
961 *----------------------------------------------------------------*/
962
963 if (((Word32) alpk * sq) > ((Word32) psk * alp))
964 {
965 psk = sq;
966 alpk = alp;
967
968 if (gsmefrFlag != 0)
969 {
970 memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index));
971 }
972 else
973 {
974 memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index));
975 }
976
977 }
978 /*----------------------------------------------------------------*
979 * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). *
980 *----------------------------------------------------------------*/
981
982 pos = ipos[1];
983 for (j = 1, k = 2; k < nbPulse; j++, k++)
984 {
985 ipos[j] = ipos[k];
986 }
987 ipos[nbPulse-1] = pos;
988 } /* end 1..nbTracks loop*/
989 }
990
991