• 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 <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