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 __builtin_add_overflow(ps1, *(p_temp1++), &ps2);
750
751 __builtin_add_overflow(alp1, *(p_temp2 + i5) << 12, &alp2);
752
753 Word32 result;
754 __builtin_add_overflow(alp2, *(p_temp1++) << 14, &result);
755 alp_16 = (Word16)(result >> 16);
756 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
757
758 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
759 {
760 sq = sq2;
761 ps = ps2;
762 alp = alp_16;
763 ia = j;
764 ib = i5;
765 }
766
767 }
768 }
769 i4 = ia;
770 i5 = ib;
771 index[4] = ia;
772 index[5] = ib;
773
774 /*----------------------------------------------------------------*
775 * i6 and i7 loop: *
776 *----------------------------------------------------------------*/
777
778 alp0 = ((Word32) alp << 15) + 0x00008000L;
779
780 p_temp1 = temp1;
781
782 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
783 {
784 s = (Word32) rr[i7][i7] >> 1;
785 s += (Word32) rr[i0][i7];
786 s += (Word32) rr[i1][i7];
787 s += (Word32) rr[i2][i7];
788 s += (Word32) rr[i3][i7];
789 s += (Word32) rr[i4][i7];
790 s += (Word32) rr[i5][i7];
791 *(p_temp1++) = ps + dn[i7];
792 *(p_temp1++) = (Word16)((s + 4) >> 3);
793 }
794
795
796 /* Default value */
797 sq = -1;
798 alp = 1;
799 ps = 0;
800 ia = ipos[6];
801 ib = ipos[7];
802
803 for (j = ipos[6]; j < L_CODE; j += step)
804 {
805 /* ps1 = add (ps0, dn[i6], pOverflow); */
806
807 p_temp2 = (Word16 *) & rr[j];
808
809 /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */
810 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10);
811
812 /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */
813 alp1 += (Word32) * (p_temp2 + i0) << 11;
814
815
816 /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */
817 alp1 += (Word32) * (p_temp2 + i1) << 11;
818
819 /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */
820 alp1 += (Word32) * (p_temp2 + i2) << 11;
821
822 /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */
823 alp1 += (Word32) * (p_temp2 + i3) << 11;
824
825 /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */
826 alp1 += (Word32) * (p_temp2 + i4) << 11;
827
828 /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */
829 alp1 += (Word32) * (p_temp2 + i5) << 11;
830
831 p_temp1 = temp1;
832 ps1 = dn[j];
833
834 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
835 {
836 ps2 = ps1 + *(p_temp1++);
837
838 alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11);
839
840 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
841
842 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
843
844 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
845 {
846 sq = sq2;
847 ps = ps2;
848 alp = alp_16;
849 ia = j;
850 ib = i7;
851 }
852 }
853 }
854
855 i6 = ia;
856 i7 = ib;
857 index[6] = ia;
858 index[7] = ib;
859
860 /* now finished searching a set of 8 pulses */
861
862 if (gsmefrFlag != 0)
863 {
864 /* go on with the two last pulses for GSMEFR */
865 /*----------------------------------------------------------------*
866 * i8 and i9 loop: *
867 *----------------------------------------------------------------*/
868
869 alp0 = ((Word32) alp << 15) + 0x00008000L;
870
871 p_temp1 = temp1;
872
873 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
874 {
875 s = (Word32) rr[i9][i9] >> 1;
876 s += (Word32) rr[i0][i9];
877 s += (Word32) rr[i1][i9];
878 s += (Word32) rr[i2][i9];
879 s += (Word32) rr[i3][i9];
880 s += (Word32) rr[i4][i9];
881 s += (Word32) rr[i5][i9];
882 s += (Word32) rr[i6][i9];
883 s += (Word32) rr[i7][i9];
884
885 *(p_temp1++) = ps + dn[i9];
886 *(p_temp1++) = (Word16)((s + 4) >> 3);
887 }
888
889 /* Default value */
890 sq = -1;
891 alp = 1;
892 ps = 0;
893 ia = ipos[8];
894 ib = ipos[9];
895
896 for (j = ipos[8]; j < L_CODE; j += step)
897 {
898 /* ps1 = add (ps0, dn[i8], pOverflow); */
899 p_temp2 = &rr[j][0];
900
901 /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */
902 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9);
903
904 /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */
905 alp1 += (Word32) rr[i0][j] << 10;
906
907 /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */
908 alp1 += (Word32) rr[i1][j] << 10;
909
910 /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */
911 alp1 += (Word32) rr[i2][j] << 10;
912
913 /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */
914 alp1 += (Word32) rr[i3][j] << 10;
915
916 /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */
917 alp1 += (Word32) rr[i4][j] << 10;
918
919 /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */
920 alp1 += (Word32) rr[i5][j] << 10;
921
922 /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */
923 alp1 += (Word32) rr[i6][j] << 10;
924
925 /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */
926 alp1 += (Word32) rr[i7][j] << 10;
927
928 p_temp1 = temp1;
929 ps1 = dn[j];
930
931 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
932 {
933 /* ps2 = add (ps1, dn[i9], pOverflow); */
934 ps2 = ps1 + *(p_temp1++);
935
936 /* sq2 = mult (ps2, ps2, pOverflow); */
937 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
938
939 /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */
940 alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ;
941
942 /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */
943 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16);
944
945 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
946 {
947 sq = sq2;
948 ps = ps2;
949 alp = alp_16;
950 ia = j;
951 ib = i9;
952 }
953 }
954 }
955
956 index[8] = ia;
957 index[9] = ib;
958
959 }/* end gsmefrFlag */
960
961 /*---------------------------------------------------------------- *
962 * test and memorise if this combination is better than the last one.*
963 *----------------------------------------------------------------*/
964
965 if (((Word32) alpk * sq) > ((Word32) psk * alp))
966 {
967 psk = sq;
968 alpk = alp;
969
970 if (gsmefrFlag != 0)
971 {
972 memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index));
973 }
974 else
975 {
976 memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index));
977 }
978
979 }
980 /*----------------------------------------------------------------*
981 * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). *
982 *----------------------------------------------------------------*/
983
984 pos = ipos[1];
985 for (j = 1, k = 2; k < nbPulse; j++, k++)
986 {
987 ipos[j] = ipos[k];
988 }
989 ipos[nbPulse-1] = pos;
990 } /* end 1..nbTracks loop*/
991 }
992
993