1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
35 Funtions: search_10and8i40
37 ------------------------------------------------------------------------------
40 /*----------------------------------------------------------------------------
42 ----------------------------------------------------------------------------*/
47 /*----------------------------------------------------------------------------
49 ; Define module specific macros here
50 ----------------------------------------------------------------------------*/
52 /*----------------------------------------------------------------------------
54 ; Include all pre-processor statements here. Include conditional
55 ; compile variables also.
56 ----------------------------------------------------------------------------*/
58 /*----------------------------------------------------------------------------
59 ; LOCAL FUNCTION DEFINITIONS
60 ; Function Prototype declaration
61 ----------------------------------------------------------------------------*/
63 /*----------------------------------------------------------------------------
64 ; LOCAL VARIABLE DEFINITIONS
65 ; Variable declaration - defined here and used outside this module
66 ----------------------------------------------------------------------------*/
69 ------------------------------------------------------------------------------
70 FUNCTION NAME: search_10and8i40
71 ------------------------------------------------------------------------------
72 INPUT AND OUTPUT DEFINITIONS
75 nbPulse = nbPulses to find (Word16)
76 step = step size (Word16)
77 nbTracks = nbTracks (Word16)
78 dn[] = correlation between target and h[] (Word16)
79 rr[][] = matrix of autocorrelation (Word16)
80 ipos[] = starting position of each pulse (Word16)
81 pos_max[] = Position of maximum dn[] (Word16)
82 codvec[] = Algebraic codebook vector (Word16)
83 pOverflow = pointer to Overflow flag (Flag)
86 codvec[] = Algebraic codebook vector (Word16)
87 pOverflow -> 1 if processing this funvction results in satuaration
92 Global Variables Used:
95 Local Variables Needed:
98 ------------------------------------------------------------------------------
101 This function searches for the best codevector; It determines the positions
102 of the 10/8 pulses in the 40-sample frame.
104 search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec); for GSMEFR
105 search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec); for 10.2
108 ------------------------------------------------------------------------------
113 ------------------------------------------------------------------------------
116 s10_8pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
118 ------------------------------------------------------------------------------
121 void search_10and8i40 (
122 Word16 nbPulse, // i : nbpulses to find
123 Word16 step, // i : stepsize
124 Word16 nbTracks, // i : nbTracks
125 Word16 dn[], // i : correlation between target and h[]
126 Word16 rr[][L_CODE], // i : matrix of autocorrelation
127 Word16 ipos[], // i : starting position for each pulse
128 Word16 pos_max[], // i : position of maximum of dn[]
129 Word16 codvec[] // o : algebraic codebook vector
132 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
133 Word16 i, j, k, pos, ia, ib;
134 Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
135 Word16 alpk, alp, alp_16;
137 Word32 s, alp0, alp1, alp2;
141 if (sub(nbPulse, 10) == 0)
150 // fix i0 on maximum of correlation position
151 i0 = pos_max[ipos[0]];
161 for (i = 0; i < nbPulse; i++)
166 for (i = 1; i < nbTracks; i++)
168 i1 = pos_max[ipos[1]];
169 ps0 = add (dn[i0], dn[i1]);
170 alp0 = L_mult (rr[i0][i0], _1_16);
171 alp0 = L_mac (alp0, rr[i1][i1], _1_16);
172 alp0 = L_mac (alp0, rr[i0][i1], _1_8);
178 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
180 s = L_mult (rr[i3][i3], _1_8); // index incr= step+L_CODE
181 s = L_mac (s, rr[i0][i3], _1_4); // index increment = step
182 s = L_mac (s, rr[i1][i3], _1_4); // index increment = step
183 rrv[i3] = pv_round (s);
193 for (i2 = ipos[2]; i2 < L_CODE; i2 += step)
195 // index increment = step
196 ps1 = add (ps0, dn[i2]);
198 // index incr= step+L_CODE
199 alp1 = L_mac (alp0, rr[i2][i2], _1_16);
201 // index increment = step
202 alp1 = L_mac (alp1, rr[i0][i2], _1_8);
204 // index increment = step
205 alp1 = L_mac (alp1, rr[i1][i2], _1_8);
207 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
209 // index increment = step
210 ps2 = add (ps1, dn[i3]);
212 // index increment = step
213 alp2 = L_mac (alp1, rrv[i3], _1_2);
215 // index increment = step
216 alp2 = L_mac (alp2, rr[i2][i3], _1_8);
218 sq2 = mult (ps2, ps2);
220 alp_16 = pv_round (alp2);
222 s = L_msu (L_mult (alp, sq2), sq, alp_16);
242 alp0 = L_mult (alp, _1_2);
244 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
246 s = L_mult (rr[i5][i5], _1_8);
247 s = L_mac (s, rr[i0][i5], _1_4);
248 s = L_mac (s, rr[i1][i5], _1_4);
249 s = L_mac (s, rr[i2][i5], _1_4);
250 s = L_mac (s, rr[i3][i5], _1_4);
251 rrv[i5] = pv_round (s);
261 for (i4 = ipos[4]; i4 < L_CODE; i4 += step)
263 ps1 = add (ps0, dn[i4]);
265 alp1 = L_mac (alp0, rr[i4][i4], _1_32);
266 alp1 = L_mac (alp1, rr[i0][i4], _1_16);
267 alp1 = L_mac (alp1, rr[i1][i4], _1_16);
268 alp1 = L_mac (alp1, rr[i2][i4], _1_16);
269 alp1 = L_mac (alp1, rr[i3][i4], _1_16);
271 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
273 ps2 = add (ps1, dn[i5]);
275 alp2 = L_mac (alp1, rrv[i5], _1_4);
276 alp2 = L_mac (alp2, rr[i4][i5], _1_16);
278 sq2 = mult (ps2, ps2);
280 alp_16 = pv_round (alp2);
282 s = L_msu (L_mult (alp, sq2), sq, alp_16);
302 alp0 = L_mult (alp, _1_2);
304 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
306 s = L_mult (rr[i7][i7], _1_16);
307 s = L_mac (s, rr[i0][i7], _1_8);
308 s = L_mac (s, rr[i1][i7], _1_8);
309 s = L_mac (s, rr[i2][i7], _1_8);
310 s = L_mac (s, rr[i3][i7], _1_8);
311 s = L_mac (s, rr[i4][i7], _1_8);
312 s = L_mac (s, rr[i5][i7], _1_8);
313 rrv[i7] = pv_round (s);
323 for (i6 = ipos[6]; i6 < L_CODE; i6 += step)
325 ps1 = add (ps0, dn[i6]);
327 alp1 = L_mac (alp0, rr[i6][i6], _1_64);
328 alp1 = L_mac (alp1, rr[i0][i6], _1_32);
329 alp1 = L_mac (alp1, rr[i1][i6], _1_32);
330 alp1 = L_mac (alp1, rr[i2][i6], _1_32);
331 alp1 = L_mac (alp1, rr[i3][i6], _1_32);
332 alp1 = L_mac (alp1, rr[i4][i6], _1_32);
333 alp1 = L_mac (alp1, rr[i5][i6], _1_32);
335 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
337 ps2 = add (ps1, dn[i7]);
339 alp2 = L_mac (alp1, rrv[i7], _1_4);
340 alp2 = L_mac (alp2, rr[i6][i7], _1_32);
342 sq2 = mult (ps2, ps2);
344 alp_16 = pv_round (alp2);
346 s = L_msu (L_mult (alp, sq2), sq, alp_16);
361 // now finished searching a set of 8 pulses
364 // go on with the two last pulses for GSMEFR
370 alp0 = L_mult (alp, _1_2);
372 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
374 s = L_mult (rr[i9][i9], _1_16);
375 s = L_mac (s, rr[i0][i9], _1_8);
376 s = L_mac (s, rr[i1][i9], _1_8);
377 s = L_mac (s, rr[i2][i9], _1_8);
378 s = L_mac (s, rr[i3][i9], _1_8);
379 s = L_mac (s, rr[i4][i9], _1_8);
380 s = L_mac (s, rr[i5][i9], _1_8);
381 s = L_mac (s, rr[i6][i9], _1_8);
382 s = L_mac (s, rr[i7][i9], _1_8);
383 rrv[i9] = pv_round (s);
393 for (i8 = ipos[8]; i8 < L_CODE; i8 += step)
395 ps1 = add (ps0, dn[i8]);
397 alp1 = L_mac (alp0, rr[i8][i8], _1_128);
398 alp1 = L_mac (alp1, rr[i0][i8], _1_64);
399 alp1 = L_mac (alp1, rr[i1][i8], _1_64);
400 alp1 = L_mac (alp1, rr[i2][i8], _1_64);
401 alp1 = L_mac (alp1, rr[i3][i8], _1_64);
402 alp1 = L_mac (alp1, rr[i4][i8], _1_64);
403 alp1 = L_mac (alp1, rr[i5][i8], _1_64);
404 alp1 = L_mac (alp1, rr[i6][i8], _1_64);
405 alp1 = L_mac (alp1, rr[i7][i8], _1_64);
407 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
409 ps2 = add (ps1, dn[i9]);
411 alp2 = L_mac (alp1, rrv[i9], _1_8);
412 alp2 = L_mac (alp2, rr[i8][i9], _1_64);
414 sq2 = mult (ps2, ps2);
416 alp_16 = pv_round (alp2);
418 s = L_msu (L_mult (alp, sq2), sq, alp_16);
433 // test and memorise if this combination is better than the last one/
436 s = L_msu (L_mult (alpk, sq), psk, alp);
459 // Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9)/
463 for (j = 1, k = 2; k < nbPulse; j++, k++)
467 ipos[sub(nbPulse,1)] = pos;
468 } // end 1..nbTracks loop
471 ------------------------------------------------------------------------------
473 [State any special notes, constraints or cautions for users of this function]
475 ------------------------------------------------------------------------------
479 /*----------------------------------------------------------------------------
481 ----------------------------------------------------------------------------*/
482 void search_10and8i40(
483 Word16 nbPulse, /* i : nbpulses to find */
484 Word16 step, /* i : stepsize */
485 Word16 nbTracks, /* i : nbTracks */
486 Word16 dn[], /* i : correlation between target and h[] */
487 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
488 Word16 ipos[], /* i : starting position for each pulse */
489 Word16 pos_max[], /* i : position of maximum of dn[] */
490 Word16 codvec[], /* o : algebraic codebook vector */
491 Flag *pOverflow /* i/o : overflow flag */
494 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i9;
495 Word16 i, j, k/*, m*/;
499 Word16 alpk, alp, alp_16;
501 Word32 alp0, alp1, alp2;
503 Word16 *p_codvec = codvec;
506 Word16 temp1[2*L_CODE];
515 OSCL_UNUSED_ARG(pOverflow);
526 /* fix i0 on maximum of correlation position */
527 i0 = pos_max[ipos[0]];
529 /*------------------------------------------------------------------*
531 *------------------------------------------------------------------*/
536 for (i = 0; i < nbPulse; i++)
541 for (i = 1; i < nbTracks; i++)
543 i1 = pos_max[ipos[1]];
546 /* ps0 = add (dn[i0], dn[i1], pOverflow);*/
547 ps0 = (Word16)((Word32) dn[i0] + dn[i1]);
549 /* alp0 = L_mult (rr[i0][i0], _1_16, pOverflow); */
550 alp0 = (Word32) rr[i0][i0] << 12;
552 /* alp0 = L_mac (alp0, rr[i1][i1], _1_16, pOverflow); */
553 alp0 += (Word32) rr[i1][i1] << 12;
555 /* alp0 = L_mac (alp0, rr[i0][i1], _1_8, pOverflow); */
556 alp0 += (Word32) rr[i0][i1] << 13;
559 /*----------------------------------------------------------------*
561 *----------------------------------------------------------------*/
564 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
566 p_temp2 = &rr[i3][0];
567 s = (Word32) * (p_temp2 + i3) >> 1;
568 s += (Word32) * (p_temp2 + i0);
569 s += (Word32) * (p_temp2 + i1);
570 *(p_temp1++) = ps0 + dn[i3];
571 *(p_temp1++) = (Word16)((s + 2) >> 2);
583 for (j = ipos[2]; j < L_CODE; j += step)
585 /* index increment = step */
588 alp1 = (s + (Word32) * (p_temp2 + j)) >> 1;
590 alp1 += (Word32) * (p_temp2 + i0);
592 alp1 += (Word32) * (p_temp2 + i1);
598 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
600 /* index increment = step */
601 ps2 = ps1 + *(p_temp1++);
603 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
605 alp2 = (alp1 + p_temp2[i3]) >> 2;
606 alp2 = (alp2 + *(p_temp1++)) >> 1; /* alp2 is always > 0 */
607 if (((Word32) sq2 * alp) > ((Word32) sq * alp2))
623 /*----------------------------------------------------------------*
625 *----------------------------------------------------------------*/
627 alp0 = ((Word32) alp << 15) + 0x00008000L;
630 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
632 p_temp2 = &rr[i5][0];
633 s = (Word32) * (p_temp2 + i5) >> 1;
634 s += (Word32) * (p_temp2 + i0);
635 s += (Word32) * (p_temp2 + i1);
636 s += (Word32) * (p_temp2 + i2);
637 s += (Word32) * (p_temp2 + i3);
639 *(p_temp1++) = ps + dn[i5];
640 *(p_temp1++) = (Word16)((s + 2) >> 2);
650 for (j = ipos[4]; j < L_CODE; j += step)
652 /* ps1 = add (ps0, dn[i4], pOverflow); */
655 /* alp1 = L_mac (alp0, rr[i4][i4], _1_32, pOverflow); */
656 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 11);
658 /* alp1 = L_mac (alp1, rr[i0][i4], _1_16, pOverflow); */
659 alp1 += (Word32) * (p_temp2 + i0) << 12;
661 /* alp1 = L_mac (alp1, rr[i1][i4], _1_16, pOverflow); */
662 alp1 += (Word32) * (p_temp2 + i1) << 12;
664 /* alp1 = L_mac (alp1, rr[i2][i4], _1_16, pOverflow); */
665 alp1 += (Word32) * (p_temp2 + i2) << 12;
667 /* alp1 = L_mac (alp1, rr[i3][i4], _1_16, pOverflow); */
668 alp1 += (Word32) * (p_temp2 + i3) << 12;
673 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
675 ps2 = ps1 + *(p_temp1++);
677 alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12);
679 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
680 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
682 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
698 /*----------------------------------------------------------------*
700 *----------------------------------------------------------------*/
702 alp0 = ((Word32) alp << 15) + 0x00008000L;
706 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
708 s = (Word32) rr[i7][i7] >> 1;
709 s += (Word32) rr[i0][i7];
710 s += (Word32) rr[i1][i7];
711 s += (Word32) rr[i2][i7];
712 s += (Word32) rr[i3][i7];
713 s += (Word32) rr[i4][i7];
714 s += (Word32) rr[i5][i7];
715 *(p_temp1++) = ps + dn[i7];
716 *(p_temp1++) = (Word16)((s + 4) >> 3);
727 for (j = ipos[6]; j < L_CODE; j += step)
729 /* ps1 = add (ps0, dn[i6], pOverflow); */
731 p_temp2 = (Word16 *) & rr[j];
733 /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */
734 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10);
736 /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */
737 alp1 += (Word32) * (p_temp2 + i0) << 11;
740 /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */
741 alp1 += (Word32) * (p_temp2 + i1) << 11;
743 /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */
744 alp1 += (Word32) * (p_temp2 + i2) << 11;
746 /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */
747 alp1 += (Word32) * (p_temp2 + i3) << 11;
749 /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */
750 alp1 += (Word32) * (p_temp2 + i4) << 11;
752 /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */
753 alp1 += (Word32) * (p_temp2 + i5) << 11;
758 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
760 ps2 = ps1 + *(p_temp1++);
762 alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11);
764 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
766 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
768 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
784 /* now finished searching a set of 8 pulses */
788 /* go on with the two last pulses for GSMEFR */
789 /*----------------------------------------------------------------*
791 *----------------------------------------------------------------*/
793 alp0 = ((Word32) alp << 15) + 0x00008000L;
797 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
799 s = (Word32) rr[i9][i9] >> 1;
800 s += (Word32) rr[i0][i9];
801 s += (Word32) rr[i1][i9];
802 s += (Word32) rr[i2][i9];
803 s += (Word32) rr[i3][i9];
804 s += (Word32) rr[i4][i9];
805 s += (Word32) rr[i5][i9];
806 s += (Word32) rr[i6][i9];
807 s += (Word32) rr[i7][i9];
809 *(p_temp1++) = ps + dn[i9];
810 *(p_temp1++) = (Word16)((s + 4) >> 3);
820 for (j = ipos[8]; j < L_CODE; j += step)
822 /* ps1 = add (ps0, dn[i8], pOverflow); */
825 /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */
826 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9);
828 /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */
829 alp1 += (Word32) rr[i0][j] << 10;
831 /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */
832 alp1 += (Word32) rr[i1][j] << 10;
834 /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */
835 alp1 += (Word32) rr[i2][j] << 10;
837 /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */
838 alp1 += (Word32) rr[i3][j] << 10;
840 /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */
841 alp1 += (Word32) rr[i4][j] << 10;
843 /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */
844 alp1 += (Word32) rr[i5][j] << 10;
846 /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */
847 alp1 += (Word32) rr[i6][j] << 10;
849 /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */
850 alp1 += (Word32) rr[i7][j] << 10;
855 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
857 /* ps2 = add (ps1, dn[i9], pOverflow); */
858 ps2 = ps1 + *(p_temp1++);
860 /* sq2 = mult (ps2, ps2, pOverflow); */
861 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
863 /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */
864 alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ;
866 /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */
867 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16);
869 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
883 }/* end gsmefrFlag */
885 /*---------------------------------------------------------------- *
886 * test and memorise if this combination is better than the last one.*
887 *----------------------------------------------------------------*/
889 if (((Word32) alpk * sq) > ((Word32) psk * alp))
896 oscl_memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index));
900 oscl_memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index));
904 /*----------------------------------------------------------------*
905 * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). *
906 *----------------------------------------------------------------*/
909 for (j = 1, k = 2; k < nbPulse; j++, k++)
913 ipos[nbPulse-1] = pos;
914 } /* end 1..nbTracks loop*/