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/c4_17pf.c 35 Functions: 36 37 Date: 05/26/2000 38 39 ------------------------------------------------------------------------------ 40 REVISION HISTORY 41 42 Description: Modified to pass overflow flag through to basic math function. 43 The flag is passed back to the calling function by pointer reference. 44 45 Description: Optimized functions to further reduce clock cycle usage. 46 Updated copyright year, removed unnecessary include files, 47 and removed unused #defines. 48 49 Description: Changed round function name to pv_round to avoid conflict with 50 round function in C standard library. 51 52 Description: Replaced "int" and/or "char" with OSCL defined types. 53 54 Description: Added #ifdef __cplusplus around extern'ed table. 55 56 Description: 57 58 ------------------------------------------------------------------------------ 59 MODULE DESCRIPTION 60 61 Purpose : Searches a 17 bit algebraic codebook containing 4 pulses 62 in a frame of 40 samples 63 ------------------------------------------------------------------------------ 64 */ 65 66 /*---------------------------------------------------------------------------- 67 ; INCLUDES 68 ----------------------------------------------------------------------------*/ 69 #include "c4_17pf.h" 70 #include "typedef.h" 71 #include "inv_sqrt.h" 72 #include "cnst.h" 73 #include "cor_h.h" 74 #include "set_sign.h" 75 #include "basic_op.h" 76 77 /*--------------------------------------------------------------------------*/ 78 #ifdef __cplusplus 79 extern "C" 80 { 81 #endif 82 83 /*---------------------------------------------------------------------------- 84 ; MACROS 85 ; Define module specific macros here 86 ----------------------------------------------------------------------------*/ 87 88 /*---------------------------------------------------------------------------- 89 ; DEFINES 90 ; Include all pre-processor statements here. Include conditional 91 ; compile variables also. 92 ----------------------------------------------------------------------------*/ 93 #define NB_PULSE 4 94 95 /*---------------------------------------------------------------------------- 96 ; LOCAL FUNCTION DEFINITIONS 97 ; Function Prototype declaration 98 ----------------------------------------------------------------------------*/ 99 100 static void search_4i40( 101 Word16 dn[], /* i : correlation between target and h[] */ 102 Word16 dn2[], /* i : maximum of corr. in each track. */ 103 Word16 rr[][L_CODE],/* i : matrix of autocorrelation */ 104 Word16 codvec[], /* o : algebraic codebook vector */ 105 Flag * pOverflow /* o : Flag set when overflow occurs */ 106 ); 107 108 static Word16 build_code( 109 Word16 codvec[], /* i : algebraic codebook vector */ 110 Word16 dn_sign[], /* i : sign of dn[] */ 111 Word16 cod[], /* o : algebraic (fixed) codebook excitation */ 112 Word16 h[], /* i : impulse response of weighted synthesis filter */ 113 Word16 y[], /* o : filtered fixed codebook excitation */ 114 Word16 sign[], /* o : index of 4 pulses (position+sign+ampl)*4 */ 115 Flag * pOverflow /* o : Flag set when overflow occurs */ 116 ); 117 118 /*---------------------------------------------------------------------------- 119 ; LOCAL VARIABLE DEFINITIONS 120 ; Variable declaration - defined here and used outside this module 121 ----------------------------------------------------------------------------*/ 122 123 /*---------------------------------------------------------------------------- 124 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 125 ; Declare variables used in this module but defined elsewhere 126 ----------------------------------------------------------------------------*/ 127 extern const Word16 gray[]; 128 extern const Word16 dgray[]; 129 130 /* 131 ------------------------------------------------------------------------------ 132 FUNCTION NAME: code_4i40_17bits() 133 ------------------------------------------------------------------------------ 134 INPUT AND OUTPUT DEFINITIONS 135 136 Inputs: 137 x[] Array of type Word16 -- target vector 138 h[] Array of type Word16 -- impulse response of weighted synthesis filter 139 h[-L_subfr..-1] must be set to zero. 140 141 T0 Array of type Word16 -- Pitch lag 142 pitch_sharp, Array of type Word16 -- Last quantized pitch gain 143 144 Outputs: 145 code[] Array of type Word16 -- Innovative codebook 146 y[] Array of type Word16 -- filtered fixed codebook excitation 147 * sign Pointer of type Word16 -- Pointer to the signs of 4 pulses 148 pOverflow Pointer to Flag -- set when overflow occurs 149 150 Returns: 151 index 152 153 Global Variables Used: 154 None 155 156 Local Variables Needed: 157 158 ------------------------------------------------------------------------------ 159 FUNCTION DESCRIPTION 160 161 PURPOSE: Searches a 17 bit algebraic codebook containing 4 pulses 162 in a frame of 40 samples. 163 164 DESCRIPTION: 165 The code length is 40, containing 4 nonzero pulses: i0...i3. 166 All pulses can have two possible amplitudes: +1 or -1. 167 Pulse i0 to i2 can have 8 possible positions, pulse i3 can have 168 2x8=16 positions. 169 170 i0 : 0, 5, 10, 15, 20, 25, 30, 35. 171 i1 : 1, 6, 11, 16, 21, 26, 31, 36. 172 i2 : 2, 7, 12, 17, 22, 27, 32, 37. 173 i3 : 3, 8, 13, 18, 23, 28, 33, 38. 174 4, 9, 14, 19, 24, 29, 34, 39. 175 176 ------------------------------------------------------------------------------ 177 REQUIREMENTS 178 179 None 180 181 ------------------------------------------------------------------------------ 182 REFERENCES 183 184 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 185 186 ------------------------------------------------------------------------------ 187 PSEUDO-CODE 188 189 ------------------------------------------------------------------------------ 190 RESOURCES USED [optional] 191 192 When the code is written for a specific target processor the 193 the resources used should be documented below. 194 195 HEAP MEMORY USED: x bytes 196 197 STACK MEMORY USED: x bytes 198 199 CLOCK CYCLES: (cycle count equation for this function) + (variable 200 used to represent cycle count for each subroutine 201 called) 202 where: (cycle count variable) = cycle count for [subroutine 203 name] 204 205 ------------------------------------------------------------------------------ 206 CAUTION [optional] 207 [State any special notes, constraints or cautions for users of this function] 208 209 ------------------------------------------------------------------------------ 210 */ 211 code_4i40_17bits(Word16 x[],Word16 h[],Word16 T0,Word16 pitch_sharp,Word16 code[],Word16 y[],Word16 * sign,Flag * pOverflow)212 Word16 code_4i40_17bits( 213 Word16 x[], /* i : target vector */ 214 Word16 h[], /* i : impulse response of weighted synthesis filter */ 215 /* h[-L_subfr..-1] must be set to zero. */ 216 Word16 T0, /* i : Pitch lag */ 217 Word16 pitch_sharp, /* i : Last quantized pitch gain */ 218 Word16 code[], /* o : Innovative codebook */ 219 Word16 y[], /* o : filtered fixed codebook excitation */ 220 Word16 * sign, /* o : Signs of 4 pulses */ 221 Flag * pOverflow /* o : Flag set when overflow occurs */ 222 ) 223 { 224 Word16 codvec[NB_PULSE]; 225 Word16 dn[L_CODE]; 226 Word16 dn2[L_CODE]; 227 Word16 dn_sign[L_CODE]; 228 229 Word16 rr[L_CODE][L_CODE]; 230 Word16 i; 231 Word16 index; 232 Word16 sharp; 233 Word16 tempWord; 234 235 sharp = pitch_sharp << 1; 236 237 if (T0 < L_CODE) 238 { 239 for (i = T0; i < L_CODE; i++) 240 { 241 tempWord = 242 mult( 243 h[i - T0], 244 sharp, 245 pOverflow); 246 247 h[i] = 248 add( 249 h[i], 250 tempWord, 251 pOverflow); 252 } 253 } 254 255 cor_h_x( 256 h, 257 x, 258 dn, 259 1, 260 pOverflow); 261 262 set_sign( 263 dn, 264 dn_sign, 265 dn2, 266 4); 267 268 cor_h( 269 h, 270 dn_sign, 271 rr, 272 pOverflow); 273 274 search_4i40( 275 dn, 276 dn2, 277 rr, 278 codvec, 279 pOverflow); 280 281 /* function result */ 282 index = 283 build_code( 284 codvec, 285 dn_sign, 286 code, 287 h, 288 y, 289 sign, 290 pOverflow); 291 292 /*-----------------------------------------------------------------* 293 * Compute innovation vector gain. * 294 * Include fixed-gain pitch contribution into code[]. * 295 *-----------------------------------------------------------------*/ 296 297 tempWord = T0 - L_CODE; 298 299 if (tempWord < 0) 300 { 301 for (i = T0; i < L_CODE; i++) 302 { 303 tempWord = 304 mult( 305 code[i - T0], 306 sharp, 307 pOverflow); 308 309 code[i] = 310 add( 311 code[i], 312 tempWord, 313 pOverflow); 314 } 315 } 316 317 return index; 318 } 319 /****************************************************************************/ 320 321 /* 322 ------------------------------------------------------------------------------ 323 FUNCTION NAME: search_4i40() 324 ------------------------------------------------------------------------------ 325 INPUT AND OUTPUT DEFINITIONS 326 327 Inputs: 328 dn[] Array of type Word16 -- correlation between target and h[] 329 dn2[] Array of type Word16 -- maximum of corr. in each track. 330 rr[][L_CODE] Double Array of type Word16 -- autocorrelation matrix 331 332 Outputs: 333 codvec[] Array of type Word16 -- algebraic codebook vector 334 pOverflow Pointer to Flag -- set when overflow occurs 335 336 Returns: 337 338 339 Global Variables Used: 340 None 341 342 Local Variables Needed: 343 344 345 ------------------------------------------------------------------------------ 346 FUNCTION DESCRIPTION 347 348 PURPOSE: Search the best codevector; determine positions of the 4 pulses 349 in the 40-sample frame. 350 351 ------------------------------------------------------------------------------ 352 REQUIREMENTS 353 354 None 355 356 ------------------------------------------------------------------------------ 357 REFERENCES 358 359 [1] c4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 360 361 ------------------------------------------------------------------------------ 362 PSEUDO-CODE 363 364 ------------------------------------------------------------------------------ 365 RESOURCES USED [optional] 366 367 When the code is written for a specific target processor the 368 the resources used should be documented below. 369 370 HEAP MEMORY USED: x bytes 371 372 STACK MEMORY USED: x bytes 373 374 CLOCK CYCLES: (cycle count equation for this function) + (variable 375 used to represent cycle count for each subroutine 376 called) 377 where: (cycle count variable) = cycle count for [subroutine 378 name] 379 380 ------------------------------------------------------------------------------ 381 CAUTION [optional] 382 [State any special notes, constraints or cautions for users of this function] 383 384 ------------------------------------------------------------------------------ 385 */ search_4i40(Word16 dn[],Word16 dn2[],Word16 rr[][L_CODE],Word16 codvec[],Flag * pOverflow)386 static void search_4i40( 387 Word16 dn[], /* i : correlation between target and h[] */ 388 Word16 dn2[], /* i : maximum of corr. in each track. */ 389 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ 390 Word16 codvec[], /* o : algebraic codebook vector */ 391 Flag * pOverflow /* o : Flag set when overflow occurs */ 392 ) 393 { 394 Word16 i0; 395 Word16 i1; 396 Word16 i2; 397 Word16 i3; 398 399 Word16 ix = 0; /* initialization only needed to keep gcc silent */ 400 Word16 ps = 0; /* initialization only needed to keep gcc silent */ 401 402 Word16 i; 403 Word16 pos; 404 Word16 track; 405 Word16 ipos[NB_PULSE]; 406 407 Word16 psk; 408 Word16 ps0; 409 Word16 ps1; 410 Word16 sq; 411 Word16 sq1; 412 413 Word16 alpk; 414 Word16 alp; 415 Word16 alp_16; 416 Word16 *p_codvec = &codvec[0]; 417 418 Word32 s; 419 Word32 alp0; 420 Word32 alp1; 421 422 OSCL_UNUSED_ARG(pOverflow); 423 424 /* Default value */ 425 psk = -1; 426 alpk = 1; 427 for (i = 0; i < NB_PULSE; i++) 428 { 429 *(p_codvec++) = i; 430 } 431 432 for (track = 3; track < 5; track++) 433 { 434 /* fix starting position */ 435 436 ipos[0] = 0; 437 ipos[1] = 1; 438 ipos[2] = 2; 439 ipos[3] = track; 440 441 /*------------------------------------------------------------------* 442 * main loop: try 4 tracks. * 443 *------------------------------------------------------------------*/ 444 445 for (i = 0; i < NB_PULSE; i++) 446 { 447 /*----------------------------------------------------------------* 448 * i0 loop: try 4 positions (use position with max of corr.). * 449 *----------------------------------------------------------------*/ 450 451 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) 452 { 453 if (dn2[i0] >= 0) 454 { 455 ps0 = dn[i0]; 456 457 alp0 = (Word32) rr[i0][i0] << 14; 458 459 /*----------------------------------------------------------------* 460 * i1 loop: 8 positions. * 461 *----------------------------------------------------------------*/ 462 463 sq = -1; 464 alp = 1; 465 ps = 0; 466 ix = ipos[1]; 467 468 /* initialize 4 index for next loop. */ 469 /*-------------------------------------------------------------------* 470 * These index have low complexity address computation because * 471 * they are, in fact, pointers with fixed increment. For example, * 472 * "rr[i0][i3]" is a pointer initialized to "&rr[i0][ipos[3]]" * 473 * and incremented by "STEP". * 474 *-------------------------------------------------------------------*/ 475 476 for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) 477 { 478 /* idx increment = STEP */ 479 /* ps1 = add(ps0, dn[i1], pOverflow); */ 480 ps1 = ps0 + dn[i1]; 481 482 /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ 483 484 /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */ 485 alp1 = alp0 + ((Word32) rr[i1][i1] << 14); 486 487 /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */ 488 alp1 += (Word32) rr[i0][i1] << 15; 489 490 /* sq1 = mult(ps1, ps1, pOverflow); */ 491 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 492 493 /* alp_16 = pv_round(alp1, pOverflow); */ 494 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 495 496 /* s = L_mult(alp, sq1, pOverflow); */ 497 s = ((Word32) alp * sq1) << 1; 498 499 /* s = L_msu(s, sq, alp_16, pOverflow); */ 500 s -= (((Word32) sq * alp_16) << 1); 501 502 if (s > 0) 503 { 504 sq = sq1; 505 ps = ps1; 506 alp = alp_16; 507 ix = i1; 508 } 509 } 510 i1 = ix; 511 512 /*----------------------------------------------------------------* 513 * i2 loop: 8 positions. * 514 *----------------------------------------------------------------*/ 515 516 ps0 = ps; 517 518 /* alp0 = L_mult(alp, _1_4, pOverflow); */ 519 alp0 = (Word32) alp << 14; 520 521 sq = -1; 522 alp = 1; 523 ps = 0; 524 ix = ipos[2]; 525 526 /* initialize 4 index for next loop (see i1 loop) */ 527 528 for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP) 529 { 530 /* index increment = STEP */ 531 /* ps1 = add(ps0, dn[i2], pOverflow); */ 532 ps1 = ps0 + dn[i2]; 533 534 /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ 535 536 /* idx incr = STEP */ 537 /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */ 538 alp1 = alp0 + ((Word32) rr[i2][i2] << 12); 539 540 /* idx incr = STEP */ 541 /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */ 542 alp1 += (Word32) rr[i1][i2] << 13; 543 544 /* idx incr = STEP */ 545 /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */ 546 alp1 += (Word32) rr[i0][i2] << 13; 547 548 /* sq1 = mult(ps1, ps1, pOverflow); */ 549 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 550 551 /* alp_16 = pv_round(alp1, pOverflow); */ 552 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 553 554 /* s = L_mult(alp, sq1, pOverflow); */ 555 s = ((Word32) alp * sq1) << 1; 556 557 /* s = L_msu(s, sq, alp_16, pOverflow); */ 558 s -= (((Word32) sq * alp_16) << 1); 559 560 if (s > 0) 561 { 562 sq = sq1; 563 ps = ps1; 564 alp = alp_16; 565 ix = i2; 566 } 567 } 568 i2 = ix; 569 570 /*----------------------------------------------------------------* 571 * i3 loop: 8 positions. * 572 *----------------------------------------------------------------*/ 573 574 ps0 = ps; 575 alp0 = L_deposit_h(alp); 576 577 sq = -1; 578 alp = 1; 579 ps = 0; 580 ix = ipos[3]; 581 582 /* initialize 5 index for next loop (see i1 loop) */ 583 584 for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP) 585 { 586 /* ps1 = add(ps0, dn[i3], pOverflow); */ 587 ps1 = ps0 + dn[i3]; /* index increment = STEP */ 588 589 /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ 590 591 /* alp1 = L_mac(alp0, rr[i3][i3], _1_16, pOverflow); */ 592 alp1 = alp0 + ((Word32) rr[i3][i3] << 12); /* idx incr = STEP */ 593 594 /* alp1 = L_mac(alp1, rr[i2][i3], _1_8, pOverflow); */ 595 alp1 += (Word32) rr[i2][i3] << 13; /* idx incr = STEP */ 596 597 /* alp1 = L_mac(alp1, rr[i1][i3], _1_8, pOverflow); */ 598 alp1 += (Word32) rr[i1][i3] << 13; /* idx incr = STEP */ 599 600 /* alp1 = L_mac(alp1, rr[i0][i3], _1_8, pOverflow); */ 601 alp1 += (Word32) rr[i0][i3] << 13; /* idx incr = STEP */ 602 603 /* sq1 = mult(ps1, ps1, pOverflow); */ 604 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 605 606 /* alp_16 = pv_round(alp1, pOverflow); */ 607 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 608 609 /* s = L_mult(alp, sq1, pOverflow); */ 610 s = ((Word32) alp * sq1) << 1; 611 612 /* s = L_msu(s, sq, alp_16, pOverflow); */ 613 s -= (((Word32) sq * alp_16) << 1); 614 615 if (s > 0) 616 { 617 sq = sq1; 618 ps = ps1; 619 alp = alp_16; 620 ix = i3; 621 } 622 } 623 624 625 /*----------------------------------------------------------------* 626 * memorise codevector if this one is better than the last one. * 627 *----------------------------------------------------------------*/ 628 629 /* s = L_mult(alpk, sq, pOverflow); */ 630 s = ((Word32) alpk * sq) << 1; 631 632 /* s = L_msu(s, psk, alp, pOverflow); */ 633 s -= (((Word32) psk * alp) << 1); 634 635 if (s > 0) 636 { 637 psk = sq; 638 alpk = alp; 639 p_codvec = &codvec[0]; 640 641 *(p_codvec++) = i0; 642 *(p_codvec++) = i1; 643 *(p_codvec++) = i2; 644 *(p_codvec) = ix; 645 } 646 } 647 } 648 649 /*----------------------------------------------------------------* 650 * Cyclic permutation of i0,i1,i2 and i3. * 651 *----------------------------------------------------------------*/ 652 653 pos = ipos[3]; 654 ipos[3] = ipos[2]; 655 ipos[2] = ipos[1]; 656 ipos[1] = ipos[0]; 657 ipos[0] = pos; 658 } 659 } 660 661 return; 662 } 663 664 665 666 667 /****************************************************************************/ 668 669 /* 670 ------------------------------------------------------------------------------ 671 FUNCTION NAME: build_code() 672 ------------------------------------------------------------------------------ 673 INPUT AND OUTPUT DEFINITIONS 674 675 Inputs: 676 codvec[] Array of type Word16 -- position of pulses 677 dn_sign[] Array of type Word16 -- sign of pulses 678 h[] Array of type Word16 -- impulse response of 679 weighted synthesis filter 680 681 Outputs: 682 cod[] Array of type Word16 -- innovative code vector 683 y[] Array of type Word16 -- filtered innovative code 684 sign[] Array of type Word16 -- index of 4 pulses (sign + position) 685 pOverflow Pointer to Flag -- set when overflow occurs 686 687 Returns: 688 indx 689 690 Global Variables Used: 691 None 692 693 Local Variables Needed: 694 695 ------------------------------------------------------------------------------ 696 FUNCTION DESCRIPTION 697 698 PURPOSE: Builds the codeword, the filtered codeword and index of the 699 codevector, based on the signs and positions of 4 pulses. 700 701 ------------------------------------------------------------------------------ 702 REQUIREMENTS 703 704 None 705 706 ------------------------------------------------------------------------------ 707 REFERENCES 708 709 [1] c4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 710 711 ------------------------------------------------------------------------------ 712 PSEUDO-CODE 713 714 ------------------------------------------------------------------------------ 715 RESOURCES USED [optional] 716 717 When the code is written for a specific target processor the 718 the resources used should be documented below. 719 720 HEAP MEMORY USED: x bytes 721 722 STACK MEMORY USED: x bytes 723 724 CLOCK CYCLES: (cycle count equation for this function) + (variable 725 used to represent cycle count for each subroutine 726 called) 727 where: (cycle count variable) = cycle count for [subroutine 728 name] 729 730 ------------------------------------------------------------------------------ 731 CAUTION [optional] 732 [State any special notes, constraints or cautions for users of this function] 733 734 ------------------------------------------------------------------------------ 735 */ 736 737 static Word16 build_code(Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)738 build_code( 739 Word16 codvec[], /* i : position of pulses */ 740 Word16 dn_sign[], /* i : sign of pulses */ 741 Word16 cod[], /* o : innovative code vector */ 742 Word16 h[], /* i : impulse response of weighted synthesis filter */ 743 Word16 y[], /* o : filtered innovative code */ 744 Word16 sign[], /* o : index of 4 pulses (sign+position) */ 745 Flag * pOverflow /* o : Flag set when overflow occurs */ 746 ) 747 { 748 Word16 i; 749 Word16 j; 750 Word16 k; 751 Word16 track; 752 Word16 index; 753 Word16 _sign[NB_PULSE]; 754 Word16 indx; 755 Word16 rsign; 756 757 Word16 *p0; 758 Word16 *p1; 759 Word16 *p2; 760 Word16 *p3; 761 Word16 *p_cod = &cod[0]; 762 763 Word32 s; 764 765 for (i = 0; i < L_CODE; i++) 766 { 767 *(p_cod++) = 0; 768 } 769 770 indx = 0; 771 rsign = 0; 772 773 for (k = 0; k < NB_PULSE; k++) 774 { 775 i = codvec[k]; /* read pulse position */ 776 j = dn_sign[i]; /* read sign */ 777 778 /* index = pos/5 */ 779 /* index = mult(i, 6554, pOverflow); */ 780 index = (Word16)(((Word32) i * 6554) >> 15); 781 782 /* track = pos%5 */ 783 /* s = L_mult(index, 5, pOverflow); */ 784 s = ((Word32) index * 5) << 1; 785 786 /* s = L_shr(s, 1, pOverflow); */ 787 s >>= 1; 788 789 /* track = sub(i, (Word16) s, pOverflow); */ 790 track = i - (Word16) s; 791 792 index = gray[index]; 793 794 if (track == 1) 795 { 796 /* index = shl(index, 3, pOverflow); */ 797 index <<= 3; 798 } 799 else if (track == 2) 800 { 801 /* index = shl(index, 6, pOverflow); */ 802 index <<= 6; 803 } 804 else if (track == 3) 805 { 806 /* index = shl(index, 10, pOverflow); */ 807 index <<= 10; 808 } 809 else if (track == 4) 810 { 811 track = 3; 812 813 /* index = shl(index, 10, pOverflow); */ 814 index <<= 10; 815 816 /* index = add(index, 512, pOverflow); */ 817 index += 512; 818 } 819 820 if (j > 0) 821 { 822 cod[i] = 8191; 823 _sign[k] = 32767; 824 825 /* track = shl(1, track, pOverflow); */ 826 track = 1 << track; 827 828 /* rsign = add(rsign, track, pOverflow); */ 829 rsign += track; 830 } 831 else 832 { 833 cod[i] = -8192; 834 _sign[k] = (Word16) - 32768L; 835 } 836 837 /* indx = add(indx, index, pOverflow); */ 838 indx += index; 839 } 840 *sign = rsign; 841 842 p0 = h - codvec[0]; 843 p1 = h - codvec[1]; 844 p2 = h - codvec[2]; 845 p3 = h - codvec[3]; 846 847 for (i = 0; i < L_CODE; i++) 848 { 849 s = 0; 850 s = 851 L_mac( 852 s, 853 *p0++, 854 _sign[0], 855 pOverflow); 856 857 s = 858 L_mac( 859 s, 860 *p1++, 861 _sign[1], 862 pOverflow); 863 864 s = 865 L_mac( 866 s, 867 *p2++, 868 _sign[2], 869 pOverflow); 870 871 s = 872 L_mac( 873 s, 874 *p3++, 875 _sign[3], 876 pOverflow); 877 878 y[i] = 879 pv_round( 880 s, 881 pOverflow); 882 883 } /* for (i = 0; i < L_CODE; i++) */ 884 885 return indx; 886 887 } /* build_code */ 888 889 #ifdef __cplusplus 890 } 891 #endif 892