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 mul; 420 Word32 alp0; 421 Word32 alp1; 422 423 OSCL_UNUSED_ARG(pOverflow); 424 425 /* Default value */ 426 psk = -1; 427 alpk = 1; 428 for (i = 0; i < NB_PULSE; i++) 429 { 430 *(p_codvec++) = i; 431 } 432 433 for (track = 3; track < 5; track++) 434 { 435 /* fix starting position */ 436 437 ipos[0] = 0; 438 ipos[1] = 1; 439 ipos[2] = 2; 440 ipos[3] = track; 441 442 /*------------------------------------------------------------------* 443 * main loop: try 4 tracks. * 444 *------------------------------------------------------------------*/ 445 446 for (i = 0; i < NB_PULSE; i++) 447 { 448 /*----------------------------------------------------------------* 449 * i0 loop: try 4 positions (use position with max of corr.). * 450 *----------------------------------------------------------------*/ 451 452 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) 453 { 454 if (dn2[i0] >= 0) 455 { 456 ps0 = dn[i0]; 457 458 alp0 = (Word32) rr[i0][i0] << 14; 459 460 /*----------------------------------------------------------------* 461 * i1 loop: 8 positions. * 462 *----------------------------------------------------------------*/ 463 464 sq = -1; 465 alp = 1; 466 ps = 0; 467 ix = ipos[1]; 468 469 /* initialize 4 index for next loop. */ 470 /*-------------------------------------------------------------------* 471 * These index have low complexity address computation because * 472 * they are, in fact, pointers with fixed increment. For example, * 473 * "rr[i0][i3]" is a pointer initialized to "&rr[i0][ipos[3]]" * 474 * and incremented by "STEP". * 475 *-------------------------------------------------------------------*/ 476 477 for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) 478 { 479 /* idx increment = STEP */ 480 /* ps1 = add(ps0, dn[i1], pOverflow); */ 481 ps1 = ps0 + dn[i1]; 482 483 /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ 484 485 /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */ 486 alp1 = alp0 + ((Word32) rr[i1][i1] << 14); 487 488 /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */ 489 alp1 += (Word32) rr[i0][i1] << 15; 490 491 /* sq1 = mult(ps1, ps1, pOverflow); */ 492 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 493 494 /* alp_16 = pv_round(alp1, pOverflow); */ 495 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 496 497 /* s = L_mult(alp, sq1, pOverflow); */ 498 s = ((Word32) alp * sq1) << 1; 499 500 /* s = L_msu(s, sq, alp_16, pOverflow); */ 501 __builtin_mul_overflow(sq, alp_16, &mul); 502 __builtin_sub_overflow(s, (mul << 1), &s); 503 504 if (s > 0) 505 { 506 sq = sq1; 507 ps = ps1; 508 alp = alp_16; 509 ix = i1; 510 } 511 } 512 i1 = ix; 513 514 /*----------------------------------------------------------------* 515 * i2 loop: 8 positions. * 516 *----------------------------------------------------------------*/ 517 518 ps0 = ps; 519 520 /* alp0 = L_mult(alp, _1_4, pOverflow); */ 521 alp0 = (Word32) alp << 14; 522 523 sq = -1; 524 alp = 1; 525 ps = 0; 526 ix = ipos[2]; 527 528 /* initialize 4 index for next loop (see i1 loop) */ 529 530 for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP) 531 { 532 /* index increment = STEP */ 533 /* ps1 = add(ps0, dn[i2], pOverflow); */ 534 ps1 = ps0 + dn[i2]; 535 536 /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */ 537 538 /* idx incr = STEP */ 539 /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */ 540 alp1 = alp0 + ((Word32) rr[i2][i2] << 12); 541 542 /* idx incr = STEP */ 543 /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */ 544 alp1 += (Word32) rr[i1][i2] << 13; 545 546 /* idx incr = STEP */ 547 /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */ 548 alp1 += (Word32) rr[i0][i2] << 13; 549 550 /* sq1 = mult(ps1, ps1, pOverflow); */ 551 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 552 553 /* alp_16 = pv_round(alp1, pOverflow); */ 554 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 555 556 /* s = L_mult(alp, sq1, pOverflow); */ 557 s = ((Word32) alp * sq1) << 1; 558 559 /* s = L_msu(s, sq, alp_16, pOverflow); */ 560 s -= (((Word32) sq * alp_16) << 1); 561 562 if (s > 0) 563 { 564 sq = sq1; 565 ps = ps1; 566 alp = alp_16; 567 ix = i2; 568 } 569 } 570 i2 = ix; 571 572 /*----------------------------------------------------------------* 573 * i3 loop: 8 positions. * 574 *----------------------------------------------------------------*/ 575 576 ps0 = ps; 577 alp0 = L_deposit_h(alp); 578 579 sq = -1; 580 alp = 1; 581 ps = 0; 582 ix = ipos[3]; 583 584 /* initialize 5 index for next loop (see i1 loop) */ 585 586 for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP) 587 { 588 /* ps1 = add(ps0, dn[i3], pOverflow); */ 589 ps1 = ps0 + dn[i3]; /* index increment = STEP */ 590 591 /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */ 592 593 /* alp1 = L_mac(alp0, rr[i3][i3], _1_16, pOverflow); */ 594 alp1 = alp0 + ((Word32) rr[i3][i3] << 12); /* idx incr = STEP */ 595 596 /* alp1 = L_mac(alp1, rr[i2][i3], _1_8, pOverflow); */ 597 alp1 += (Word32) rr[i2][i3] << 13; /* idx incr = STEP */ 598 599 /* alp1 = L_mac(alp1, rr[i1][i3], _1_8, pOverflow); */ 600 alp1 += (Word32) rr[i1][i3] << 13; /* idx incr = STEP */ 601 602 /* alp1 = L_mac(alp1, rr[i0][i3], _1_8, pOverflow); */ 603 alp1 += (Word32) rr[i0][i3] << 13; /* idx incr = STEP */ 604 605 /* sq1 = mult(ps1, ps1, pOverflow); */ 606 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 607 608 /* alp_16 = pv_round(alp1, pOverflow); */ 609 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 610 611 /* s = L_mult(alp, sq1, pOverflow); */ 612 s = ((Word32) alp * sq1) << 1; 613 614 /* s = L_msu(s, sq, alp_16, pOverflow); */ 615 __builtin_mul_overflow(sq, alp_16, &mul); 616 __builtin_sub_overflow(s, (mul << 1), &s); 617 618 if (s > 0) 619 { 620 sq = sq1; 621 ps = ps1; 622 alp = alp_16; 623 ix = i3; 624 } 625 } 626 627 628 /*----------------------------------------------------------------* 629 * memorise codevector if this one is better than the last one. * 630 *----------------------------------------------------------------*/ 631 632 /* s = L_mult(alpk, sq, pOverflow); */ 633 s = ((Word32) alpk * sq) << 1; 634 635 /* s = L_msu(s, psk, alp, pOverflow); */ 636 __builtin_mul_overflow(psk, alp, &mul); 637 __builtin_sub_overflow(s, (mul << 1), &s); 638 639 if (s > 0) 640 { 641 psk = sq; 642 alpk = alp; 643 p_codvec = &codvec[0]; 644 645 *(p_codvec++) = i0; 646 *(p_codvec++) = i1; 647 *(p_codvec++) = i2; 648 *(p_codvec) = ix; 649 } 650 } 651 } 652 653 /*----------------------------------------------------------------* 654 * Cyclic permutation of i0,i1,i2 and i3. * 655 *----------------------------------------------------------------*/ 656 657 pos = ipos[3]; 658 ipos[3] = ipos[2]; 659 ipos[2] = ipos[1]; 660 ipos[1] = ipos[0]; 661 ipos[0] = pos; 662 } 663 } 664 665 return; 666 } 667 668 669 670 671 /****************************************************************************/ 672 673 /* 674 ------------------------------------------------------------------------------ 675 FUNCTION NAME: build_code() 676 ------------------------------------------------------------------------------ 677 INPUT AND OUTPUT DEFINITIONS 678 679 Inputs: 680 codvec[] Array of type Word16 -- position of pulses 681 dn_sign[] Array of type Word16 -- sign of pulses 682 h[] Array of type Word16 -- impulse response of 683 weighted synthesis filter 684 685 Outputs: 686 cod[] Array of type Word16 -- innovative code vector 687 y[] Array of type Word16 -- filtered innovative code 688 sign[] Array of type Word16 -- index of 4 pulses (sign + position) 689 pOverflow Pointer to Flag -- set when overflow occurs 690 691 Returns: 692 indx 693 694 Global Variables Used: 695 None 696 697 Local Variables Needed: 698 699 ------------------------------------------------------------------------------ 700 FUNCTION DESCRIPTION 701 702 PURPOSE: Builds the codeword, the filtered codeword and index of the 703 codevector, based on the signs and positions of 4 pulses. 704 705 ------------------------------------------------------------------------------ 706 REQUIREMENTS 707 708 None 709 710 ------------------------------------------------------------------------------ 711 REFERENCES 712 713 [1] c4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 714 715 ------------------------------------------------------------------------------ 716 PSEUDO-CODE 717 718 ------------------------------------------------------------------------------ 719 RESOURCES USED [optional] 720 721 When the code is written for a specific target processor the 722 the resources used should be documented below. 723 724 HEAP MEMORY USED: x bytes 725 726 STACK MEMORY USED: x bytes 727 728 CLOCK CYCLES: (cycle count equation for this function) + (variable 729 used to represent cycle count for each subroutine 730 called) 731 where: (cycle count variable) = cycle count for [subroutine 732 name] 733 734 ------------------------------------------------------------------------------ 735 CAUTION [optional] 736 [State any special notes, constraints or cautions for users of this function] 737 738 ------------------------------------------------------------------------------ 739 */ 740 741 static Word16 build_code(Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)742 build_code( 743 Word16 codvec[], /* i : position of pulses */ 744 Word16 dn_sign[], /* i : sign of pulses */ 745 Word16 cod[], /* o : innovative code vector */ 746 Word16 h[], /* i : impulse response of weighted synthesis filter */ 747 Word16 y[], /* o : filtered innovative code */ 748 Word16 sign[], /* o : index of 4 pulses (sign+position) */ 749 Flag * pOverflow /* o : Flag set when overflow occurs */ 750 ) 751 { 752 Word16 i; 753 Word16 j; 754 Word16 k; 755 Word16 track; 756 Word16 index; 757 Word16 _sign[NB_PULSE]; 758 Word16 indx; 759 Word16 rsign; 760 761 Word16 *p0; 762 Word16 *p1; 763 Word16 *p2; 764 Word16 *p3; 765 Word16 *p_cod = &cod[0]; 766 767 Word32 s; 768 769 for (i = 0; i < L_CODE; i++) 770 { 771 *(p_cod++) = 0; 772 } 773 774 indx = 0; 775 rsign = 0; 776 777 for (k = 0; k < NB_PULSE; k++) 778 { 779 i = codvec[k]; /* read pulse position */ 780 j = dn_sign[i]; /* read sign */ 781 782 /* index = pos/5 */ 783 /* index = mult(i, 6554, pOverflow); */ 784 index = (Word16)(((Word32) i * 6554) >> 15); 785 786 /* track = pos%5 */ 787 /* s = L_mult(index, 5, pOverflow); */ 788 s = ((Word32) index * 5) << 1; 789 790 /* s = L_shr(s, 1, pOverflow); */ 791 s >>= 1; 792 793 /* track = sub(i, (Word16) s, pOverflow); */ 794 track = i - (Word16) s; 795 796 index = gray[index]; 797 798 if (track == 1) 799 { 800 /* index = shl(index, 3, pOverflow); */ 801 index <<= 3; 802 } 803 else if (track == 2) 804 { 805 /* index = shl(index, 6, pOverflow); */ 806 index <<= 6; 807 } 808 else if (track == 3) 809 { 810 /* index = shl(index, 10, pOverflow); */ 811 index <<= 10; 812 } 813 else if (track == 4) 814 { 815 track = 3; 816 817 /* index = shl(index, 10, pOverflow); */ 818 index <<= 10; 819 820 /* index = add(index, 512, pOverflow); */ 821 index += 512; 822 } 823 824 if (j > 0) 825 { 826 cod[i] = 8191; 827 _sign[k] = 32767; 828 829 /* track = shl(1, track, pOverflow); */ 830 track = 1 << track; 831 832 /* rsign = add(rsign, track, pOverflow); */ 833 rsign += track; 834 } 835 else 836 { 837 cod[i] = -8192; 838 _sign[k] = (Word16) - 32768L; 839 } 840 841 /* indx = add(indx, index, pOverflow); */ 842 indx += index; 843 } 844 *sign = rsign; 845 846 p0 = h - codvec[0]; 847 p1 = h - codvec[1]; 848 p2 = h - codvec[2]; 849 p3 = h - codvec[3]; 850 851 for (i = 0; i < L_CODE; i++) 852 { 853 s = 0; 854 s = 855 L_mac( 856 s, 857 *p0++, 858 _sign[0], 859 pOverflow); 860 861 s = 862 L_mac( 863 s, 864 *p1++, 865 _sign[1], 866 pOverflow); 867 868 s = 869 L_mac( 870 s, 871 *p2++, 872 _sign[2], 873 pOverflow); 874 875 s = 876 L_mac( 877 s, 878 *p3++, 879 _sign[3], 880 pOverflow); 881 882 y[i] = 883 pv_round( 884 s, 885 pOverflow); 886 887 } /* for (i = 0; i < L_CODE; i++) */ 888 889 return indx; 890 891 } /* build_code */ 892 893 #ifdef __cplusplus 894 } 895 #endif 896