s10_8pf.cpp revision b841f14f8e51f2365945281fbfa54ef6a1b1b5a6
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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
179void 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----------------------------------------------------------------------------*/
556void 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