| /* ------------------------------------------------------------------ |
| * 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*/ |
| } |
| |