1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21 3GPP TS 26.073
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/s10_8pf.c
35 Funtions: search_10and8i40
36
37 Date: 04/18/2000
38
39 ------------------------------------------------------------------------------
40 REVISION HISTORY
41
42 Description: Adding pOverflow to the functions to remove global variables.
43 These changes are needed for the EPOC releases. Cleaned up code.
44 Updated template.
45
46 Description: Changed temp to temp32. When temp was only 16 bits it was not
47 holding the 32 bit value returned from the functions. Some
48 variables were also being declared as Word16 rather than Word32
49 as they were suposed to be.
50
51 Description: Changed copyright year. Removed all calls to math functions by
52 inlining them, and removed all unnecessary files in the Include
53 section.
54
55 Description: Made the following changes per comments from Phase 2/3 review:
56 1. Removed all #defines.
57 2. Used a pointer to &codvec[0] instead of array indexing.
58 3. Removed multiple data casting in the code.
59
60 Description:
61 1. Eliminated unused include files.
62 2. Replaced array addressing by pointers, this by taking
63 advantage of the fact that the autocrrelation matrix is
64 a toeplitz matrix, so r[i][j] = r[j][i], then a single
65 pointer can be used to address a matrix. The use of this
66 is not uniform along the function (due to compiler limitations:
67 handling so many variables in this file) so the use
68 of this is pointer optimizations is limited to places
69 where the ARM compiler provides the lesses numer of cycles
70 3. Eliminated use of intermediate variables to accelerate
71 comparisons (like in the nested loops)
72 4. Introduced array temp1[], to pre-calculate the elements
73 used in the nested loops, in this way the calculation is
74 not repeated in every loop iteration. This is done for
75 loops i3-i5-i7 and i9
76 5. Use array Index[] to store indexes i1:i9, and then use memcpy
77 to update indexes.
78 6. Eliminated shifts by modifying the way number are rounded,
79 this does not have any effect in ARM processors but may help
80 other compilers
81
82 Description:
83 1. When storing indexes, added memcpy() to support the rates
84 that use this function: 12.2 (already done) and 10.2 (missing).
85
86 Description: Replaced OSCL mem type functions and eliminated include
87 files that now are chosen by OSCL definitions
88
89 Description: Changed round function name to pv_round to avoid conflict with
90 round function in C standard library.
91
92 Description:
93
94 ------------------------------------------------------------------------------
95 */
96
97 /*----------------------------------------------------------------------------
98 ; INCLUDES
99 ----------------------------------------------------------------------------*/
100 #include "s10_8pf.h"
101 #include "cnst.h"
102 #include "oscl_mem.h"
103
104 /*----------------------------------------------------------------------------
105 ; MACROS
106 ; Define module specific macros here
107 ----------------------------------------------------------------------------*/
108
109 /*----------------------------------------------------------------------------
110 ; DEFINES
111 ; Include all pre-processor statements here. Include conditional
112 ; compile variables also.
113 ----------------------------------------------------------------------------*/
114
115 /*----------------------------------------------------------------------------
116 ; LOCAL FUNCTION DEFINITIONS
117 ; Function Prototype declaration
118 ----------------------------------------------------------------------------*/
119
120 /*----------------------------------------------------------------------------
121 ; LOCAL VARIABLE DEFINITIONS
122 ; Variable declaration - defined here and used outside this module
123 ----------------------------------------------------------------------------*/
124
125 /*
126 ------------------------------------------------------------------------------
127 FUNCTION NAME: search_10and8i40
128 ------------------------------------------------------------------------------
129 INPUT AND OUTPUT DEFINITIONS
130
131 Inputs:
132 nbPulse = nbPulses to find (Word16)
133 step = step size (Word16)
134 nbTracks = nbTracks (Word16)
135 dn[] = correlation between target and h[] (Word16)
136 rr[][] = matrix of autocorrelation (Word16)
137 ipos[] = starting position of each pulse (Word16)
138 pos_max[] = Position of maximum dn[] (Word16)
139 codvec[] = Algebraic codebook vector (Word16)
140 pOverflow = pointer to Overflow flag (Flag)
141
142 Outputs:
143 codvec[] = Algebraic codebook vector (Word16)
144 pOverflow -> 1 if processing this funvction results in satuaration
145
146 Returns:
147 None
148
149 Global Variables Used:
150 None
151
152 Local Variables Needed:
153 None
154
155 ------------------------------------------------------------------------------
156 FUNCTION DESCRIPTION
157
158 This function searches for the best codevector; It determines the positions
159 of the 10/8 pulses in the 40-sample frame.
160
161 search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec); for GSMEFR
162 search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec); for 10.2
163
164
165 ------------------------------------------------------------------------------
166 REQUIREMENTS
167
168 None
169
170 ------------------------------------------------------------------------------
171 REFERENCES
172
173 s10_8pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
174
175 ------------------------------------------------------------------------------
176 PSEUDO-CODE
177
178 void search_10and8i40 (
179 Word16 nbPulse, // i : nbpulses to find
180 Word16 step, // i : stepsize
181 Word16 nbTracks, // i : nbTracks
182 Word16 dn[], // i : correlation between target and h[]
183 Word16 rr[][L_CODE], // i : matrix of autocorrelation
184 Word16 ipos[], // i : starting position for each pulse
185 Word16 pos_max[], // i : position of maximum of dn[]
186 Word16 codvec[] // o : algebraic codebook vector
187 )
188 {
189 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
190 Word16 i, j, k, pos, ia, ib;
191 Word16 psk, ps, ps0, ps1, ps2, sq, sq2;
192 Word16 alpk, alp, alp_16;
193 Word16 rrv[L_CODE];
194 Word32 s, alp0, alp1, alp2;
195 Word16 gsmefrFlag;
196
197
198 if (sub(nbPulse, 10) == 0)
199 {
200 gsmefrFlag=1;
201 }
202 else
203 {
204 gsmefrFlag=0;
205 }
206
207 // fix i0 on maximum of correlation position
208 i0 = pos_max[ipos[0]];
209
210 //
211 // i1 loop: *
212 //
213
214 // Default value
215
216 psk = -1;
217 alpk = 1;
218 for (i = 0; i < nbPulse; i++)
219 {
220 codvec[i] = i;
221 }
222
223 for (i = 1; i < nbTracks; i++)
224 {
225 i1 = pos_max[ipos[1]];
226 ps0 = add (dn[i0], dn[i1]);
227 alp0 = L_mult (rr[i0][i0], _1_16);
228 alp0 = L_mac (alp0, rr[i1][i1], _1_16);
229 alp0 = L_mac (alp0, rr[i0][i1], _1_8);
230
231 //
232 // i2 and i3 loop
233 //
234
235 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
236 {
237 s = L_mult (rr[i3][i3], _1_8); // index incr= step+L_CODE
238 s = L_mac (s, rr[i0][i3], _1_4); // index increment = step
239 s = L_mac (s, rr[i1][i3], _1_4); // index increment = step
240 rrv[i3] = pv_round (s);
241 }
242
243 // Default value
244 sq = -1;
245 alp = 1;
246 ps = 0;
247 ia = ipos[2];
248 ib = ipos[3];
249
250 for (i2 = ipos[2]; i2 < L_CODE; i2 += step)
251 {
252 // index increment = step
253 ps1 = add (ps0, dn[i2]);
254
255 // index incr= step+L_CODE
256 alp1 = L_mac (alp0, rr[i2][i2], _1_16);
257
258 // index increment = step
259 alp1 = L_mac (alp1, rr[i0][i2], _1_8);
260
261 // index increment = step
262 alp1 = L_mac (alp1, rr[i1][i2], _1_8);
263
264 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
265 {
266 // index increment = step
267 ps2 = add (ps1, dn[i3]);
268
269 // index increment = step
270 alp2 = L_mac (alp1, rrv[i3], _1_2);
271
272 // index increment = step
273 alp2 = L_mac (alp2, rr[i2][i3], _1_8);
274
275 sq2 = mult (ps2, ps2);
276
277 alp_16 = pv_round (alp2);
278
279 s = L_msu (L_mult (alp, sq2), sq, alp_16);
280
281 if (s > 0)
282 {
283 sq = sq2;
284 ps = ps2;
285 alp = alp_16;
286 ia = i2;
287 ib = i3;
288 }
289 }
290 }
291 i2 = ia;
292 i3 = ib;
293
294 //
295 // i4 and i5 loop:
296 //
297
298 ps0 = ps;
299 alp0 = L_mult (alp, _1_2);
300
301 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
302 {
303 s = L_mult (rr[i5][i5], _1_8);
304 s = L_mac (s, rr[i0][i5], _1_4);
305 s = L_mac (s, rr[i1][i5], _1_4);
306 s = L_mac (s, rr[i2][i5], _1_4);
307 s = L_mac (s, rr[i3][i5], _1_4);
308 rrv[i5] = pv_round (s);
309 }
310
311 // Default value
312 sq = -1;
313 alp = 1;
314 ps = 0;
315 ia = ipos[4];
316 ib = ipos[5];
317
318 for (i4 = ipos[4]; i4 < L_CODE; i4 += step)
319 {
320 ps1 = add (ps0, dn[i4]);
321
322 alp1 = L_mac (alp0, rr[i4][i4], _1_32);
323 alp1 = L_mac (alp1, rr[i0][i4], _1_16);
324 alp1 = L_mac (alp1, rr[i1][i4], _1_16);
325 alp1 = L_mac (alp1, rr[i2][i4], _1_16);
326 alp1 = L_mac (alp1, rr[i3][i4], _1_16);
327
328 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
329 {
330 ps2 = add (ps1, dn[i5]);
331
332 alp2 = L_mac (alp1, rrv[i5], _1_4);
333 alp2 = L_mac (alp2, rr[i4][i5], _1_16);
334
335 sq2 = mult (ps2, ps2);
336
337 alp_16 = pv_round (alp2);
338
339 s = L_msu (L_mult (alp, sq2), sq, alp_16);
340
341 if (s > 0)
342 {
343 sq = sq2;
344 ps = ps2;
345 alp = alp_16;
346 ia = i4;
347 ib = i5;
348 }
349 }
350 }
351 i4 = ia;
352 i5 = ib;
353
354 //
355 // i6 and i7 loop:
356 //
357
358 ps0 = ps;
359 alp0 = L_mult (alp, _1_2);
360
361 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
362 {
363 s = L_mult (rr[i7][i7], _1_16);
364 s = L_mac (s, rr[i0][i7], _1_8);
365 s = L_mac (s, rr[i1][i7], _1_8);
366 s = L_mac (s, rr[i2][i7], _1_8);
367 s = L_mac (s, rr[i3][i7], _1_8);
368 s = L_mac (s, rr[i4][i7], _1_8);
369 s = L_mac (s, rr[i5][i7], _1_8);
370 rrv[i7] = pv_round (s);
371 }
372
373 // Default value
374 sq = -1;
375 alp = 1;
376 ps = 0;
377 ia = ipos[6];
378 ib = ipos[7];
379
380 for (i6 = ipos[6]; i6 < L_CODE; i6 += step)
381 {
382 ps1 = add (ps0, dn[i6]);
383
384 alp1 = L_mac (alp0, rr[i6][i6], _1_64);
385 alp1 = L_mac (alp1, rr[i0][i6], _1_32);
386 alp1 = L_mac (alp1, rr[i1][i6], _1_32);
387 alp1 = L_mac (alp1, rr[i2][i6], _1_32);
388 alp1 = L_mac (alp1, rr[i3][i6], _1_32);
389 alp1 = L_mac (alp1, rr[i4][i6], _1_32);
390 alp1 = L_mac (alp1, rr[i5][i6], _1_32);
391
392 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
393 {
394 ps2 = add (ps1, dn[i7]);
395
396 alp2 = L_mac (alp1, rrv[i7], _1_4);
397 alp2 = L_mac (alp2, rr[i6][i7], _1_32);
398
399 sq2 = mult (ps2, ps2);
400
401 alp_16 = pv_round (alp2);
402
403 s = L_msu (L_mult (alp, sq2), sq, alp_16);
404
405 if (s > 0)
406 {
407 sq = sq2;
408 ps = ps2;
409 alp = alp_16;
410 ia = i6;
411 ib = i7;
412 }
413 }
414 }
415 i6 = ia;
416 i7 = ib;
417
418 // now finished searching a set of 8 pulses
419
420 if(gsmefrFlag != 0){
421 // go on with the two last pulses for GSMEFR
422 //
423 // i8 and i9 loop:
424 //
425
426 ps0 = ps;
427 alp0 = L_mult (alp, _1_2);
428
429 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
430 {
431 s = L_mult (rr[i9][i9], _1_16);
432 s = L_mac (s, rr[i0][i9], _1_8);
433 s = L_mac (s, rr[i1][i9], _1_8);
434 s = L_mac (s, rr[i2][i9], _1_8);
435 s = L_mac (s, rr[i3][i9], _1_8);
436 s = L_mac (s, rr[i4][i9], _1_8);
437 s = L_mac (s, rr[i5][i9], _1_8);
438 s = L_mac (s, rr[i6][i9], _1_8);
439 s = L_mac (s, rr[i7][i9], _1_8);
440 rrv[i9] = pv_round (s);
441 }
442
443 // Default value
444 sq = -1;
445 alp = 1;
446 ps = 0;
447 ia = ipos[8];
448 ib = ipos[9];
449
450 for (i8 = ipos[8]; i8 < L_CODE; i8 += step)
451 {
452 ps1 = add (ps0, dn[i8]);
453
454 alp1 = L_mac (alp0, rr[i8][i8], _1_128);
455 alp1 = L_mac (alp1, rr[i0][i8], _1_64);
456 alp1 = L_mac (alp1, rr[i1][i8], _1_64);
457 alp1 = L_mac (alp1, rr[i2][i8], _1_64);
458 alp1 = L_mac (alp1, rr[i3][i8], _1_64);
459 alp1 = L_mac (alp1, rr[i4][i8], _1_64);
460 alp1 = L_mac (alp1, rr[i5][i8], _1_64);
461 alp1 = L_mac (alp1, rr[i6][i8], _1_64);
462 alp1 = L_mac (alp1, rr[i7][i8], _1_64);
463
464 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
465 {
466 ps2 = add (ps1, dn[i9]);
467
468 alp2 = L_mac (alp1, rrv[i9], _1_8);
469 alp2 = L_mac (alp2, rr[i8][i9], _1_64);
470
471 sq2 = mult (ps2, ps2);
472
473 alp_16 = pv_round (alp2);
474
475 s = L_msu (L_mult (alp, sq2), sq, alp_16);
476
477 if (s > 0)
478 {
479 sq = sq2;
480 ps = ps2;
481 alp = alp_16;
482 ia = i8;
483 ib = i9;
484 }
485 }
486 }
487 } // end gsmefrFlag
488
489 //
490 // test and memorise if this combination is better than the last one/
491 //
492
493 s = L_msu (L_mult (alpk, sq), psk, alp);
494
495 if (s > 0)
496 {
497 psk = sq;
498 alpk = alp;
499 codvec[0] = i0;
500 codvec[1] = i1;
501 codvec[2] = i2;
502 codvec[3] = i3;
503 codvec[4] = i4;
504 codvec[5] = i5;
505 codvec[6] = i6;
506 codvec[7] = i7;
507
508 if (gsmefrFlag != 0)
509 {
510 codvec[8] = ia;
511 codvec[9] = ib;
512 }
513 }
514
515 //
516 // Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9)/
517 //
518
519 pos = ipos[1];
520 for (j = 1, k = 2; k < nbPulse; j++, k++)
521 {
522 ipos[j] = ipos[k];
523 }
524 ipos[sub(nbPulse,1)] = pos;
525 } // end 1..nbTracks loop
526 }
527
528 ------------------------------------------------------------------------------
529 RESOURCES USED [optional]
530
531 When the code is written for a specific target processor the
532 the resources used should be documented below.
533
534 HEAP MEMORY USED: x bytes
535
536 STACK MEMORY USED: x bytes
537
538 CLOCK CYCLES: (cycle count equation for this function) + (variable
539 used to represent cycle count for each subroutine
540 called)
541 where: (cycle count variable) = cycle count for [subroutine
542 name]
543
544 ------------------------------------------------------------------------------
545 CAUTION [optional]
546 [State any special notes, constraints or cautions for users of this function]
547
548 ------------------------------------------------------------------------------
549 */
550
551
552 /*----------------------------------------------------------------------------
553 ; FUNCTION CODE
554 ----------------------------------------------------------------------------*/
search_10and8i40(Word16 nbPulse,Word16 step,Word16 nbTracks,Word16 dn[],Word16 rr[][L_CODE],Word16 ipos[],Word16 pos_max[],Word16 codvec[],Flag * pOverflow)555 void search_10and8i40(
556 Word16 nbPulse, /* i : nbpulses to find */
557 Word16 step, /* i : stepsize */
558 Word16 nbTracks, /* i : nbTracks */
559 Word16 dn[], /* i : correlation between target and h[] */
560 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
561 Word16 ipos[], /* i : starting position for each pulse */
562 Word16 pos_max[], /* i : position of maximum of dn[] */
563 Word16 codvec[], /* o : algebraic codebook vector */
564 Flag *pOverflow /* i/o : overflow flag */
565 )
566 {
567 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i9;
568 Word16 i, j, k/*, m*/;
569 Word16 pos, ia, ib;
570 Word16 psk;
571 Word16 sq, sq2;
572 Word16 alpk, alp, alp_16;
573 Word32 s;
574 Word32 alp0, alp1, alp2;
575 Word16 gsmefrFlag;
576 Word16 *p_codvec = codvec;
577 Word16 *p_temp2;
578
579 Word16 temp1[2*L_CODE];
580 Word16 *p_temp1;
581 Word16 ps2;
582 Word16 ps1;
583 Word16 ps;
584 Word16 ps0;
585
586 Word16 index[10];
587
588 OSCL_UNUSED_ARG(pOverflow);
589
590 if (nbPulse == 10)
591 {
592 gsmefrFlag = 1;
593 }
594 else
595 {
596 gsmefrFlag = 0;
597 }
598
599 /* fix i0 on maximum of correlation position */
600 i0 = pos_max[ipos[0]];
601 index[0] = i0;
602 /*------------------------------------------------------------------*
603 * i1 loop: *
604 *------------------------------------------------------------------*/
605
606 /* Default value */
607 psk = -1;
608 alpk = 1;
609 for (i = 0; i < nbPulse; i++)
610 {
611 *(p_codvec++) = i;
612 }
613
614 for (i = 1; i < nbTracks; i++)
615 {
616 i1 = pos_max[ipos[1]];
617 index[1] = i1;
618
619 /* ps0 = add (dn[i0], dn[i1], pOverflow);*/
620 ps0 = (Word16)((Word32) dn[i0] + dn[i1]);
621
622 /* alp0 = L_mult (rr[i0][i0], _1_16, pOverflow); */
623 alp0 = (Word32) rr[i0][i0] << 12;
624
625 /* alp0 = L_mac (alp0, rr[i1][i1], _1_16, pOverflow); */
626 alp0 += (Word32) rr[i1][i1] << 12;
627
628 /* alp0 = L_mac (alp0, rr[i0][i1], _1_8, pOverflow); */
629 alp0 += (Word32) rr[i0][i1] << 13;
630 alp0 += 0x00008000L;
631
632 /*----------------------------------------------------------------*
633 * i2 and i3 loop: *
634 *----------------------------------------------------------------*/
635
636 p_temp1 = temp1;
637 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
638 {
639 p_temp2 = &rr[i3][0];
640 s = (Word32) * (p_temp2 + i3) >> 1;
641 s += (Word32) * (p_temp2 + i0);
642 s += (Word32) * (p_temp2 + i1);
643 *(p_temp1++) = ps0 + dn[i3];
644 *(p_temp1++) = (Word16)((s + 2) >> 2);
645 }
646
647 /* Default value */
648 sq = -1;
649 alp = 1;
650 ps = 0;
651 ia = ipos[2];
652 ib = ipos[3];
653
654 s = (alp0 >> 12);
655
656 for (j = ipos[2]; j < L_CODE; j += step)
657 {
658 /* index increment = step */
659 p_temp2 = &rr[j][0];
660
661 alp1 = (s + (Word32) * (p_temp2 + j)) >> 1;
662
663 alp1 += (Word32) * (p_temp2 + i0);
664
665 alp1 += (Word32) * (p_temp2 + i1);
666
667 p_temp1 = temp1;
668 ps1 = dn[j];
669
670
671 for (i3 = ipos[3]; i3 < L_CODE; i3 += step)
672 {
673 /* index increment = step */
674 ps2 = ps1 + *(p_temp1++);
675
676 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
677
678 alp2 = (alp1 + p_temp2[i3]) >> 2;
679 alp2 = (alp2 + *(p_temp1++)) >> 1; /* alp2 is always > 0 */
680 if (((Word32) sq2 * alp) > ((Word32) sq * alp2))
681 {
682 sq = sq2;
683 ps = ps2;
684 alp = (Word16)alp2;
685 ia = j;
686 ib = i3;
687 }
688 }
689
690 }
691 i2 = ia;
692 i3 = ib;
693 index[2] = ia;
694 index[3] = ib;
695
696 /*----------------------------------------------------------------*
697 * i4 and i5 loop: *
698 *----------------------------------------------------------------*/
699
700 alp0 = ((Word32) alp << 15) + 0x00008000L;
701 p_temp1 = temp1;
702
703 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
704 {
705 p_temp2 = &rr[i5][0];
706 s = (Word32) * (p_temp2 + i5) >> 1;
707 s += (Word32) * (p_temp2 + i0);
708 s += (Word32) * (p_temp2 + i1);
709 s += (Word32) * (p_temp2 + i2);
710 s += (Word32) * (p_temp2 + i3);
711
712 *(p_temp1++) = ps + dn[i5];
713 *(p_temp1++) = (Word16)((s + 2) >> 2);
714 }
715
716 /* Default value */
717 sq = -1;
718 alp = 1;
719 ps = 0;
720 ia = ipos[4];
721 ib = ipos[5];
722
723 for (j = ipos[4]; j < L_CODE; j += step)
724 {
725 /* ps1 = add (ps0, dn[i4], pOverflow); */
726 p_temp2 = &rr[j][0];
727
728 /* alp1 = L_mac (alp0, rr[i4][i4], _1_32, pOverflow); */
729 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 11);
730
731 /* alp1 = L_mac (alp1, rr[i0][i4], _1_16, pOverflow); */
732 alp1 += (Word32) * (p_temp2 + i0) << 12;
733
734 /* alp1 = L_mac (alp1, rr[i1][i4], _1_16, pOverflow); */
735 alp1 += (Word32) * (p_temp2 + i1) << 12;
736
737 /* alp1 = L_mac (alp1, rr[i2][i4], _1_16, pOverflow); */
738 alp1 += (Word32) * (p_temp2 + i2) << 12;
739
740 /* alp1 = L_mac (alp1, rr[i3][i4], _1_16, pOverflow); */
741 alp1 += (Word32) * (p_temp2 + i3) << 12;
742
743 p_temp1 = temp1;
744 ps1 = dn[j];
745
746 for (i5 = ipos[5]; i5 < L_CODE; i5 += step)
747 {
748 ps2 = ps1 + *(p_temp1++);
749
750 alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12);
751
752 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
753 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
754
755 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
756 {
757 sq = sq2;
758 ps = ps2;
759 alp = alp_16;
760 ia = j;
761 ib = i5;
762 }
763
764 }
765 }
766 i4 = ia;
767 i5 = ib;
768 index[4] = ia;
769 index[5] = ib;
770
771 /*----------------------------------------------------------------*
772 * i6 and i7 loop: *
773 *----------------------------------------------------------------*/
774
775 alp0 = ((Word32) alp << 15) + 0x00008000L;
776
777 p_temp1 = temp1;
778
779 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
780 {
781 s = (Word32) rr[i7][i7] >> 1;
782 s += (Word32) rr[i0][i7];
783 s += (Word32) rr[i1][i7];
784 s += (Word32) rr[i2][i7];
785 s += (Word32) rr[i3][i7];
786 s += (Word32) rr[i4][i7];
787 s += (Word32) rr[i5][i7];
788 *(p_temp1++) = ps + dn[i7];
789 *(p_temp1++) = (Word16)((s + 4) >> 3);
790 }
791
792
793 /* Default value */
794 sq = -1;
795 alp = 1;
796 ps = 0;
797 ia = ipos[6];
798 ib = ipos[7];
799
800 for (j = ipos[6]; j < L_CODE; j += step)
801 {
802 /* ps1 = add (ps0, dn[i6], pOverflow); */
803
804 p_temp2 = (Word16 *) & rr[j];
805
806 /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */
807 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10);
808
809 /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */
810 alp1 += (Word32) * (p_temp2 + i0) << 11;
811
812
813 /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */
814 alp1 += (Word32) * (p_temp2 + i1) << 11;
815
816 /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */
817 alp1 += (Word32) * (p_temp2 + i2) << 11;
818
819 /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */
820 alp1 += (Word32) * (p_temp2 + i3) << 11;
821
822 /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */
823 alp1 += (Word32) * (p_temp2 + i4) << 11;
824
825 /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */
826 alp1 += (Word32) * (p_temp2 + i5) << 11;
827
828 p_temp1 = temp1;
829 ps1 = dn[j];
830
831 for (i7 = ipos[7]; i7 < L_CODE; i7 += step)
832 {
833 ps2 = ps1 + *(p_temp1++);
834
835 alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11);
836
837 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16);
838
839 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
840
841 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
842 {
843 sq = sq2;
844 ps = ps2;
845 alp = alp_16;
846 ia = j;
847 ib = i7;
848 }
849 }
850 }
851
852 i6 = ia;
853 i7 = ib;
854 index[6] = ia;
855 index[7] = ib;
856
857 /* now finished searching a set of 8 pulses */
858
859 if (gsmefrFlag != 0)
860 {
861 /* go on with the two last pulses for GSMEFR */
862 /*----------------------------------------------------------------*
863 * i8 and i9 loop: *
864 *----------------------------------------------------------------*/
865
866 alp0 = ((Word32) alp << 15) + 0x00008000L;
867
868 p_temp1 = temp1;
869
870 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
871 {
872 s = (Word32) rr[i9][i9] >> 1;
873 s += (Word32) rr[i0][i9];
874 s += (Word32) rr[i1][i9];
875 s += (Word32) rr[i2][i9];
876 s += (Word32) rr[i3][i9];
877 s += (Word32) rr[i4][i9];
878 s += (Word32) rr[i5][i9];
879 s += (Word32) rr[i6][i9];
880 s += (Word32) rr[i7][i9];
881
882 *(p_temp1++) = ps + dn[i9];
883 *(p_temp1++) = (Word16)((s + 4) >> 3);
884 }
885
886 /* Default value */
887 sq = -1;
888 alp = 1;
889 ps = 0;
890 ia = ipos[8];
891 ib = ipos[9];
892
893 for (j = ipos[8]; j < L_CODE; j += step)
894 {
895 /* ps1 = add (ps0, dn[i8], pOverflow); */
896 p_temp2 = &rr[j][0];
897
898 /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */
899 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9);
900
901 /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */
902 alp1 += (Word32) rr[i0][j] << 10;
903
904 /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */
905 alp1 += (Word32) rr[i1][j] << 10;
906
907 /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */
908 alp1 += (Word32) rr[i2][j] << 10;
909
910 /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */
911 alp1 += (Word32) rr[i3][j] << 10;
912
913 /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */
914 alp1 += (Word32) rr[i4][j] << 10;
915
916 /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */
917 alp1 += (Word32) rr[i5][j] << 10;
918
919 /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */
920 alp1 += (Word32) rr[i6][j] << 10;
921
922 /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */
923 alp1 += (Word32) rr[i7][j] << 10;
924
925 p_temp1 = temp1;
926 ps1 = dn[j];
927
928 for (i9 = ipos[9]; i9 < L_CODE; i9 += step)
929 {
930 /* ps2 = add (ps1, dn[i9], pOverflow); */
931 ps2 = ps1 + *(p_temp1++);
932
933 /* sq2 = mult (ps2, ps2, pOverflow); */
934 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15);
935
936 /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */
937 alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ;
938
939 /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */
940 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16);
941
942 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16))
943 {
944 sq = sq2;
945 ps = ps2;
946 alp = alp_16;
947 ia = j;
948 ib = i9;
949 }
950 }
951 }
952
953 index[8] = ia;
954 index[9] = ib;
955
956 }/* end gsmefrFlag */
957
958 /*---------------------------------------------------------------- *
959 * test and memorise if this combination is better than the last one.*
960 *----------------------------------------------------------------*/
961
962 if (((Word32) alpk * sq) > ((Word32) psk * alp))
963 {
964 psk = sq;
965 alpk = alp;
966
967 if (gsmefrFlag != 0)
968 {
969 oscl_memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index));
970 }
971 else
972 {
973 oscl_memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index));
974 }
975
976 }
977 /*----------------------------------------------------------------*
978 * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). *
979 *----------------------------------------------------------------*/
980
981 pos = ipos[1];
982 for (j = 1, k = 2; k < nbPulse; j++, k++)
983 {
984 ipos[j] = ipos[k];
985 }
986 ipos[nbPulse-1] = pos;
987 } /* end 1..nbTracks loop*/
988 }
989
990