• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "s10_8pf.h"
101 #include "cnst.h"
102 #include "oscl_mem.h"
103 
104 /*----------------------------------------------------------------------------
105 ; MACROS
106 ; Define module specific macros here
107 ----------------------------------------------------------------------------*/
108 
109 /*----------------------------------------------------------------------------
110 ; DEFINES
111 ; Include all pre-processor statements here. Include conditional
112 ; compile variables also.
113 ----------------------------------------------------------------------------*/
114 
115 /*----------------------------------------------------------------------------
116 ; LOCAL FUNCTION DEFINITIONS
117 ; Function Prototype declaration
118 ----------------------------------------------------------------------------*/
119 
120 /*----------------------------------------------------------------------------
121 ; LOCAL VARIABLE DEFINITIONS
122 ; Variable declaration - defined here and used outside this module
123 ----------------------------------------------------------------------------*/
124 
125 /*
126 ------------------------------------------------------------------------------
127  FUNCTION NAME: search_10and8i40
128 ------------------------------------------------------------------------------
129  INPUT AND OUTPUT DEFINITIONS
130 
131  Inputs:
132     nbPulse = nbPulses to find (Word16)
133     step = step size (Word16)
134     nbTracks = nbTracks (Word16)
135     dn[] = correlation between target and h[] (Word16)
136     rr[][] = matrix of autocorrelation (Word16)
137     ipos[] = starting position of each pulse (Word16)
138     pos_max[] = Position of maximum dn[] (Word16)
139     codvec[] = Algebraic codebook vector (Word16)
140     pOverflow = pointer to Overflow flag (Flag)
141 
142  Outputs:
143     codvec[] = Algebraic codebook vector (Word16)
144     pOverflow -> 1 if processing this funvction results in satuaration
145 
146  Returns:
147     None
148 
149  Global Variables Used:
150     None
151 
152  Local Variables Needed:
153     None
154 
155 ------------------------------------------------------------------------------
156  FUNCTION DESCRIPTION
157 
158  This function searches for the best codevector; It determines the positions
159  of the 10/8 pulses in the 40-sample frame.
160 
161     search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec);   for GSMEFR
162     search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec);   for 10.2
163 
164 
165 ------------------------------------------------------------------------------
166  REQUIREMENTS
167 
168  None
169 
170 ------------------------------------------------------------------------------
171  REFERENCES
172 
173  s10_8pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
174 
175 ------------------------------------------------------------------------------
176  PSEUDO-CODE
177 
178 void search_10and8i40 (
179     Word16 nbPulse,      // i : nbpulses to find
180     Word16 step,         // i :  stepsize
181     Word16 nbTracks,     // i :  nbTracks
182     Word16 dn[],         // i : correlation between target and h[]
183     Word16 rr[][L_CODE], // i : matrix of autocorrelation
184     Word16 ipos[],       // i : starting position for each pulse
185     Word16 pos_max[],    // i : position of maximum of dn[]
186     Word16 codvec[]      // o : algebraic codebook vector
187 )
188 {
189    Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
190    Word16 i, j, k, pos, ia, ib;
191    Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
192    Word16 alpk, alp, alp_16;
193    Word16 rrv[L_CODE];
194    Word32 s, alp0, alp1, alp2;
195    Word16 gsmefrFlag;
196 
197 
198    if (sub(nbPulse, 10) == 0)
199    {
200       gsmefrFlag=1;
201    }
202    else
203    {
204       gsmefrFlag=0;
205    }
206 
207    // fix i0 on maximum of correlation position
208    i0 = pos_max[ipos[0]];
209 
210    //
211    // i1 loop:                                                         *
212    //
213 
214    // Default value
215 
216    psk = -1;
217    alpk = 1;
218    for (i = 0; i < nbPulse; i++)
219    {
220       codvec[i] = i;
221    }
222 
223    for (i = 1; i < nbTracks; i++)
224    {
225       i1 = pos_max[ipos[1]];
226       ps0 = add (dn[i0], dn[i1]);
227       alp0 = L_mult (rr[i0][i0], _1_16);
228       alp0 = L_mac (alp0, rr[i1][i1], _1_16);
229       alp0 = L_mac (alp0, rr[i0][i1], _1_8);
230 
231       //
232       // i2 and i3 loop
233       //
234 
235       for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
236       {
237          s = L_mult (rr[i3][i3], _1_8);       // index incr= step+L_CODE
238          s = L_mac (s, rr[i0][i3], _1_4);     // index increment = step
239          s = L_mac (s, rr[i1][i3], _1_4);     // index increment = step
240          rrv[i3] = pv_round (s);
241       }
242 
243       // Default value
244       sq = -1;
245       alp = 1;
246       ps = 0;
247       ia = ipos[2];
248       ib = ipos[3];
249 
250       for (i2 = ipos[2]; i2 < L_CODE; i2 += step)
251       {
252          // index increment = step
253          ps1 = add (ps0, dn[i2]);
254 
255          // index incr= step+L_CODE
256          alp1 = L_mac (alp0, rr[i2][i2], _1_16);
257 
258          // index increment = step
259          alp1 = L_mac (alp1, rr[i0][i2], _1_8);
260 
261          // index increment = step
262          alp1 = L_mac (alp1, rr[i1][i2], _1_8);
263 
264          for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
265          {
266             // index increment = step
267             ps2 = add (ps1, dn[i3]);
268 
269             // index increment = step
270             alp2 = L_mac (alp1, rrv[i3], _1_2);
271 
272             // index increment = step
273             alp2 = L_mac (alp2, rr[i2][i3], _1_8);
274 
275             sq2 = mult (ps2, ps2);
276 
277             alp_16 = pv_round (alp2);
278 
279             s = L_msu (L_mult (alp, sq2), sq, alp_16);
280 
281             if (s > 0)
282             {
283                sq = sq2;
284                ps = ps2;
285                alp = alp_16;
286                ia = i2;
287                ib = i3;
288             }
289          }
290       }
291       i2 = ia;
292       i3 = ib;
293 
294         //
295         // i4 and i5 loop:
296         //
297 
298         ps0 = ps;
299         alp0 = L_mult (alp, _1_2);
300 
301         for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
302         {
303             s = L_mult (rr[i5][i5], _1_8);
304             s = L_mac (s, rr[i0][i5], _1_4);
305             s = L_mac (s, rr[i1][i5], _1_4);
306             s = L_mac (s, rr[i2][i5], _1_4);
307             s = L_mac (s, rr[i3][i5], _1_4);
308             rrv[i5] = pv_round (s);
309         }
310 
311         // Default value
312         sq = -1;
313         alp = 1;
314         ps = 0;
315         ia = ipos[4];
316         ib = ipos[5];
317 
318         for (i4 = ipos[4]; i4 < L_CODE; i4 += step)
319         {
320             ps1 = add (ps0, dn[i4]);
321 
322             alp1 = L_mac (alp0, rr[i4][i4], _1_32);
323             alp1 = L_mac (alp1, rr[i0][i4], _1_16);
324             alp1 = L_mac (alp1, rr[i1][i4], _1_16);
325             alp1 = L_mac (alp1, rr[i2][i4], _1_16);
326             alp1 = L_mac (alp1, rr[i3][i4], _1_16);
327 
328             for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
329             {
330                 ps2 = add (ps1, dn[i5]);
331 
332                 alp2 = L_mac (alp1, rrv[i5], _1_4);
333                 alp2 = L_mac (alp2, rr[i4][i5], _1_16);
334 
335                 sq2 = mult (ps2, ps2);
336 
337                 alp_16 = pv_round (alp2);
338 
339                 s = L_msu (L_mult (alp, sq2), sq, alp_16);
340 
341                 if (s > 0)
342                 {
343                     sq = sq2;
344                     ps = ps2;
345                     alp = alp_16;
346                     ia = i4;
347                     ib = i5;
348                 }
349             }
350         }
351         i4 = ia;
352         i5 = ib;
353 
354         //
355         // i6 and i7 loop:
356         //
357 
358         ps0 = ps;
359         alp0 = L_mult (alp, _1_2);
360 
361         for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
362         {
363             s = L_mult (rr[i7][i7], _1_16);
364             s = L_mac (s, rr[i0][i7], _1_8);
365             s = L_mac (s, rr[i1][i7], _1_8);
366             s = L_mac (s, rr[i2][i7], _1_8);
367             s = L_mac (s, rr[i3][i7], _1_8);
368             s = L_mac (s, rr[i4][i7], _1_8);
369             s = L_mac (s, rr[i5][i7], _1_8);
370             rrv[i7] = pv_round (s);
371         }
372 
373         // Default value
374         sq = -1;
375         alp = 1;
376         ps = 0;
377         ia = ipos[6];
378         ib = ipos[7];
379 
380         for (i6 = ipos[6]; i6 < L_CODE; i6 += step)
381         {
382             ps1 = add (ps0, dn[i6]);
383 
384             alp1 = L_mac (alp0, rr[i6][i6], _1_64);
385             alp1 = L_mac (alp1, rr[i0][i6], _1_32);
386             alp1 = L_mac (alp1, rr[i1][i6], _1_32);
387             alp1 = L_mac (alp1, rr[i2][i6], _1_32);
388             alp1 = L_mac (alp1, rr[i3][i6], _1_32);
389             alp1 = L_mac (alp1, rr[i4][i6], _1_32);
390             alp1 = L_mac (alp1, rr[i5][i6], _1_32);
391 
392             for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
393             {
394                 ps2 = add (ps1, dn[i7]);
395 
396                 alp2 = L_mac (alp1, rrv[i7], _1_4);
397                 alp2 = L_mac (alp2, rr[i6][i7], _1_32);
398 
399                 sq2 = mult (ps2, ps2);
400 
401                 alp_16 = pv_round (alp2);
402 
403                 s = L_msu (L_mult (alp, sq2), sq, alp_16);
404 
405                 if (s > 0)
406                 {
407                     sq = sq2;
408                     ps = ps2;
409                     alp = alp_16;
410                     ia = i6;
411                     ib = i7;
412                 }
413             }
414         }
415         i6 = ia;
416         i7 = ib;
417 
418         // now finished searching a set of 8 pulses
419 
420         if(gsmefrFlag != 0){
421            // go on with the two last pulses for GSMEFR
422            //
423            // i8 and i9 loop:
424            //
425 
426            ps0 = ps;
427            alp0 = L_mult (alp, _1_2);
428 
429            for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
430            {
431               s = L_mult (rr[i9][i9], _1_16);
432               s = L_mac (s, rr[i0][i9], _1_8);
433               s = L_mac (s, rr[i1][i9], _1_8);
434               s = L_mac (s, rr[i2][i9], _1_8);
435               s = L_mac (s, rr[i3][i9], _1_8);
436               s = L_mac (s, rr[i4][i9], _1_8);
437               s = L_mac (s, rr[i5][i9], _1_8);
438               s = L_mac (s, rr[i6][i9], _1_8);
439               s = L_mac (s, rr[i7][i9], _1_8);
440               rrv[i9] = pv_round (s);
441            }
442 
443            // Default value
444            sq = -1;
445            alp = 1;
446            ps = 0;
447            ia = ipos[8];
448            ib = ipos[9];
449 
450            for (i8 = ipos[8]; i8 < L_CODE; i8 += step)
451            {
452               ps1 = add (ps0, dn[i8]);
453 
454               alp1 = L_mac (alp0, rr[i8][i8], _1_128);
455               alp1 = L_mac (alp1, rr[i0][i8], _1_64);
456               alp1 = L_mac (alp1, rr[i1][i8], _1_64);
457               alp1 = L_mac (alp1, rr[i2][i8], _1_64);
458               alp1 = L_mac (alp1, rr[i3][i8], _1_64);
459               alp1 = L_mac (alp1, rr[i4][i8], _1_64);
460               alp1 = L_mac (alp1, rr[i5][i8], _1_64);
461               alp1 = L_mac (alp1, rr[i6][i8], _1_64);
462               alp1 = L_mac (alp1, rr[i7][i8], _1_64);
463 
464               for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
465               {
466                  ps2 = add (ps1, dn[i9]);
467 
468                  alp2 = L_mac (alp1, rrv[i9], _1_8);
469                  alp2 = L_mac (alp2, rr[i8][i9], _1_64);
470 
471                  sq2 = mult (ps2, ps2);
472 
473                  alp_16 = pv_round (alp2);
474 
475                  s = L_msu (L_mult (alp, sq2), sq, alp_16);
476 
477                  if (s > 0)
478                  {
479                     sq = sq2;
480                     ps = ps2;
481                     alp = alp_16;
482                     ia = i8;
483                     ib = i9;
484                  }
485               }
486            }
487         } // end  gsmefrFlag
488 
489         //
490         // test and memorise if this combination is better than the last one/
491         //
492 
493         s = L_msu (L_mult (alpk, sq), psk, alp);
494 
495         if (s > 0)
496         {
497             psk = sq;
498             alpk = alp;
499             codvec[0] = i0;
500             codvec[1] = i1;
501             codvec[2] = i2;
502             codvec[3] = i3;
503             codvec[4] = i4;
504             codvec[5] = i5;
505             codvec[6] = i6;
506             codvec[7] = i7;
507 
508             if (gsmefrFlag != 0)
509             {
510                codvec[8] = ia;
511                codvec[9] = ib;
512             }
513         }
514 
515         //
516         // Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9)/
517         //
518 
519         pos = ipos[1];
520         for (j = 1, k = 2; k < nbPulse; j++, k++)
521         {
522             ipos[j] = ipos[k];
523         }
524         ipos[sub(nbPulse,1)] = pos;
525    } // end 1..nbTracks  loop
526 }
527 
528 ------------------------------------------------------------------------------
529  RESOURCES USED [optional]
530 
531  When the code is written for a specific target processor the
532  the resources used should be documented below.
533 
534  HEAP MEMORY USED: x bytes
535 
536  STACK MEMORY USED: x bytes
537 
538  CLOCK CYCLES: (cycle count equation for this function) + (variable
539                 used to represent cycle count for each subroutine
540                 called)
541      where: (cycle count variable) = cycle count for [subroutine
542                                      name]
543 
544 ------------------------------------------------------------------------------
545  CAUTION [optional]
546  [State any special notes, constraints or cautions for users of this function]
547 
548 ------------------------------------------------------------------------------
549 */
550 
551 
552 /*----------------------------------------------------------------------------
553 ; FUNCTION CODE
554 ----------------------------------------------------------------------------*/
search_10and8i40(Word16 nbPulse,Word16 step,Word16 nbTracks,Word16 dn[],Word16 rr[][L_CODE],Word16 ipos[],Word16 pos_max[],Word16 codvec[],Flag * pOverflow)555 void search_10and8i40(
556     Word16 nbPulse,      /* i : nbpulses to find                       */
557     Word16 step,         /* i : stepsize                               */
558     Word16 nbTracks,     /* i : nbTracks                               */
559     Word16 dn[],         /* i : correlation between target and h[]     */
560     Word16 rr[][L_CODE], /* i : matrix of autocorrelation              */
561     Word16 ipos[],       /* i : starting position for each pulse       */
562     Word16 pos_max[],    /* i : position of maximum of dn[]            */
563     Word16 codvec[],     /* o : algebraic codebook vector              */
564     Flag   *pOverflow    /* i/o : overflow flag                        */
565 )
566 {
567     Word16 i0, i1, i2, i3, i4, i5, i6, i7, i9;
568     Word16 i, j, k/*, m*/;
569     Word16 pos, ia, ib;
570     Word16 psk;
571     Word16 sq, sq2;
572     Word16 alpk, alp, alp_16;
573     Word32 s;
574     Word32 alp0, alp1, alp2;
575     Word16 gsmefrFlag;
576     Word16 *p_codvec = codvec;
577     Word16  *p_temp2;
578 
579     Word16  temp1[2*L_CODE];
580     Word16  *p_temp1;
581     Word16  ps2;
582     Word16  ps1;
583     Word16  ps;
584     Word16 ps0;
585 
586     Word16  index[10];
587 
588     OSCL_UNUSED_ARG(pOverflow);
589 
590     if (nbPulse == 10)
591     {
592         gsmefrFlag = 1;
593     }
594     else
595     {
596         gsmefrFlag = 0;
597     }
598 
599     /* fix i0 on maximum of correlation position */
600     i0 = pos_max[ipos[0]];
601     index[0] = i0;
602     /*------------------------------------------------------------------*
603     * i1 loop:                                                         *
604     *------------------------------------------------------------------*/
605 
606     /* Default value */
607     psk = -1;
608     alpk = 1;
609     for (i = 0; i < nbPulse; i++)
610     {
611         *(p_codvec++) = i;
612     }
613 
614     for (i = 1; i < nbTracks; i++)
615     {
616         i1 = pos_max[ipos[1]];
617         index[1] = i1;
618 
619         /* ps0 = add (dn[i0], dn[i1], pOverflow);*/
620         ps0 = (Word16)((Word32) dn[i0] + dn[i1]);
621 
622         /* alp0 = L_mult (rr[i0][i0], _1_16, pOverflow); */
623         alp0 = (Word32) rr[i0][i0] << 12;
624 
625         /* alp0 = L_mac (alp0, rr[i1][i1], _1_16, pOverflow); */
626         alp0 += (Word32) rr[i1][i1] << 12;
627 
628         /* alp0 = L_mac (alp0, rr[i0][i1], _1_8, pOverflow); */
629         alp0 += (Word32) rr[i0][i1] << 13;
630         alp0 += 0x00008000L;
631 
632         /*----------------------------------------------------------------*
633         * i2 and i3 loop:                                                *
634         *----------------------------------------------------------------*/
635 
636         p_temp1 = temp1;
637         for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
638         {
639             p_temp2 = &rr[i3][0];
640             s  = (Word32) * (p_temp2 + i3) >> 1;
641             s += (Word32) * (p_temp2 + i0);
642             s += (Word32) * (p_temp2 + i1);
643             *(p_temp1++) = ps0 + dn[i3];
644             *(p_temp1++) = (Word16)((s + 2) >> 2);
645         }
646 
647         /* Default value */
648         sq = -1;
649         alp = 1;
650         ps = 0;
651         ia = ipos[2];
652         ib = ipos[3];
653 
654         s = (alp0 >> 12);
655 
656         for (j = ipos[2]; j < L_CODE; j += step)
657         {
658             /* index increment = step  */
659             p_temp2 = &rr[j][0];
660 
661             alp1 = (s + (Word32) * (p_temp2 + j)) >> 1;
662 
663             alp1 += (Word32) * (p_temp2 + i0);
664 
665             alp1 += (Word32) * (p_temp2 + i1);
666 
667             p_temp1 = temp1;
668             ps1 = dn[j];
669 
670 
671             for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
672             {
673                 /* index increment = step */
674                 ps2 = ps1 + *(p_temp1++);
675 
676                 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
677 
678                 alp2 = (alp1 + p_temp2[i3]) >> 2;
679                 alp2 = (alp2 + *(p_temp1++)) >> 1;  /*  alp2 is always > 0  */
680                 if (((Word32) sq2 * alp) > ((Word32) sq * alp2))
681                 {
682                     sq = sq2;
683                     ps = ps2;
684                     alp = (Word16)alp2;
685                     ia = j;
686                     ib = i3;
687                 }
688             }
689 
690         }
691         i2 = ia;
692         i3 = ib;
693         index[2] = ia;
694         index[3] = ib;
695 
696         /*----------------------------------------------------------------*
697         * i4 and i5 loop:                                                *
698         *----------------------------------------------------------------*/
699 
700         alp0 = ((Word32) alp << 15) + 0x00008000L;
701         p_temp1 = temp1;
702 
703         for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
704         {
705             p_temp2 = &rr[i5][0];
706             s = (Word32) * (p_temp2 + i5) >> 1;
707             s += (Word32) * (p_temp2 + i0);
708             s += (Word32) * (p_temp2 + i1);
709             s += (Word32) * (p_temp2 + i2);
710             s += (Word32) * (p_temp2 + i3);
711 
712             *(p_temp1++) = ps + dn[i5];
713             *(p_temp1++) = (Word16)((s + 2) >> 2);
714         }
715 
716         /* Default value */
717         sq = -1;
718         alp = 1;
719         ps = 0;
720         ia = ipos[4];
721         ib = ipos[5];
722 
723         for (j = ipos[4]; j < L_CODE; j += step)
724         {
725             /* ps1 = add (ps0, dn[i4], pOverflow); */
726             p_temp2 = &rr[j][0];
727 
728             /* alp1 = L_mac (alp0, rr[i4][i4], _1_32, pOverflow); */
729             alp1 = alp0 + ((Word32) * (p_temp2 + j) << 11);
730 
731             /* alp1 = L_mac (alp1, rr[i0][i4], _1_16, pOverflow); */
732             alp1 += (Word32) * (p_temp2 + i0) << 12;
733 
734             /* alp1 = L_mac (alp1, rr[i1][i4], _1_16, pOverflow); */
735             alp1 += (Word32) * (p_temp2 + i1) << 12;
736 
737             /* alp1 = L_mac (alp1, rr[i2][i4], _1_16, pOverflow); */
738             alp1 += (Word32) * (p_temp2 + i2) << 12;
739 
740             /* alp1 = L_mac (alp1, rr[i3][i4], _1_16, pOverflow); */
741             alp1 += (Word32) * (p_temp2 + i3) << 12;
742 
743             p_temp1 = temp1;
744             ps1 =  dn[j];
745 
746             for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
747             {
748                 ps2 = ps1 + *(p_temp1++);
749 
750                 alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12);
751 
752                 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
753                 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
754 
755                 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
756                 {
757                     sq = sq2;
758                     ps = ps2;
759                     alp = alp_16;
760                     ia = j;
761                     ib = i5;
762                 }
763 
764             }
765         }
766         i4 = ia;
767         i5 = ib;
768         index[4] = ia;
769         index[5] = ib;
770 
771         /*----------------------------------------------------------------*
772         * i6 and i7 loop:                                                *
773         *----------------------------------------------------------------*/
774 
775         alp0 = ((Word32) alp << 15) + 0x00008000L;
776 
777         p_temp1 = temp1;
778 
779         for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
780         {
781             s = (Word32) rr[i7][i7] >> 1;
782             s += (Word32) rr[i0][i7];
783             s += (Word32) rr[i1][i7];
784             s += (Word32) rr[i2][i7];
785             s += (Word32) rr[i3][i7];
786             s += (Word32) rr[i4][i7];
787             s += (Word32) rr[i5][i7];
788             *(p_temp1++) = ps + dn[i7];
789             *(p_temp1++) = (Word16)((s + 4) >> 3);
790         }
791 
792 
793         /* Default value */
794         sq = -1;
795         alp = 1;
796         ps = 0;
797         ia = ipos[6];
798         ib = ipos[7];
799 
800         for (j = ipos[6]; j < L_CODE; j += step)
801         {
802             /* ps1 = add (ps0, dn[i6], pOverflow); */
803 
804             p_temp2 = (Word16 *) & rr[j];
805 
806             /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */
807             alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10);
808 
809             /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */
810             alp1 += (Word32) * (p_temp2 + i0) << 11;
811 
812 
813             /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */
814             alp1 += (Word32) * (p_temp2 + i1) << 11;
815 
816             /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */
817             alp1 += (Word32) * (p_temp2 + i2) << 11;
818 
819             /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */
820             alp1 += (Word32) * (p_temp2 + i3) << 11;
821 
822             /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */
823             alp1 += (Word32) * (p_temp2 + i4) << 11;
824 
825             /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */
826             alp1 += (Word32) * (p_temp2 + i5) << 11;
827 
828             p_temp1 = temp1;
829             ps1 = dn[j];
830 
831             for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
832             {
833                 ps2 = ps1 + *(p_temp1++);
834 
835                 alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11);
836 
837                 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
838 
839                 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
840 
841                 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
842                 {
843                     sq = sq2;
844                     ps = ps2;
845                     alp = alp_16;
846                     ia = j;
847                     ib = i7;
848                 }
849             }
850         }
851 
852         i6 = ia;
853         i7 = ib;
854         index[6] = ia;
855         index[7] = ib;
856 
857         /* now finished searching a set of 8 pulses */
858 
859         if (gsmefrFlag != 0)
860         {
861             /* go on with the two last pulses for GSMEFR                      */
862             /*----------------------------------------------------------------*
863             * i8 and i9 loop:                                                *
864             *----------------------------------------------------------------*/
865 
866             alp0 = ((Word32) alp << 15) + 0x00008000L;
867 
868             p_temp1 = temp1;
869 
870             for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
871             {
872                 s = (Word32) rr[i9][i9] >> 1;
873                 s += (Word32) rr[i0][i9];
874                 s += (Word32) rr[i1][i9];
875                 s += (Word32) rr[i2][i9];
876                 s += (Word32) rr[i3][i9];
877                 s += (Word32) rr[i4][i9];
878                 s += (Word32) rr[i5][i9];
879                 s += (Word32) rr[i6][i9];
880                 s += (Word32) rr[i7][i9];
881 
882                 *(p_temp1++) = ps + dn[i9];
883                 *(p_temp1++) = (Word16)((s + 4) >> 3);
884             }
885 
886             /* Default value */
887             sq = -1;
888             alp = 1;
889             ps = 0;
890             ia = ipos[8];
891             ib = ipos[9];
892 
893             for (j = ipos[8]; j < L_CODE; j += step)
894             {
895                 /* ps1 = add (ps0, dn[i8], pOverflow); */
896                 p_temp2 = &rr[j][0];
897 
898                 /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */
899                 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9);
900 
901                 /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */
902                 alp1 += (Word32) rr[i0][j] << 10;
903 
904                 /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */
905                 alp1 += (Word32) rr[i1][j] << 10;
906 
907                 /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */
908                 alp1 += (Word32) rr[i2][j] << 10;
909 
910                 /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */
911                 alp1 += (Word32) rr[i3][j] << 10;
912 
913                 /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */
914                 alp1 += (Word32) rr[i4][j] << 10;
915 
916                 /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */
917                 alp1 += (Word32) rr[i5][j] << 10;
918 
919                 /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */
920                 alp1 += (Word32) rr[i6][j] << 10;
921 
922                 /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */
923                 alp1 += (Word32) rr[i7][j] << 10;
924 
925                 p_temp1 = temp1;
926                 ps1 = dn[j];
927 
928                 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
929                 {
930                     /* ps2 = add (ps1, dn[i9], pOverflow); */
931                     ps2 = ps1 + *(p_temp1++);
932 
933                     /* sq2 = mult (ps2, ps2, pOverflow); */
934                     sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
935 
936                     /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */
937                     alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ;
938 
939                     /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */
940                     alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16);
941 
942                     if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
943                     {
944                         sq = sq2;
945                         ps = ps2;
946                         alp = alp_16;
947                         ia = j;
948                         ib = i9;
949                     }
950                 }
951             }
952 
953             index[8] = ia;
954             index[9] = ib;
955 
956         }/* end  gsmefrFlag */
957 
958         /*----------------------------------------------------------------  *
959          * test and memorise if this combination is better than the last one.*
960          *----------------------------------------------------------------*/
961 
962         if (((Word32) alpk * sq) > ((Word32) psk * alp))
963         {
964             psk = sq;
965             alpk = alp;
966 
967             if (gsmefrFlag != 0)
968             {
969                 oscl_memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index));
970             }
971             else
972             {
973                 oscl_memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index));
974             }
975 
976         }
977         /*----------------------------------------------------------------*
978         * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9).          *
979         *----------------------------------------------------------------*/
980 
981         pos = ipos[1];
982         for (j = 1, k = 2; k < nbPulse; j++, k++)
983         {
984             ipos[j] = ipos[k];
985         }
986         ipos[nbPulse-1] = pos;
987     } /* end 1..nbTracks  loop*/
988 }
989 
990