summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp')
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp990
1 files changed, 990 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp b/media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp
new file mode 100644
index 0000000..352b611
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/src/s10_8pf.cpp
@@ -0,0 +1,990 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+/****************************************************************************************
+Portions of this file are derived from the following 3GPP standard:
+
+ 3GPP TS 26.073
+ ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
+ Available from http://www.3gpp.org
+
+(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
+Permission to distribute, modify and use this file under the standard license
+terms listed above has been obtained from the copyright holder.
+****************************************************************************************/
+/*
+------------------------------------------------------------------------------
+
+
+
+ Pathname: ./audio/gsm-amr/c/src/s10_8pf.c
+ Funtions: search_10and8i40
+
+ Date: 04/18/2000
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Adding pOverflow to the functions to remove global variables.
+ These changes are needed for the EPOC releases. Cleaned up code.
+ Updated template.
+
+ Description: Changed temp to temp32. When temp was only 16 bits it was not
+ holding the 32 bit value returned from the functions. Some
+ variables were also being declared as Word16 rather than Word32
+ as they were suposed to be.
+
+ Description: Changed copyright year. Removed all calls to math functions by
+ inlining them, and removed all unnecessary files in the Include
+ section.
+
+ Description: Made the following changes per comments from Phase 2/3 review:
+ 1. Removed all #defines.
+ 2. Used a pointer to &codvec[0] instead of array indexing.
+ 3. Removed multiple data casting in the code.
+
+ Description:
+ 1. Eliminated unused include files.
+ 2. Replaced array addressing by pointers, this by taking
+ advantage of the fact that the autocrrelation matrix is
+ a toeplitz matrix, so r[i][j] = r[j][i], then a single
+ pointer can be used to address a matrix. The use of this
+ is not uniform along the function (due to compiler limitations:
+ handling so many variables in this file) so the use
+ of this is pointer optimizations is limited to places
+ where the ARM compiler provides the lesses numer of cycles
+ 3. Eliminated use of intermediate variables to accelerate
+ comparisons (like in the nested loops)
+ 4. Introduced array temp1[], to pre-calculate the elements
+ used in the nested loops, in this way the calculation is
+ not repeated in every loop iteration. This is done for
+ loops i3-i5-i7 and i9
+ 5. Use array Index[] to store indexes i1:i9, and then use memcpy
+ to update indexes.
+ 6. Eliminated shifts by modifying the way number are rounded,
+ this does not have any effect in ARM processors but may help
+ other compilers
+
+ Description:
+ 1. When storing indexes, added memcpy() to support the rates
+ that use this function: 12.2 (already done) and 10.2 (missing).
+
+ Description: Replaced OSCL mem type functions and eliminated include
+ files that now are chosen by OSCL definitions
+
+ Description: Changed round function name to pv_round to avoid conflict with
+ round function in C standard library.
+
+ Description:
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include <string.h>
+
+#include "s10_8pf.h"
+#include "cnst.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL VARIABLE DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: search_10and8i40
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ nbPulse = nbPulses to find (Word16)
+ step = step size (Word16)
+ nbTracks = nbTracks (Word16)
+ dn[] = correlation between target and h[] (Word16)
+ rr[][] = matrix of autocorrelation (Word16)
+ ipos[] = starting position of each pulse (Word16)
+ pos_max[] = Position of maximum dn[] (Word16)
+ codvec[] = Algebraic codebook vector (Word16)
+ pOverflow = pointer to Overflow flag (Flag)
+
+ Outputs:
+ codvec[] = Algebraic codebook vector (Word16)
+ pOverflow -> 1 if processing this funvction results in satuaration
+
+ Returns:
+ None
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function searches for the best codevector; It determines the positions
+ of the 10/8 pulses in the 40-sample frame.
+
+ search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec); for GSMEFR
+ search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec); for 10.2
+
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ s10_8pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+void search_10and8i40 (
+ Word16 nbPulse, // i : nbpulses to find
+ Word16 step, // i : stepsize
+ Word16 nbTracks, // i : nbTracks
+ Word16 dn[], // i : correlation between target and h[]
+ Word16 rr[][L_CODE], // i : matrix of autocorrelation
+ Word16 ipos[], // i : starting position for each pulse
+ Word16 pos_max[], // i : position of maximum of dn[]
+ Word16 codvec[] // o : algebraic codebook vector
+)
+{
+ Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
+ Word16 i, j, k, pos, ia, ib;
+ Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
+ Word16 alpk, alp, alp_16;
+ Word16 rrv[L_CODE];
+ Word32 s, alp0, alp1, alp2;
+ Word16 gsmefrFlag;
+
+
+ if (sub(nbPulse, 10) == 0)
+ {
+ gsmefrFlag=1;
+ }
+ else
+ {
+ gsmefrFlag=0;
+ }
+
+ // fix i0 on maximum of correlation position
+ i0 = pos_max[ipos[0]];
+
+ //
+ // i1 loop: *
+ //
+
+ // Default value
+
+ psk = -1;
+ alpk = 1;
+ for (i = 0; i < nbPulse; i++)
+ {
+ codvec[i] = i;
+ }
+
+ for (i = 1; i < nbTracks; i++)
+ {
+ i1 = pos_max[ipos[1]];
+ ps0 = add (dn[i0], dn[i1]);
+ alp0 = L_mult (rr[i0][i0], _1_16);
+ alp0 = L_mac (alp0, rr[i1][i1], _1_16);
+ alp0 = L_mac (alp0, rr[i0][i1], _1_8);
+
+ //
+ // i2 and i3 loop
+ //
+
+ for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
+ {
+ s = L_mult (rr[i3][i3], _1_8); // index incr= step+L_CODE
+ s = L_mac (s, rr[i0][i3], _1_4); // index increment = step
+ s = L_mac (s, rr[i1][i3], _1_4); // index increment = step
+ rrv[i3] = pv_round (s);
+ }
+
+ // Default value
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[2];
+ ib = ipos[3];
+
+ for (i2 = ipos[2]; i2 < L_CODE; i2 += step)
+ {
+ // index increment = step
+ ps1 = add (ps0, dn[i2]);
+
+ // index incr= step+L_CODE
+ alp1 = L_mac (alp0, rr[i2][i2], _1_16);
+
+ // index increment = step
+ alp1 = L_mac (alp1, rr[i0][i2], _1_8);
+
+ // index increment = step
+ alp1 = L_mac (alp1, rr[i1][i2], _1_8);
+
+ for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
+ {
+ // index increment = step
+ ps2 = add (ps1, dn[i3]);
+
+ // index increment = step
+ alp2 = L_mac (alp1, rrv[i3], _1_2);
+
+ // index increment = step
+ alp2 = L_mac (alp2, rr[i2][i3], _1_8);
+
+ sq2 = mult (ps2, ps2);
+
+ alp_16 = pv_round (alp2);
+
+ s = L_msu (L_mult (alp, sq2), sq, alp_16);
+
+ if (s > 0)
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = alp_16;
+ ia = i2;
+ ib = i3;
+ }
+ }
+ }
+ i2 = ia;
+ i3 = ib;
+
+ //
+ // i4 and i5 loop:
+ //
+
+ ps0 = ps;
+ alp0 = L_mult (alp, _1_2);
+
+ for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
+ {
+ s = L_mult (rr[i5][i5], _1_8);
+ s = L_mac (s, rr[i0][i5], _1_4);
+ s = L_mac (s, rr[i1][i5], _1_4);
+ s = L_mac (s, rr[i2][i5], _1_4);
+ s = L_mac (s, rr[i3][i5], _1_4);
+ rrv[i5] = pv_round (s);
+ }
+
+ // Default value
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[4];
+ ib = ipos[5];
+
+ for (i4 = ipos[4]; i4 < L_CODE; i4 += step)
+ {
+ ps1 = add (ps0, dn[i4]);
+
+ alp1 = L_mac (alp0, rr[i4][i4], _1_32);
+ alp1 = L_mac (alp1, rr[i0][i4], _1_16);
+ alp1 = L_mac (alp1, rr[i1][i4], _1_16);
+ alp1 = L_mac (alp1, rr[i2][i4], _1_16);
+ alp1 = L_mac (alp1, rr[i3][i4], _1_16);
+
+ for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
+ {
+ ps2 = add (ps1, dn[i5]);
+
+ alp2 = L_mac (alp1, rrv[i5], _1_4);
+ alp2 = L_mac (alp2, rr[i4][i5], _1_16);
+
+ sq2 = mult (ps2, ps2);
+
+ alp_16 = pv_round (alp2);
+
+ s = L_msu (L_mult (alp, sq2), sq, alp_16);
+
+ if (s > 0)
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = alp_16;
+ ia = i4;
+ ib = i5;
+ }
+ }
+ }
+ i4 = ia;
+ i5 = ib;
+
+ //
+ // i6 and i7 loop:
+ //
+
+ ps0 = ps;
+ alp0 = L_mult (alp, _1_2);
+
+ for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
+ {
+ s = L_mult (rr[i7][i7], _1_16);
+ s = L_mac (s, rr[i0][i7], _1_8);
+ s = L_mac (s, rr[i1][i7], _1_8);
+ s = L_mac (s, rr[i2][i7], _1_8);
+ s = L_mac (s, rr[i3][i7], _1_8);
+ s = L_mac (s, rr[i4][i7], _1_8);
+ s = L_mac (s, rr[i5][i7], _1_8);
+ rrv[i7] = pv_round (s);
+ }
+
+ // Default value
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[6];
+ ib = ipos[7];
+
+ for (i6 = ipos[6]; i6 < L_CODE; i6 += step)
+ {
+ ps1 = add (ps0, dn[i6]);
+
+ alp1 = L_mac (alp0, rr[i6][i6], _1_64);
+ alp1 = L_mac (alp1, rr[i0][i6], _1_32);
+ alp1 = L_mac (alp1, rr[i1][i6], _1_32);
+ alp1 = L_mac (alp1, rr[i2][i6], _1_32);
+ alp1 = L_mac (alp1, rr[i3][i6], _1_32);
+ alp1 = L_mac (alp1, rr[i4][i6], _1_32);
+ alp1 = L_mac (alp1, rr[i5][i6], _1_32);
+
+ for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
+ {
+ ps2 = add (ps1, dn[i7]);
+
+ alp2 = L_mac (alp1, rrv[i7], _1_4);
+ alp2 = L_mac (alp2, rr[i6][i7], _1_32);
+
+ sq2 = mult (ps2, ps2);
+
+ alp_16 = pv_round (alp2);
+
+ s = L_msu (L_mult (alp, sq2), sq, alp_16);
+
+ if (s > 0)
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = alp_16;
+ ia = i6;
+ ib = i7;
+ }
+ }
+ }
+ i6 = ia;
+ i7 = ib;
+
+ // now finished searching a set of 8 pulses
+
+ if(gsmefrFlag != 0){
+ // go on with the two last pulses for GSMEFR
+ //
+ // i8 and i9 loop:
+ //
+
+ ps0 = ps;
+ alp0 = L_mult (alp, _1_2);
+
+ for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
+ {
+ s = L_mult (rr[i9][i9], _1_16);
+ s = L_mac (s, rr[i0][i9], _1_8);
+ s = L_mac (s, rr[i1][i9], _1_8);
+ s = L_mac (s, rr[i2][i9], _1_8);
+ s = L_mac (s, rr[i3][i9], _1_8);
+ s = L_mac (s, rr[i4][i9], _1_8);
+ s = L_mac (s, rr[i5][i9], _1_8);
+ s = L_mac (s, rr[i6][i9], _1_8);
+ s = L_mac (s, rr[i7][i9], _1_8);
+ rrv[i9] = pv_round (s);
+ }
+
+ // Default value
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[8];
+ ib = ipos[9];
+
+ for (i8 = ipos[8]; i8 < L_CODE; i8 += step)
+ {
+ ps1 = add (ps0, dn[i8]);
+
+ alp1 = L_mac (alp0, rr[i8][i8], _1_128);
+ alp1 = L_mac (alp1, rr[i0][i8], _1_64);
+ alp1 = L_mac (alp1, rr[i1][i8], _1_64);
+ alp1 = L_mac (alp1, rr[i2][i8], _1_64);
+ alp1 = L_mac (alp1, rr[i3][i8], _1_64);
+ alp1 = L_mac (alp1, rr[i4][i8], _1_64);
+ alp1 = L_mac (alp1, rr[i5][i8], _1_64);
+ alp1 = L_mac (alp1, rr[i6][i8], _1_64);
+ alp1 = L_mac (alp1, rr[i7][i8], _1_64);
+
+ for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
+ {
+ ps2 = add (ps1, dn[i9]);
+
+ alp2 = L_mac (alp1, rrv[i9], _1_8);
+ alp2 = L_mac (alp2, rr[i8][i9], _1_64);
+
+ sq2 = mult (ps2, ps2);
+
+ alp_16 = pv_round (alp2);
+
+ s = L_msu (L_mult (alp, sq2), sq, alp_16);
+
+ if (s > 0)
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = alp_16;
+ ia = i8;
+ ib = i9;
+ }
+ }
+ }
+ } // end gsmefrFlag
+
+ //
+ // test and memorise if this combination is better than the last one/
+ //
+
+ s = L_msu (L_mult (alpk, sq), psk, alp);
+
+ if (s > 0)
+ {
+ psk = sq;
+ alpk = alp;
+ codvec[0] = i0;
+ codvec[1] = i1;
+ codvec[2] = i2;
+ codvec[3] = i3;
+ codvec[4] = i4;
+ codvec[5] = i5;
+ codvec[6] = i6;
+ codvec[7] = i7;
+
+ if (gsmefrFlag != 0)
+ {
+ codvec[8] = ia;
+ codvec[9] = ib;
+ }
+ }
+
+ //
+ // Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9)/
+ //
+
+ pos = ipos[1];
+ for (j = 1, k = 2; k < nbPulse; j++, k++)
+ {
+ ipos[j] = ipos[k];
+ }
+ ipos[sub(nbPulse,1)] = pos;
+ } // end 1..nbTracks loop
+}
+
+------------------------------------------------------------------------------
+ RESOURCES USED [optional]
+
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ HEAP MEMORY USED: x bytes
+
+ STACK MEMORY USED: x bytes
+
+ CLOCK CYCLES: (cycle count equation for this function) + (variable
+ used to represent cycle count for each subroutine
+ called)
+ where: (cycle count variable) = cycle count for [subroutine
+ name]
+
+------------------------------------------------------------------------------
+ CAUTION [optional]
+ [State any special notes, constraints or cautions for users of this function]
+
+------------------------------------------------------------------------------
+*/
+
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void search_10and8i40(
+ Word16 nbPulse, /* i : nbpulses to find */
+ Word16 step, /* i : stepsize */
+ Word16 nbTracks, /* i : nbTracks */
+ Word16 dn[], /* i : correlation between target and h[] */
+ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
+ Word16 ipos[], /* i : starting position for each pulse */
+ Word16 pos_max[], /* i : position of maximum of dn[] */
+ Word16 codvec[], /* o : algebraic codebook vector */
+ Flag *pOverflow /* i/o : overflow flag */
+)
+{
+ Word16 i0, i1, i2, i3, i4, i5, i6, i7, i9;
+ Word16 i, j, k/*, m*/;
+ Word16 pos, ia, ib;
+ Word16 psk;
+ Word16 sq, sq2;
+ Word16 alpk, alp, alp_16;
+ Word32 s;
+ Word32 alp0, alp1, alp2;
+ Word16 gsmefrFlag;
+ Word16 *p_codvec = codvec;
+ Word16 *p_temp2;
+
+ Word16 temp1[2*L_CODE];
+ Word16 *p_temp1;
+ Word16 ps2;
+ Word16 ps1;
+ Word16 ps;
+ Word16 ps0;
+
+ Word16 index[10];
+
+ OSCL_UNUSED_ARG(pOverflow);
+
+ if (nbPulse == 10)
+ {
+ gsmefrFlag = 1;
+ }
+ else
+ {
+ gsmefrFlag = 0;
+ }
+
+ /* fix i0 on maximum of correlation position */
+ i0 = pos_max[ipos[0]];
+ index[0] = i0;
+ /*------------------------------------------------------------------*
+ * i1 loop: *
+ *------------------------------------------------------------------*/
+
+ /* Default value */
+ psk = -1;
+ alpk = 1;
+ for (i = 0; i < nbPulse; i++)
+ {
+ *(p_codvec++) = i;
+ }
+
+ for (i = 1; i < nbTracks; i++)
+ {
+ i1 = pos_max[ipos[1]];
+ index[1] = i1;
+
+ /* ps0 = add (dn[i0], dn[i1], pOverflow);*/
+ ps0 = (Word16)((Word32) dn[i0] + dn[i1]);
+
+ /* alp0 = L_mult (rr[i0][i0], _1_16, pOverflow); */
+ alp0 = (Word32) rr[i0][i0] << 12;
+
+ /* alp0 = L_mac (alp0, rr[i1][i1], _1_16, pOverflow); */
+ alp0 += (Word32) rr[i1][i1] << 12;
+
+ /* alp0 = L_mac (alp0, rr[i0][i1], _1_8, pOverflow); */
+ alp0 += (Word32) rr[i0][i1] << 13;
+ alp0 += 0x00008000L;
+
+ /*----------------------------------------------------------------*
+ * i2 and i3 loop: *
+ *----------------------------------------------------------------*/
+
+ p_temp1 = temp1;
+ for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
+ {
+ p_temp2 = &rr[i3][0];
+ s = (Word32) * (p_temp2 + i3) >> 1;
+ s += (Word32) * (p_temp2 + i0);
+ s += (Word32) * (p_temp2 + i1);
+ *(p_temp1++) = ps0 + dn[i3];
+ *(p_temp1++) = (Word16)((s + 2) >> 2);
+ }
+
+ /* Default value */
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[2];
+ ib = ipos[3];
+
+ s = (alp0 >> 12);
+
+ for (j = ipos[2]; j < L_CODE; j += step)
+ {
+ /* index increment = step */
+ p_temp2 = &rr[j][0];
+
+ alp1 = (s + (Word32) * (p_temp2 + j)) >> 1;
+
+ alp1 += (Word32) * (p_temp2 + i0);
+
+ alp1 += (Word32) * (p_temp2 + i1);
+
+ p_temp1 = temp1;
+ ps1 = dn[j];
+
+
+ for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
+ {
+ /* index increment = step */
+ ps2 = ps1 + *(p_temp1++);
+
+ sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
+
+ alp2 = (alp1 + p_temp2[i3]) >> 2;
+ alp2 = (alp2 + *(p_temp1++)) >> 1; /* alp2 is always > 0 */
+ if (((Word32) sq2 * alp) > ((Word32) sq * alp2))
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = (Word16)alp2;
+ ia = j;
+ ib = i3;
+ }
+ }
+
+ }
+ i2 = ia;
+ i3 = ib;
+ index[2] = ia;
+ index[3] = ib;
+
+ /*----------------------------------------------------------------*
+ * i4 and i5 loop: *
+ *----------------------------------------------------------------*/
+
+ alp0 = ((Word32) alp << 15) + 0x00008000L;
+ p_temp1 = temp1;
+
+ for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
+ {
+ p_temp2 = &rr[i5][0];
+ s = (Word32) * (p_temp2 + i5) >> 1;
+ s += (Word32) * (p_temp2 + i0);
+ s += (Word32) * (p_temp2 + i1);
+ s += (Word32) * (p_temp2 + i2);
+ s += (Word32) * (p_temp2 + i3);
+
+ *(p_temp1++) = ps + dn[i5];
+ *(p_temp1++) = (Word16)((s + 2) >> 2);
+ }
+
+ /* Default value */
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[4];
+ ib = ipos[5];
+
+ for (j = ipos[4]; j < L_CODE; j += step)
+ {
+ /* ps1 = add (ps0, dn[i4], pOverflow); */
+ p_temp2 = &rr[j][0];
+
+ /* alp1 = L_mac (alp0, rr[i4][i4], _1_32, pOverflow); */
+ alp1 = alp0 + ((Word32) * (p_temp2 + j) << 11);
+
+ /* alp1 = L_mac (alp1, rr[i0][i4], _1_16, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i0) << 12;
+
+ /* alp1 = L_mac (alp1, rr[i1][i4], _1_16, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i1) << 12;
+
+ /* alp1 = L_mac (alp1, rr[i2][i4], _1_16, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i2) << 12;
+
+ /* alp1 = L_mac (alp1, rr[i3][i4], _1_16, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i3) << 12;
+
+ p_temp1 = temp1;
+ ps1 = dn[j];
+
+ for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
+ {
+ ps2 = ps1 + *(p_temp1++);
+
+ alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12);
+
+ alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
+ sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
+
+ if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = alp_16;
+ ia = j;
+ ib = i5;
+ }
+
+ }
+ }
+ i4 = ia;
+ i5 = ib;
+ index[4] = ia;
+ index[5] = ib;
+
+ /*----------------------------------------------------------------*
+ * i6 and i7 loop: *
+ *----------------------------------------------------------------*/
+
+ alp0 = ((Word32) alp << 15) + 0x00008000L;
+
+ p_temp1 = temp1;
+
+ for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
+ {
+ s = (Word32) rr[i7][i7] >> 1;
+ s += (Word32) rr[i0][i7];
+ s += (Word32) rr[i1][i7];
+ s += (Word32) rr[i2][i7];
+ s += (Word32) rr[i3][i7];
+ s += (Word32) rr[i4][i7];
+ s += (Word32) rr[i5][i7];
+ *(p_temp1++) = ps + dn[i7];
+ *(p_temp1++) = (Word16)((s + 4) >> 3);
+ }
+
+
+ /* Default value */
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[6];
+ ib = ipos[7];
+
+ for (j = ipos[6]; j < L_CODE; j += step)
+ {
+ /* ps1 = add (ps0, dn[i6], pOverflow); */
+
+ p_temp2 = (Word16 *) & rr[j];
+
+ /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */
+ alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10);
+
+ /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i0) << 11;
+
+
+ /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i1) << 11;
+
+ /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i2) << 11;
+
+ /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i3) << 11;
+
+ /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i4) << 11;
+
+ /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */
+ alp1 += (Word32) * (p_temp2 + i5) << 11;
+
+ p_temp1 = temp1;
+ ps1 = dn[j];
+
+ for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
+ {
+ ps2 = ps1 + *(p_temp1++);
+
+ alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11);
+
+ alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
+
+ sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
+
+ if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = alp_16;
+ ia = j;
+ ib = i7;
+ }
+ }
+ }
+
+ i6 = ia;
+ i7 = ib;
+ index[6] = ia;
+ index[7] = ib;
+
+ /* now finished searching a set of 8 pulses */
+
+ if (gsmefrFlag != 0)
+ {
+ /* go on with the two last pulses for GSMEFR */
+ /*----------------------------------------------------------------*
+ * i8 and i9 loop: *
+ *----------------------------------------------------------------*/
+
+ alp0 = ((Word32) alp << 15) + 0x00008000L;
+
+ p_temp1 = temp1;
+
+ for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
+ {
+ s = (Word32) rr[i9][i9] >> 1;
+ s += (Word32) rr[i0][i9];
+ s += (Word32) rr[i1][i9];
+ s += (Word32) rr[i2][i9];
+ s += (Word32) rr[i3][i9];
+ s += (Word32) rr[i4][i9];
+ s += (Word32) rr[i5][i9];
+ s += (Word32) rr[i6][i9];
+ s += (Word32) rr[i7][i9];
+
+ *(p_temp1++) = ps + dn[i9];
+ *(p_temp1++) = (Word16)((s + 4) >> 3);
+ }
+
+ /* Default value */
+ sq = -1;
+ alp = 1;
+ ps = 0;
+ ia = ipos[8];
+ ib = ipos[9];
+
+ for (j = ipos[8]; j < L_CODE; j += step)
+ {
+ /* ps1 = add (ps0, dn[i8], pOverflow); */
+ p_temp2 = &rr[j][0];
+
+ /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */
+ alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9);
+
+ /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i0][j] << 10;
+
+ /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i1][j] << 10;
+
+ /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i2][j] << 10;
+
+ /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i3][j] << 10;
+
+ /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i4][j] << 10;
+
+ /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i5][j] << 10;
+
+ /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i6][j] << 10;
+
+ /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */
+ alp1 += (Word32) rr[i7][j] << 10;
+
+ p_temp1 = temp1;
+ ps1 = dn[j];
+
+ for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
+ {
+ /* ps2 = add (ps1, dn[i9], pOverflow); */
+ ps2 = ps1 + *(p_temp1++);
+
+ /* sq2 = mult (ps2, ps2, pOverflow); */
+ sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
+
+ /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */
+ alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ;
+
+ /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */
+ alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16);
+
+ if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
+ {
+ sq = sq2;
+ ps = ps2;
+ alp = alp_16;
+ ia = j;
+ ib = i9;
+ }
+ }
+ }
+
+ index[8] = ia;
+ index[9] = ib;
+
+ }/* end gsmefrFlag */
+
+ /*---------------------------------------------------------------- *
+ * test and memorise if this combination is better than the last one.*
+ *----------------------------------------------------------------*/
+
+ if (((Word32) alpk * sq) > ((Word32) psk * alp))
+ {
+ psk = sq;
+ alpk = alp;
+
+ if (gsmefrFlag != 0)
+ {
+ memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index));
+ }
+ else
+ {
+ memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index));
+ }
+
+ }
+ /*----------------------------------------------------------------*
+ * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). *
+ *----------------------------------------------------------------*/
+
+ pos = ipos[1];
+ for (j = 1, k = 2; k < nbPulse; j++, k++)
+ {
+ ipos[j] = ipos[k];
+ }
+ ipos[nbPulse-1] = pos;
+ } /* end 1..nbTracks loop*/
+}
+