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 <string.h> 101 102 #include "s10_8pf.h" 103 #include "cnst.h" 104 105 /*---------------------------------------------------------------------------- 106 ; MACROS 107 ; Define module specific macros here 108 ----------------------------------------------------------------------------*/ 109 110 /*---------------------------------------------------------------------------- 111 ; DEFINES 112 ; Include all pre-processor statements here. Include conditional 113 ; compile variables also. 114 ----------------------------------------------------------------------------*/ 115 116 /*---------------------------------------------------------------------------- 117 ; LOCAL FUNCTION DEFINITIONS 118 ; Function Prototype declaration 119 ----------------------------------------------------------------------------*/ 120 121 /*---------------------------------------------------------------------------- 122 ; LOCAL VARIABLE DEFINITIONS 123 ; Variable declaration - defined here and used outside this module 124 ----------------------------------------------------------------------------*/ 125 126 /* 127 ------------------------------------------------------------------------------ 128 FUNCTION NAME: search_10and8i40 129 ------------------------------------------------------------------------------ 130 INPUT AND OUTPUT DEFINITIONS 131 132 Inputs: 133 nbPulse = nbPulses to find (Word16) 134 step = step size (Word16) 135 nbTracks = nbTracks (Word16) 136 dn[] = correlation between target and h[] (Word16) 137 rr[][] = matrix of autocorrelation (Word16) 138 ipos[] = starting position of each pulse (Word16) 139 pos_max[] = Position of maximum dn[] (Word16) 140 codvec[] = Algebraic codebook vector (Word16) 141 pOverflow = pointer to Overflow flag (Flag) 142 143 Outputs: 144 codvec[] = Algebraic codebook vector (Word16) 145 pOverflow -> 1 if processing this funvction results in satuaration 146 147 Returns: 148 None 149 150 Global Variables Used: 151 None 152 153 Local Variables Needed: 154 None 155 156 ------------------------------------------------------------------------------ 157 FUNCTION DESCRIPTION 158 159 This function searches for the best codevector; It determines the positions 160 of the 10/8 pulses in the 40-sample frame. 161 162 search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec); for GSMEFR 163 search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec); for 10.2 164 165 166 ------------------------------------------------------------------------------ 167 REQUIREMENTS 168 169 None 170 171 ------------------------------------------------------------------------------ 172 REFERENCES 173 174 s10_8pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 175 176 ------------------------------------------------------------------------------ 177 PSEUDO-CODE 178 179 void search_10and8i40 ( 180 Word16 nbPulse, // i : nbpulses to find 181 Word16 step, // i : stepsize 182 Word16 nbTracks, // i : nbTracks 183 Word16 dn[], // i : correlation between target and h[] 184 Word16 rr[][L_CODE], // i : matrix of autocorrelation 185 Word16 ipos[], // i : starting position for each pulse 186 Word16 pos_max[], // i : position of maximum of dn[] 187 Word16 codvec[] // o : algebraic codebook vector 188 ) 189 { 190 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; 191 Word16 i, j, k, pos, ia, ib; 192 Word16 psk, ps, ps0, ps1, ps2, sq, sq2; 193 Word16 alpk, alp, alp_16; 194 Word16 rrv[L_CODE]; 195 Word32 s, alp0, alp1, alp2; 196 Word16 gsmefrFlag; 197 198 199 if (sub(nbPulse, 10) == 0) 200 { 201 gsmefrFlag=1; 202 } 203 else 204 { 205 gsmefrFlag=0; 206 } 207 208 // fix i0 on maximum of correlation position 209 i0 = pos_max[ipos[0]]; 210 211 // 212 // i1 loop: * 213 // 214 215 // Default value 216 217 psk = -1; 218 alpk = 1; 219 for (i = 0; i < nbPulse; i++) 220 { 221 codvec[i] = i; 222 } 223 224 for (i = 1; i < nbTracks; i++) 225 { 226 i1 = pos_max[ipos[1]]; 227 ps0 = add (dn[i0], dn[i1]); 228 alp0 = L_mult (rr[i0][i0], _1_16); 229 alp0 = L_mac (alp0, rr[i1][i1], _1_16); 230 alp0 = L_mac (alp0, rr[i0][i1], _1_8); 231 232 // 233 // i2 and i3 loop 234 // 235 236 for (i3 = ipos[3]; i3 < L_CODE; i3 += step) 237 { 238 s = L_mult (rr[i3][i3], _1_8); // index incr= step+L_CODE 239 s = L_mac (s, rr[i0][i3], _1_4); // index increment = step 240 s = L_mac (s, rr[i1][i3], _1_4); // index increment = step 241 rrv[i3] = pv_round (s); 242 } 243 244 // Default value 245 sq = -1; 246 alp = 1; 247 ps = 0; 248 ia = ipos[2]; 249 ib = ipos[3]; 250 251 for (i2 = ipos[2]; i2 < L_CODE; i2 += step) 252 { 253 // index increment = step 254 ps1 = add (ps0, dn[i2]); 255 256 // index incr= step+L_CODE 257 alp1 = L_mac (alp0, rr[i2][i2], _1_16); 258 259 // index increment = step 260 alp1 = L_mac (alp1, rr[i0][i2], _1_8); 261 262 // index increment = step 263 alp1 = L_mac (alp1, rr[i1][i2], _1_8); 264 265 for (i3 = ipos[3]; i3 < L_CODE; i3 += step) 266 { 267 // index increment = step 268 ps2 = add (ps1, dn[i3]); 269 270 // index increment = step 271 alp2 = L_mac (alp1, rrv[i3], _1_2); 272 273 // index increment = step 274 alp2 = L_mac (alp2, rr[i2][i3], _1_8); 275 276 sq2 = mult (ps2, ps2); 277 278 alp_16 = pv_round (alp2); 279 280 s = L_msu (L_mult (alp, sq2), sq, alp_16); 281 282 if (s > 0) 283 { 284 sq = sq2; 285 ps = ps2; 286 alp = alp_16; 287 ia = i2; 288 ib = i3; 289 } 290 } 291 } 292 i2 = ia; 293 i3 = ib; 294 295 // 296 // i4 and i5 loop: 297 // 298 299 ps0 = ps; 300 alp0 = L_mult (alp, _1_2); 301 302 for (i5 = ipos[5]; i5 < L_CODE; i5 += step) 303 { 304 s = L_mult (rr[i5][i5], _1_8); 305 s = L_mac (s, rr[i0][i5], _1_4); 306 s = L_mac (s, rr[i1][i5], _1_4); 307 s = L_mac (s, rr[i2][i5], _1_4); 308 s = L_mac (s, rr[i3][i5], _1_4); 309 rrv[i5] = pv_round (s); 310 } 311 312 // Default value 313 sq = -1; 314 alp = 1; 315 ps = 0; 316 ia = ipos[4]; 317 ib = ipos[5]; 318 319 for (i4 = ipos[4]; i4 < L_CODE; i4 += step) 320 { 321 ps1 = add (ps0, dn[i4]); 322 323 alp1 = L_mac (alp0, rr[i4][i4], _1_32); 324 alp1 = L_mac (alp1, rr[i0][i4], _1_16); 325 alp1 = L_mac (alp1, rr[i1][i4], _1_16); 326 alp1 = L_mac (alp1, rr[i2][i4], _1_16); 327 alp1 = L_mac (alp1, rr[i3][i4], _1_16); 328 329 for (i5 = ipos[5]; i5 < L_CODE; i5 += step) 330 { 331 ps2 = add (ps1, dn[i5]); 332 333 alp2 = L_mac (alp1, rrv[i5], _1_4); 334 alp2 = L_mac (alp2, rr[i4][i5], _1_16); 335 336 sq2 = mult (ps2, ps2); 337 338 alp_16 = pv_round (alp2); 339 340 s = L_msu (L_mult (alp, sq2), sq, alp_16); 341 342 if (s > 0) 343 { 344 sq = sq2; 345 ps = ps2; 346 alp = alp_16; 347 ia = i4; 348 ib = i5; 349 } 350 } 351 } 352 i4 = ia; 353 i5 = ib; 354 355 // 356 // i6 and i7 loop: 357 // 358 359 ps0 = ps; 360 alp0 = L_mult (alp, _1_2); 361 362 for (i7 = ipos[7]; i7 < L_CODE; i7 += step) 363 { 364 s = L_mult (rr[i7][i7], _1_16); 365 s = L_mac (s, rr[i0][i7], _1_8); 366 s = L_mac (s, rr[i1][i7], _1_8); 367 s = L_mac (s, rr[i2][i7], _1_8); 368 s = L_mac (s, rr[i3][i7], _1_8); 369 s = L_mac (s, rr[i4][i7], _1_8); 370 s = L_mac (s, rr[i5][i7], _1_8); 371 rrv[i7] = pv_round (s); 372 } 373 374 // Default value 375 sq = -1; 376 alp = 1; 377 ps = 0; 378 ia = ipos[6]; 379 ib = ipos[7]; 380 381 for (i6 = ipos[6]; i6 < L_CODE; i6 += step) 382 { 383 ps1 = add (ps0, dn[i6]); 384 385 alp1 = L_mac (alp0, rr[i6][i6], _1_64); 386 alp1 = L_mac (alp1, rr[i0][i6], _1_32); 387 alp1 = L_mac (alp1, rr[i1][i6], _1_32); 388 alp1 = L_mac (alp1, rr[i2][i6], _1_32); 389 alp1 = L_mac (alp1, rr[i3][i6], _1_32); 390 alp1 = L_mac (alp1, rr[i4][i6], _1_32); 391 alp1 = L_mac (alp1, rr[i5][i6], _1_32); 392 393 for (i7 = ipos[7]; i7 < L_CODE; i7 += step) 394 { 395 ps2 = add (ps1, dn[i7]); 396 397 alp2 = L_mac (alp1, rrv[i7], _1_4); 398 alp2 = L_mac (alp2, rr[i6][i7], _1_32); 399 400 sq2 = mult (ps2, ps2); 401 402 alp_16 = pv_round (alp2); 403 404 s = L_msu (L_mult (alp, sq2), sq, alp_16); 405 406 if (s > 0) 407 { 408 sq = sq2; 409 ps = ps2; 410 alp = alp_16; 411 ia = i6; 412 ib = i7; 413 } 414 } 415 } 416 i6 = ia; 417 i7 = ib; 418 419 // now finished searching a set of 8 pulses 420 421 if(gsmefrFlag != 0){ 422 // go on with the two last pulses for GSMEFR 423 // 424 // i8 and i9 loop: 425 // 426 427 ps0 = ps; 428 alp0 = L_mult (alp, _1_2); 429 430 for (i9 = ipos[9]; i9 < L_CODE; i9 += step) 431 { 432 s = L_mult (rr[i9][i9], _1_16); 433 s = L_mac (s, rr[i0][i9], _1_8); 434 s = L_mac (s, rr[i1][i9], _1_8); 435 s = L_mac (s, rr[i2][i9], _1_8); 436 s = L_mac (s, rr[i3][i9], _1_8); 437 s = L_mac (s, rr[i4][i9], _1_8); 438 s = L_mac (s, rr[i5][i9], _1_8); 439 s = L_mac (s, rr[i6][i9], _1_8); 440 s = L_mac (s, rr[i7][i9], _1_8); 441 rrv[i9] = pv_round (s); 442 } 443 444 // Default value 445 sq = -1; 446 alp = 1; 447 ps = 0; 448 ia = ipos[8]; 449 ib = ipos[9]; 450 451 for (i8 = ipos[8]; i8 < L_CODE; i8 += step) 452 { 453 ps1 = add (ps0, dn[i8]); 454 455 alp1 = L_mac (alp0, rr[i8][i8], _1_128); 456 alp1 = L_mac (alp1, rr[i0][i8], _1_64); 457 alp1 = L_mac (alp1, rr[i1][i8], _1_64); 458 alp1 = L_mac (alp1, rr[i2][i8], _1_64); 459 alp1 = L_mac (alp1, rr[i3][i8], _1_64); 460 alp1 = L_mac (alp1, rr[i4][i8], _1_64); 461 alp1 = L_mac (alp1, rr[i5][i8], _1_64); 462 alp1 = L_mac (alp1, rr[i6][i8], _1_64); 463 alp1 = L_mac (alp1, rr[i7][i8], _1_64); 464 465 for (i9 = ipos[9]; i9 < L_CODE; i9 += step) 466 { 467 ps2 = add (ps1, dn[i9]); 468 469 alp2 = L_mac (alp1, rrv[i9], _1_8); 470 alp2 = L_mac (alp2, rr[i8][i9], _1_64); 471 472 sq2 = mult (ps2, ps2); 473 474 alp_16 = pv_round (alp2); 475 476 s = L_msu (L_mult (alp, sq2), sq, alp_16); 477 478 if (s > 0) 479 { 480 sq = sq2; 481 ps = ps2; 482 alp = alp_16; 483 ia = i8; 484 ib = i9; 485 } 486 } 487 } 488 } // end gsmefrFlag 489 490 // 491 // test and memorise if this combination is better than the last one/ 492 // 493 494 s = L_msu (L_mult (alpk, sq), psk, alp); 495 496 if (s > 0) 497 { 498 psk = sq; 499 alpk = alp; 500 codvec[0] = i0; 501 codvec[1] = i1; 502 codvec[2] = i2; 503 codvec[3] = i3; 504 codvec[4] = i4; 505 codvec[5] = i5; 506 codvec[6] = i6; 507 codvec[7] = i7; 508 509 if (gsmefrFlag != 0) 510 { 511 codvec[8] = ia; 512 codvec[9] = ib; 513 } 514 } 515 516 // 517 // Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9)/ 518 // 519 520 pos = ipos[1]; 521 for (j = 1, k = 2; k < nbPulse; j++, k++) 522 { 523 ipos[j] = ipos[k]; 524 } 525 ipos[sub(nbPulse,1)] = pos; 526 } // end 1..nbTracks loop 527 } 528 529 ------------------------------------------------------------------------------ 530 RESOURCES USED [optional] 531 532 When the code is written for a specific target processor the 533 the resources used should be documented below. 534 535 HEAP MEMORY USED: x bytes 536 537 STACK MEMORY USED: x bytes 538 539 CLOCK CYCLES: (cycle count equation for this function) + (variable 540 used to represent cycle count for each subroutine 541 called) 542 where: (cycle count variable) = cycle count for [subroutine 543 name] 544 545 ------------------------------------------------------------------------------ 546 CAUTION [optional] 547 [State any special notes, constraints or cautions for users of this function] 548 549 ------------------------------------------------------------------------------ 550 */ 551 552 553 /*---------------------------------------------------------------------------- 554 ; FUNCTION CODE 555 ----------------------------------------------------------------------------*/ 556 void search_10and8i40( 557 Word16 nbPulse, /* i : nbpulses to find */ 558 Word16 step, /* i : stepsize */ 559 Word16 nbTracks, /* i : nbTracks */ 560 Word16 dn[], /* i : correlation between target and h[] */ 561 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ 562 Word16 ipos[], /* i : starting position for each pulse */ 563 Word16 pos_max[], /* i : position of maximum of dn[] */ 564 Word16 codvec[], /* o : algebraic codebook vector */ 565 Flag *pOverflow /* i/o : overflow flag */ 566 ) 567 { 568 Word16 i0, i1, i2, i3, i4, i5, i6, i7, i9; 569 Word16 i, j, k/*, m*/; 570 Word16 pos, ia, ib; 571 Word16 psk; 572 Word16 sq, sq2; 573 Word16 alpk, alp, alp_16; 574 Word32 s; 575 Word32 alp0, alp1, alp2; 576 Word16 gsmefrFlag; 577 Word16 *p_codvec = codvec; 578 Word16 *p_temp2; 579 580 Word16 temp1[2*L_CODE]; 581 Word16 *p_temp1; 582 Word16 ps2; 583 Word16 ps1; 584 Word16 ps; 585 Word16 ps0; 586 587 Word16 index[10]; 588 589 OSCL_UNUSED_ARG(pOverflow); 590 591 if (nbPulse == 10) 592 { 593 gsmefrFlag = 1; 594 } 595 else 596 { 597 gsmefrFlag = 0; 598 } 599 600 /* fix i0 on maximum of correlation position */ 601 i0 = pos_max[ipos[0]]; 602 index[0] = i0; 603 /*------------------------------------------------------------------* 604 * i1 loop: * 605 *------------------------------------------------------------------*/ 606 607 /* Default value */ 608 psk = -1; 609 alpk = 1; 610 for (i = 0; i < nbPulse; i++) 611 { 612 *(p_codvec++) = i; 613 } 614 615 for (i = 1; i < nbTracks; i++) 616 { 617 i1 = pos_max[ipos[1]]; 618 index[1] = i1; 619 620 /* ps0 = add (dn[i0], dn[i1], pOverflow);*/ 621 ps0 = (Word16)((Word32) dn[i0] + dn[i1]); 622 623 /* alp0 = L_mult (rr[i0][i0], _1_16, pOverflow); */ 624 alp0 = (Word32) rr[i0][i0] << 12; 625 626 /* alp0 = L_mac (alp0, rr[i1][i1], _1_16, pOverflow); */ 627 alp0 += (Word32) rr[i1][i1] << 12; 628 629 /* alp0 = L_mac (alp0, rr[i0][i1], _1_8, pOverflow); */ 630 alp0 += (Word32) rr[i0][i1] << 13; 631 alp0 += 0x00008000L; 632 633 /*----------------------------------------------------------------* 634 * i2 and i3 loop: * 635 *----------------------------------------------------------------*/ 636 637 p_temp1 = temp1; 638 for (i3 = ipos[3]; i3 < L_CODE; i3 += step) 639 { 640 p_temp2 = &rr[i3][0]; 641 s = (Word32) * (p_temp2 + i3) >> 1; 642 s += (Word32) * (p_temp2 + i0); 643 s += (Word32) * (p_temp2 + i1); 644 *(p_temp1++) = ps0 + dn[i3]; 645 *(p_temp1++) = (Word16)((s + 2) >> 2); 646 } 647 648 /* Default value */ 649 sq = -1; 650 alp = 1; 651 ps = 0; 652 ia = ipos[2]; 653 ib = ipos[3]; 654 655 s = (alp0 >> 12); 656 657 for (j = ipos[2]; j < L_CODE; j += step) 658 { 659 /* index increment = step */ 660 p_temp2 = &rr[j][0]; 661 662 alp1 = (s + (Word32) * (p_temp2 + j)) >> 1; 663 664 alp1 += (Word32) * (p_temp2 + i0); 665 666 alp1 += (Word32) * (p_temp2 + i1); 667 668 p_temp1 = temp1; 669 ps1 = dn[j]; 670 671 672 for (i3 = ipos[3]; i3 < L_CODE; i3 += step) 673 { 674 /* index increment = step */ 675 ps2 = ps1 + *(p_temp1++); 676 677 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); 678 679 alp2 = (alp1 + p_temp2[i3]) >> 2; 680 alp2 = (alp2 + *(p_temp1++)) >> 1; /* alp2 is always > 0 */ 681 if (((Word32) sq2 * alp) > ((Word32) sq * alp2)) 682 { 683 sq = sq2; 684 ps = ps2; 685 alp = (Word16)alp2; 686 ia = j; 687 ib = i3; 688 } 689 } 690 691 } 692 i2 = ia; 693 i3 = ib; 694 index[2] = ia; 695 index[3] = ib; 696 697 /*----------------------------------------------------------------* 698 * i4 and i5 loop: * 699 *----------------------------------------------------------------*/ 700 701 alp0 = ((Word32) alp << 15) + 0x00008000L; 702 p_temp1 = temp1; 703 704 for (i5 = ipos[5]; i5 < L_CODE; i5 += step) 705 { 706 p_temp2 = &rr[i5][0]; 707 s = (Word32) * (p_temp2 + i5) >> 1; 708 s += (Word32) * (p_temp2 + i0); 709 s += (Word32) * (p_temp2 + i1); 710 s += (Word32) * (p_temp2 + i2); 711 s += (Word32) * (p_temp2 + i3); 712 713 *(p_temp1++) = ps + dn[i5]; 714 *(p_temp1++) = (Word16)((s + 2) >> 2); 715 } 716 717 /* Default value */ 718 sq = -1; 719 alp = 1; 720 ps = 0; 721 ia = ipos[4]; 722 ib = ipos[5]; 723 724 for (j = ipos[4]; j < L_CODE; j += step) 725 { 726 /* ps1 = add (ps0, dn[i4], pOverflow); */ 727 p_temp2 = &rr[j][0]; 728 729 /* alp1 = L_mac (alp0, rr[i4][i4], _1_32, pOverflow); */ 730 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 11); 731 732 /* alp1 = L_mac (alp1, rr[i0][i4], _1_16, pOverflow); */ 733 alp1 += (Word32) * (p_temp2 + i0) << 12; 734 735 /* alp1 = L_mac (alp1, rr[i1][i4], _1_16, pOverflow); */ 736 alp1 += (Word32) * (p_temp2 + i1) << 12; 737 738 /* alp1 = L_mac (alp1, rr[i2][i4], _1_16, pOverflow); */ 739 alp1 += (Word32) * (p_temp2 + i2) << 12; 740 741 /* alp1 = L_mac (alp1, rr[i3][i4], _1_16, pOverflow); */ 742 alp1 += (Word32) * (p_temp2 + i3) << 12; 743 744 p_temp1 = temp1; 745 ps1 = dn[j]; 746 747 for (i5 = ipos[5]; i5 < L_CODE; i5 += step) 748 { 749 ps2 = ps1 + *(p_temp1++); 750 751 alp2 = alp1 + ((Word32) * (p_temp2 + i5) << 12); 752 753 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16); 754 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); 755 756 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16)) 757 { 758 sq = sq2; 759 ps = ps2; 760 alp = alp_16; 761 ia = j; 762 ib = i5; 763 } 764 765 } 766 } 767 i4 = ia; 768 i5 = ib; 769 index[4] = ia; 770 index[5] = ib; 771 772 /*----------------------------------------------------------------* 773 * i6 and i7 loop: * 774 *----------------------------------------------------------------*/ 775 776 alp0 = ((Word32) alp << 15) + 0x00008000L; 777 778 p_temp1 = temp1; 779 780 for (i7 = ipos[7]; i7 < L_CODE; i7 += step) 781 { 782 s = (Word32) rr[i7][i7] >> 1; 783 s += (Word32) rr[i0][i7]; 784 s += (Word32) rr[i1][i7]; 785 s += (Word32) rr[i2][i7]; 786 s += (Word32) rr[i3][i7]; 787 s += (Word32) rr[i4][i7]; 788 s += (Word32) rr[i5][i7]; 789 *(p_temp1++) = ps + dn[i7]; 790 *(p_temp1++) = (Word16)((s + 4) >> 3); 791 } 792 793 794 /* Default value */ 795 sq = -1; 796 alp = 1; 797 ps = 0; 798 ia = ipos[6]; 799 ib = ipos[7]; 800 801 for (j = ipos[6]; j < L_CODE; j += step) 802 { 803 /* ps1 = add (ps0, dn[i6], pOverflow); */ 804 805 p_temp2 = (Word16 *) & rr[j]; 806 807 /* alp1 = L_mac (alp0, rr[i6][i6], _1_64, pOverflow); */ 808 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 10); 809 810 /* alp1 = L_mac (alp1, rr[i0][i6], _1_32, pOverflow); */ 811 alp1 += (Word32) * (p_temp2 + i0) << 11; 812 813 814 /* alp1 = L_mac (alp1, rr[i1][i6], _1_32, pOverflow); */ 815 alp1 += (Word32) * (p_temp2 + i1) << 11; 816 817 /* alp1 = L_mac (alp1, rr[i2][i6], _1_32, pOverflow); */ 818 alp1 += (Word32) * (p_temp2 + i2) << 11; 819 820 /* alp1 = L_mac (alp1, rr[i3][i6], _1_32, pOverflow); */ 821 alp1 += (Word32) * (p_temp2 + i3) << 11; 822 823 /* alp1 = L_mac (alp1, rr[i4][i6], _1_32, pOverflow); */ 824 alp1 += (Word32) * (p_temp2 + i4) << 11; 825 826 /* alp1 = L_mac (alp1, rr[i5][i6], _1_32, pOverflow); */ 827 alp1 += (Word32) * (p_temp2 + i5) << 11; 828 829 p_temp1 = temp1; 830 ps1 = dn[j]; 831 832 for (i7 = ipos[7]; i7 < L_CODE; i7 += step) 833 { 834 ps2 = ps1 + *(p_temp1++); 835 836 alp2 = alp1 + ((Word32) * (p_temp2 + i7) << 11); 837 838 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 14)) >> 16); 839 840 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); 841 842 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16)) 843 { 844 sq = sq2; 845 ps = ps2; 846 alp = alp_16; 847 ia = j; 848 ib = i7; 849 } 850 } 851 } 852 853 i6 = ia; 854 i7 = ib; 855 index[6] = ia; 856 index[7] = ib; 857 858 /* now finished searching a set of 8 pulses */ 859 860 if (gsmefrFlag != 0) 861 { 862 /* go on with the two last pulses for GSMEFR */ 863 /*----------------------------------------------------------------* 864 * i8 and i9 loop: * 865 *----------------------------------------------------------------*/ 866 867 alp0 = ((Word32) alp << 15) + 0x00008000L; 868 869 p_temp1 = temp1; 870 871 for (i9 = ipos[9]; i9 < L_CODE; i9 += step) 872 { 873 s = (Word32) rr[i9][i9] >> 1; 874 s += (Word32) rr[i0][i9]; 875 s += (Word32) rr[i1][i9]; 876 s += (Word32) rr[i2][i9]; 877 s += (Word32) rr[i3][i9]; 878 s += (Word32) rr[i4][i9]; 879 s += (Word32) rr[i5][i9]; 880 s += (Word32) rr[i6][i9]; 881 s += (Word32) rr[i7][i9]; 882 883 *(p_temp1++) = ps + dn[i9]; 884 *(p_temp1++) = (Word16)((s + 4) >> 3); 885 } 886 887 /* Default value */ 888 sq = -1; 889 alp = 1; 890 ps = 0; 891 ia = ipos[8]; 892 ib = ipos[9]; 893 894 for (j = ipos[8]; j < L_CODE; j += step) 895 { 896 /* ps1 = add (ps0, dn[i8], pOverflow); */ 897 p_temp2 = &rr[j][0]; 898 899 /* alp1 = L_mac (alp0, rr[i8][i8], _1_128, pOverflow); */ 900 alp1 = alp0 + ((Word32) * (p_temp2 + j) << 9); 901 902 /* alp1 = L_mac (alp1, rr[i0][i8], _1_64, pOverflow); */ 903 alp1 += (Word32) rr[i0][j] << 10; 904 905 /* alp1 = L_mac (alp1, rr[i1][i8], _1_64, pOverflow); */ 906 alp1 += (Word32) rr[i1][j] << 10; 907 908 /* alp1 = L_mac (alp1, rr[i2][i8], _1_64, pOverflow); */ 909 alp1 += (Word32) rr[i2][j] << 10; 910 911 /* alp1 = L_mac (alp1, rr[i3][i8], _1_64, pOverflow); */ 912 alp1 += (Word32) rr[i3][j] << 10; 913 914 /* alp1 = L_mac (alp1, rr[i4][i8], _1_64, pOverflow); */ 915 alp1 += (Word32) rr[i4][j] << 10; 916 917 /* alp1 = L_mac (alp1, rr[i5][i8], _1_64, pOverflow); */ 918 alp1 += (Word32) rr[i5][j] << 10; 919 920 /* alp1 = L_mac (alp1, rr[i6][i8], _1_64, pOverflow); */ 921 alp1 += (Word32) rr[i6][j] << 10; 922 923 /* alp1 = L_mac (alp1, rr[i7][i8], _1_64, pOverflow); */ 924 alp1 += (Word32) rr[i7][j] << 10; 925 926 p_temp1 = temp1; 927 ps1 = dn[j]; 928 929 for (i9 = ipos[9]; i9 < L_CODE; i9 += step) 930 { 931 /* ps2 = add (ps1, dn[i9], pOverflow); */ 932 ps2 = ps1 + *(p_temp1++); 933 934 /* sq2 = mult (ps2, ps2, pOverflow); */ 935 sq2 = (Word16)(((Word32) ps2 * ps2) >> 15); 936 937 /* alp2 = L_mac (alp1, rrv[i9], _1_8, pOverflow); */ 938 alp2 = alp1 + ((Word32) * (p_temp2 + i9) << 10) ; 939 940 /* alp2 = L_mac (alp2, rr[i8][i9], _1_64, pOverflow); */ 941 alp_16 = (Word16)((alp2 + ((Word32) * (p_temp1++) << 13)) >> 16); 942 943 if (((Word32) sq2 * alp) > ((Word32) sq * alp_16)) 944 { 945 sq = sq2; 946 ps = ps2; 947 alp = alp_16; 948 ia = j; 949 ib = i9; 950 } 951 } 952 } 953 954 index[8] = ia; 955 index[9] = ib; 956 957 }/* end gsmefrFlag */ 958 959 /*---------------------------------------------------------------- * 960 * test and memorise if this combination is better than the last one.* 961 *----------------------------------------------------------------*/ 962 963 if (((Word32) alpk * sq) > ((Word32) psk * alp)) 964 { 965 psk = sq; 966 alpk = alp; 967 968 if (gsmefrFlag != 0) 969 { 970 memcpy(codvec, index, (2*NB_TRACK)*sizeof(*index)); 971 } 972 else 973 { 974 memcpy(codvec, index, (2*NB_TRACK_MR102)*sizeof(*index)); 975 } 976 977 } 978 /*----------------------------------------------------------------* 979 * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). * 980 *----------------------------------------------------------------*/ 981 982 pos = ipos[1]; 983 for (j = 1, k = 2; k < nbPulse; j++, k++) 984 { 985 ipos[j] = ipos[k]; 986 } 987 ipos[nbPulse-1] = pos; 988 } /* end 1..nbTracks loop*/ 989 } 990 991