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/c2_9pf.c 35 Funtions: code_2i40_9bits 36 search_2i40 37 Test_search_2i40 38 build_code 39 Test_build_code 40 41 Date: 05/26/2000 42 43 ------------------------------------------------------------------------------ 44 REVISION HISTORY 45 46 Description: Changed template used to PV coding template. First attempt at 47 optimizing C code. 48 49 Description: Updated file per comments gathered from Phase 2/3 review. 50 51 Description: Added setting of Overflow flag in inlined code. 52 53 Description: Synchronized file with UMTS version 3.2.0. Updated coding 54 template. 55 56 Description: Replaced basic_op.h with the header files of the math functions 57 used by the file. 58 59 Description: Made the following changes per comments from Phase 2/3 review: 60 1. Defined one local variable per line. 61 62 Description: Passed in pOverflow flag for EPOC compatibility. 63 64 Description: Optimized search_2i40() to reduce clock cycle usage. 65 66 Description: Removed unnecessary include files and #defines. 67 68 Description: Changed function name to pv_round to avoid conflict with 69 round function in C standard library. 70 71 Description: Replaced "int" and/or "char" with OSCL defined types. 72 73 Description: Added #ifdef __cplusplus around extern'ed table. 74 75 Description: 76 77 ------------------------------------------------------------------------------ 78 MODULE DESCRIPTION 79 80 This file contains the functions that search a 9 bit algebraic codebook 81 containing 2 pulses in a frame of 40 samples. 82 83 ------------------------------------------------------------------------------ 84 */ 85 86 /*---------------------------------------------------------------------------- 87 ; INCLUDES 88 ----------------------------------------------------------------------------*/ 89 #include "c2_9pf.h" 90 #include "typedef.h" 91 #include "basic_op.h" 92 #include "inv_sqrt.h" 93 #include "cnst.h" 94 #include "cor_h.h" 95 #include "cor_h_x.h" 96 #include "set_sign.h" 97 98 /*--------------------------------------------------------------------------*/ 99 #ifdef __cplusplus 100 extern "C" 101 { 102 #endif 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 #define NB_PULSE 2 115 116 /*---------------------------------------------------------------------------- 117 ; LOCAL FUNCTION DEFINITIONS 118 ; Function Prototype declaration 119 ----------------------------------------------------------------------------*/ 120 static void search_2i40( 121 Word16 subNr, /* i : subframe number */ 122 Word16 dn[], /* i : correlation between target and h[] */ 123 Word16 rr[][L_CODE],/* i : matrix of autocorrelation */ 124 Word16 codvec[], /* o : algebraic codebook vector */ 125 Flag * pOverflow /* o : Flag set when overflow occurs */ 126 ); 127 128 static Word16 build_code( 129 Word16 subNr, /* i : subframe number */ 130 Word16 codvec[], /* i : algebraic codebook vector */ 131 Word16 dn_sign[], /* i : sign of dn[] */ 132 Word16 cod[], /* o : algebraic (fixed) codebook excitation */ 133 Word16 h[], /* i : impulse response of weighted synthesis filter */ 134 Word16 y[], /* o : filtered fixed codebook excitation */ 135 Word16 sign[], /* o : sign of 2 pulses */ 136 Flag * pOverflow /* o : Flag set when overflow occurs */ 137 ); 138 139 /*---------------------------------------------------------------------------- 140 ; LOCAL VARIABLE DEFINITIONS 141 ; Variable declaration - defined here and used outside this module 142 ----------------------------------------------------------------------------*/ 143 144 const Word16 trackTable[4*5] = 145 { 146 0, 1, 0, 1, -1, /* subframe 1; track to code; 147 * -1 do not code this position 148 */ 149 0, -1, 1, 0, 1, /* subframe 2 */ 150 0, 1, 0, -1, 1, /* subframe 3 */ 151 0, 1, -1, 0, 1 152 };/* subframe 4 */ 153 154 155 /*---------------------------------------------------------------------------- 156 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 157 ; Declare variables used in this module but defined elsewhere 158 ----------------------------------------------------------------------------*/ 159 extern const Word16 startPos[]; 160 161 /* 162 ------------------------------------------------------------------------------ 163 FUNCTION NAME: code_2i40_9bits 164 ------------------------------------------------------------------------------ 165 INPUT AND OUTPUT DEFINITIONS 166 167 Inputs: 168 subNr = subframe number (Word16) 169 x = target buffer (Word16) 170 h = buffer containing the impulse response of the 171 weighted synthesis filter; h[-L_subfr .. -1] must be 172 set to zero (Word16) 173 T0 = pitch lag (Word16) 174 pitch_sharp = last quantized pitch gain (Word16) 175 code = buffer containing the innovative codebook (Word16) 176 y = buffer containing the filtered fixed codebook excitation (Word16) 177 sign = pointer to the signs of 2 pulses (Word16) 178 179 Outputs: 180 code buffer contains the new innovation vector gains 181 182 Returns: 183 index = code index (Word16) 184 185 Global Variables Used: 186 Overflow = overflow flag (Flag) 187 188 Local Variables Needed: 189 None 190 191 ------------------------------------------------------------------------------ 192 FUNCTION DESCRIPTION 193 194 This function searches a 9 bit algebraic codebook containing 2 pulses in a 195 frame of 40 samples. 196 197 The code length is 40, containing 2 nonzero pulses: i0...i1. All pulses can 198 have two possible amplitudes: +1 or -1. Pulse i0 can have 8 possible positions, 199 pulse i1 can have 8 positions. Also coded is which track pair should be used, 200 i.e. first or second pair. Where each pair contains 2 tracks. 201 202 First subframe: 203 first i0 : 0, 5, 10, 15, 20, 25, 30, 35. 204 i1 : 2, 7, 12, 17, 22, 27, 32, 37. 205 second i0 : 1, 6, 11, 16, 21, 26, 31, 36. 206 i1 : 3, 8, 13, 18, 23, 28, 33, 38. 207 208 Second subframe: 209 first i0 : 0, 5, 10, 15, 20, 25, 30, 35. 210 i1 : 3, 8, 13, 18, 23, 28, 33, 38. 211 second i0 : 2, 7, 12, 17, 22, 27, 32, 37. 212 i1 : 4, 9, 14, 19, 24, 29, 34, 39. 213 214 Third subframe: 215 first i0 : 0, 5, 10, 15, 20, 25, 30, 35. 216 i1 : 2, 7, 12, 17, 22, 27, 32, 37. 217 second i0 : 1, 6, 11, 16, 21, 26, 31, 36. 218 i1 : 4, 9, 14, 19, 24, 29, 34, 39. 219 220 Fourth subframe: 221 first i0 : 0, 5, 10, 15, 20, 25, 30, 35. 222 i1 : 3, 8, 13, 18, 23, 28, 33, 38. 223 second i0 : 1, 6, 11, 16, 21, 26, 31, 36. 224 i1 : 4, 9, 14, 19, 24, 29, 34, 39. 225 226 ------------------------------------------------------------------------------ 227 REQUIREMENTS 228 229 None 230 231 ------------------------------------------------------------------------------ 232 REFERENCES 233 234 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 235 236 ------------------------------------------------------------------------------ 237 PSEUDO-CODE 238 239 Word16 code_2i40_9bits( 240 Word16 subNr, // i : subframe number 241 Word16 x[], // i : target vector 242 Word16 h[], // i : impulse response of weighted synthesis filter 243 // h[-L_subfr..-1] must be set to zero. 244 Word16 T0, // i : Pitch lag 245 Word16 pitch_sharp, // i : Last quantized pitch gain 246 Word16 code[], // o : Innovative codebook 247 Word16 y[], // o : filtered fixed codebook excitation 248 Word16 * sign // o : Signs of 2 pulses 249 ) 250 { 251 Word16 codvec[NB_PULSE]; 252 Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE]; 253 Word16 rr[L_CODE][L_CODE]; 254 Word16 i, index, sharp; 255 256 sharp = shl(pitch_sharp, 1); 257 if (sub(T0, L_CODE) < 0) 258 for (i = T0; i < L_CODE; i++) { 259 h[i] = add(h[i], mult(h[i - T0], sharp)); 260 } 261 cor_h_x(h, x, dn, 1); 262 set_sign(dn, dn_sign, dn2, 8); // dn2[] not used in this codebook search 263 cor_h(h, dn_sign, rr); 264 search_2i40(subNr, dn, rr, codvec); 265 index = build_code(subNr, codvec, dn_sign, code, h, y, sign); 266 267 *-----------------------------------------------------------------* 268 * Compute innovation vector gain. * 269 * Include fixed-gain pitch contribution into code[]. * 270 *-----------------------------------------------------------------* 271 272 if (sub(T0, L_CODE) < 0) 273 for (i = T0; i < L_CODE; i++) { 274 code[i] = add(code[i], mult(code[i - T0], sharp)); 275 } 276 return index; 277 } 278 279 ------------------------------------------------------------------------------ 280 RESOURCES USED [optional] 281 282 When the code is written for a specific target processor the 283 the resources used should be documented below. 284 285 HEAP MEMORY USED: x bytes 286 287 STACK MEMORY USED: x bytes 288 289 CLOCK CYCLES: (cycle count equation for this function) + (variable 290 used to represent cycle count for each subroutine 291 called) 292 where: (cycle count variable) = cycle count for [subroutine 293 name] 294 295 ------------------------------------------------------------------------------ 296 CAUTION [optional] 297 [State any special notes, constraints or cautions for users of this function] 298 299 ------------------------------------------------------------------------------ 300 */ 301 code_2i40_9bits(Word16 subNr,Word16 x[],Word16 h[],Word16 T0,Word16 pitch_sharp,Word16 code[],Word16 y[],Word16 * sign,Flag * pOverflow)302 Word16 code_2i40_9bits( 303 Word16 subNr, /* i : subframe number */ 304 Word16 x[], /* i : target vector */ 305 Word16 h[], /* i : impulse response of weighted synthesis */ 306 /* filter h[-L_subfr..-1] must be set to 0. */ 307 Word16 T0, /* i : Pitch lag */ 308 Word16 pitch_sharp, /* i : Last quantized pitch gain */ 309 Word16 code[], /* o : Innovative codebook */ 310 Word16 y[], /* o : filtered fixed codebook excitation */ 311 Word16 * sign, /* o : Signs of 2 pulses */ 312 Flag * pOverflow /* o : Flag set when overflow occurs */ 313 ) 314 { 315 Word16 codvec[NB_PULSE]; 316 Word16 dn[L_CODE]; 317 Word16 dn2[L_CODE]; 318 Word16 dn_sign[L_CODE]; 319 Word16 rr[L_CODE][L_CODE]; 320 321 Word16 i; 322 323 Word16 index; 324 Word16 sharp; 325 Word16 temp; 326 Word32 L_temp; 327 328 L_temp = ((Word32) pitch_sharp) << 1; 329 330 /* Check for overflow condition */ 331 if (L_temp != (Word32)((Word16) L_temp)) 332 { 333 *(pOverflow) = 1; 334 sharp = (pitch_sharp > 0) ? MAX_16 : MIN_16; 335 } 336 else 337 { 338 sharp = (Word16) L_temp; 339 } 340 341 if (T0 < L_CODE) 342 { 343 for (i = T0; i < L_CODE; i++) 344 { 345 temp = 346 mult( 347 *(h + i - T0), 348 sharp, 349 pOverflow); 350 351 *(h + i) = 352 add( 353 *(h + i), 354 temp, 355 pOverflow); 356 } 357 } 358 359 cor_h_x( 360 h, 361 x, 362 dn, 363 1, 364 pOverflow); 365 366 /* dn2[] not used in this codebook search */ 367 368 set_sign( 369 dn, 370 dn_sign, 371 dn2, 372 8); 373 374 cor_h( 375 h, 376 dn_sign, 377 rr, 378 pOverflow); 379 380 search_2i40( 381 subNr, 382 dn, 383 rr, 384 codvec, 385 pOverflow); 386 387 index = 388 build_code( 389 subNr, 390 codvec, 391 dn_sign, 392 code, 393 h, 394 y, 395 sign, 396 pOverflow); 397 398 /*-----------------------------------------------------------------* 399 * Compute innovation vector gain. * 400 * Include fixed-gain pitch contribution into code[]. * 401 *-----------------------------------------------------------------*/ 402 403 if (T0 < L_CODE) 404 { 405 for (i = T0; i < L_CODE; i++) 406 { 407 temp = 408 mult( 409 *(code + i - T0), 410 sharp, 411 pOverflow); 412 413 *(code + i) = 414 add( 415 *(code + i), 416 temp, 417 pOverflow); 418 } 419 } 420 421 return(index); 422 } 423 424 /****************************************************************************/ 425 426 427 /* 428 ------------------------------------------------------------------------------ 429 FUNCTION NAME: search_2i40 430 ------------------------------------------------------------------------------ 431 INPUT AND OUTPUT DEFINITIONS 432 433 Inputs: 434 subNr = subframe number (Word16) 435 dn = vector containing the correlation between target and the impulse 436 response of the weighted synthesis filter (Word16) 437 rr = autocorrelation matrix (Word16) 438 codvec = algebraic codebook vector (Word16) 439 440 Outputs: 441 codvec contains the newly calculated codevectors 442 443 Returns: 444 None 445 446 Global Variables Used: 447 None 448 449 Local Variables Needed: 450 startPos = table containing the start positions used by fixed codebook 451 routines (const Word16) 452 453 ------------------------------------------------------------------------------ 454 FUNCTION DESCRIPTION 455 456 This function searches the best codevector and determines the positions of 457 the 2 pulses in the 40-sample frame. 458 459 ------------------------------------------------------------------------------ 460 REQUIREMENTS 461 462 None 463 464 ------------------------------------------------------------------------------ 465 REFERENCES 466 467 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 468 469 ------------------------------------------------------------------------------ 470 PSEUDO-CODE 471 472 static void search_2i40( 473 Word16 subNr, // i : subframe number 474 Word16 dn[], // i : correlation between target and h[] 475 Word16 rr[][L_CODE], // i : matrix of autocorrelation 476 Word16 codvec[] // o : algebraic codebook vector 477 ) 478 { 479 Word16 i0, i1; 480 Word16 ix = 0; // initialization only needed to keep gcc silent 481 Word16 track1, ipos[NB_PULSE]; 482 Word16 psk, ps0, ps1, sq, sq1; 483 Word16 alpk, alp, alp_16; 484 Word32 s, alp0, alp1; 485 Word16 i; 486 487 psk = -1; 488 alpk = 1; 489 for (i = 0; i < NB_PULSE; i++) 490 { 491 codvec[i] = i; 492 } 493 494 for (track1 = 0; track1 < 2; track1++) { 495 // fix starting position 496 497 ipos[0] = startPos[subNr*2+8*track1]; 498 ipos[1] = startPos[subNr*2+1+8*track1]; 499 500 501 *----------------------------------------------------------------* 502 * i0 loop: try 8 positions. * 503 *----------------------------------------------------------------* 504 505 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) { 506 507 ps0 = dn[i0]; 508 alp0 = L_mult(rr[i0][i0], _1_4); 509 510 *----------------------------------------------------------------* 511 * i1 loop: 8 positions. * 512 *----------------------------------------------------------------* 513 514 sq = -1; 515 alp = 1; 516 ix = ipos[1]; 517 518 *-------------------------------------------------------------------* 519 * These index have low complexity address computation because * 520 * they are, in fact, pointers with fixed increment. For example, * 521 * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" * 522 * and incremented by "STEP". * 523 *-------------------------------------------------------------------* 524 525 for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) { 526 ps1 = add(ps0, dn[i1]); // idx increment = STEP 527 528 // alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; 529 530 alp1 = L_mac(alp0, rr[i1][i1], _1_4); // idx incr = STEP 531 alp1 = L_mac(alp1, rr[i0][i1], _1_2); // idx incr = STEP 532 533 sq1 = mult(ps1, ps1); 534 535 alp_16 = pv_round(alp1); 536 537 s = L_msu(L_mult(alp, sq1), sq, alp_16); 538 539 if (s > 0) { 540 sq = sq1; 541 alp = alp_16; 542 ix = i1; 543 } 544 } 545 546 *----------------------------------------------------------------* 547 * memorise codevector if this one is better than the last one. * 548 *----------------------------------------------------------------* 549 550 s = L_msu(L_mult(alpk, sq), psk, alp); 551 552 if (s > 0) { 553 psk = sq; 554 alpk = alp; 555 codvec[0] = i0; 556 codvec[1] = ix; 557 } 558 } 559 } 560 561 return; 562 } 563 564 ------------------------------------------------------------------------------ 565 RESOURCES USED [optional] 566 567 When the code is written for a specific target processor the 568 the resources used should be documented below. 569 570 HEAP MEMORY USED: x bytes 571 572 STACK MEMORY USED: x bytes 573 574 CLOCK CYCLES: (cycle count equation for this function) + (variable 575 used to represent cycle count for each subroutine 576 called) 577 where: (cycle count variable) = cycle count for [subroutine 578 name] 579 580 ------------------------------------------------------------------------------ 581 CAUTION [optional] 582 [State any special notes, constraints or cautions for users of this function] 583 584 ------------------------------------------------------------------------------ 585 */ 586 search_2i40(Word16 subNr,Word16 dn[],Word16 rr[][L_CODE],Word16 codvec[],Flag * pOverflow)587 static void search_2i40( 588 Word16 subNr, /* i : subframe number */ 589 Word16 dn[], /* i : correlation between target and h[] */ 590 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ 591 Word16 codvec[], /* o : algebraic codebook vector */ 592 Flag * pOverflow /* o : Flag set when overflow occurs */ 593 ) 594 { 595 Word16 i0; 596 Word16 i1; 597 Word16 ix = 0; /* initialization only needed to keep gcc silent */ 598 Word16 track1; 599 Word16 ipos[NB_PULSE]; 600 Word16 psk; 601 Word16 ps0; 602 Word16 ps1; 603 Word16 sq; 604 Word16 sq1; 605 Word16 alpk; 606 Word16 alp; 607 Word16 alp_16; 608 Word32 s; 609 Word32 alp0; 610 Word32 alp1; 611 Word16 i; 612 Word32 L_temp; 613 Word32 mul; 614 Word16 *p_codvec = &codvec[0]; 615 616 OSCL_UNUSED_ARG(pOverflow); 617 618 psk = -1; 619 alpk = 1; 620 621 /* Unrolled the following FOR loop to save MIPS */ 622 /* for (i = 0; i < NB_PULSE; i++) */ 623 /* { */ 624 /* *(codvec + i) = i; */ 625 /* } */ 626 627 *(p_codvec++) = 0; 628 *(p_codvec) = 1; 629 630 for (track1 = 0; track1 < 2; track1++) 631 { 632 /* fix starting position */ 633 634 i = (subNr << 1) + (track1 << 3); 635 *ipos = *(startPos + i); 636 *(ipos + 1) = *(startPos + i + 1); 637 638 639 /*----------------------------------------------------------* 640 * i0 loop: try 8 positions. * 641 *----------------------------------------------------------*/ 642 643 for (i0 = *ipos; i0 < L_CODE; i0 += STEP) 644 { 645 ps0 = *(dn + i0); 646 647 /* Left shift by 1 converts integer product to */ 648 /* fractional product. */ 649 alp0 = (Word32) rr[i0][i0] << 14; 650 651 /*--------------------------------------------------* 652 * i1 loop: 8 positions. * 653 *--------------------------------------------------*/ 654 655 sq = -1; 656 alp = 1; 657 ix = *(ipos + 1); 658 659 /*--------------------------------------------------* 660 * These index have low complexity address * 661 * computation because they are, in fact, pointers * 662 * with fixed increment. For example, "rr[i0][i2]" * 663 * is a pointer initialized to "&rr[i0][ipos[2]]" * 664 * and incremented by "STEP". * 665 *---------------------------------------------------*/ 666 667 for (i1 = *(ipos + 1); i1 < L_CODE; i1 += STEP) 668 { 669 /* idx increment = STEP */ 670 /* ps1 = add(ps0, *(dn + i1), pOverflow); */ 671 ps1 = ps0 + dn[i1]; 672 673 /* alp1 = alp0+rr[i0][i1]+1/2*rr[i1][i1]; */ 674 675 /* idx incr = STEP */ 676 /* Extra left shift by 1 converts integer */ 677 /* product to fractional product */ 678 /* alp1 = L_add(alp0, s, pOverflow); */ 679 alp1 = alp0 + ((Word32) rr[i1][i1] << 14); 680 681 /* idx incr = STEP */ 682 /* Extra left shift by 1 converts integer */ 683 /* product to fractional product */ 684 /* alp1 = L_add(alp1, s, pOverflow); */ 685 alp1 += (Word32) rr[i0][i1] << 15; 686 687 /* sq1 = mult(ps1, ps1, pOverflow); */ 688 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 689 690 /* alp_16 = pv_round(alp1, pOverflow); */ 691 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 692 693 /* L_temp = L_mult(alp, sq1, pOverflow); */ 694 L_temp = ((Word32) alp * sq1) << 1; 695 696 /* s = L_msu(L_temp, sq, alp_16, pOverflow); */ 697 __builtin_mul_overflow(sq, alp_16, &mul); 698 __builtin_sub_overflow(L_temp, (mul << 1), &s); 699 700 if (s > 0) 701 { 702 sq = sq1; 703 alp = alp_16; 704 ix = i1; 705 } 706 } 707 708 /* memorize codevector if this one is better than the last one. */ 709 710 /* L_temp = L_mult(alpk, sq, pOverflow); */ 711 L_temp = ((Word32) alpk * sq) << 1; 712 713 /* s = L_msu(L_temp, psk, alp, pOverflow); */ 714 s = L_temp - (((Word32) psk * alp) << 1); 715 716 if (s > 0) 717 { 718 psk = sq; 719 alpk = alp; 720 p_codvec = &codvec[0]; 721 *(p_codvec++) = i0; 722 *(p_codvec) = ix; 723 } 724 } 725 } 726 727 return; 728 } 729 730 /****************************************************************************/ 731 732 /* 733 ------------------------------------------------------------------------------ 734 FUNCTION NAME: Test_search_2i40 735 ------------------------------------------------------------------------------ 736 INPUT AND OUTPUT DEFINITIONS 737 738 Inputs: 739 subNr = subframe number (Word16) 740 dn = vector containing the correlation between target and the impulse 741 response of the weighted synthesis filter (Word16) 742 rr = autocorrelation matrix (Word16) 743 codvec = algebraic codebook vector (Word16) 744 745 Outputs: 746 codvec contains the newly calculated codevectors 747 748 Returns: 749 None 750 751 Global Variables Used: 752 None 753 754 Local Variables Needed: 755 startPos = table containing the start positions used by fixed codebook 756 routines (const Word16) 757 758 ------------------------------------------------------------------------------ 759 FUNCTION DESCRIPTION 760 761 This function provides external access to the local function search_2i40. 762 763 ------------------------------------------------------------------------------ 764 REQUIREMENTS 765 766 None 767 768 ------------------------------------------------------------------------------ 769 REFERENCES 770 771 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 772 773 ------------------------------------------------------------------------------ 774 PSEUDO-CODE 775 776 CALL search_2i40 ( subNr = subNr 777 dn = dn 778 rr = rr 779 codvec = codvec ) 780 MODIFYING(nothing) 781 RETURNING(nothing) 782 783 ------------------------------------------------------------------------------ 784 RESOURCES USED [optional] 785 786 When the code is written for a specific target processor the 787 the resources used should be documented below. 788 789 HEAP MEMORY USED: x bytes 790 791 STACK MEMORY USED: x bytes 792 793 CLOCK CYCLES: (cycle count equation for this function) + (variable 794 used to represent cycle count for each subroutine 795 called) 796 where: (cycle count variable) = cycle count for [subroutine 797 name] 798 799 ------------------------------------------------------------------------------ 800 CAUTION [optional] 801 [State any special notes, constraints or cautions for users of this function] 802 803 ------------------------------------------------------------------------------ 804 */ 805 Test_search_2i40(Word16 subNr,Word16 dn[],Word16 rr[][L_CODE],Word16 codvec[],Flag * pOverflow)806 void Test_search_2i40( 807 Word16 subNr, /* i : subframe number */ 808 Word16 dn[], /* i : correlation between target and h[] */ 809 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ 810 Word16 codvec[], /* o : algebraic codebook vector */ 811 Flag * pOverflow /* o : Flag set when overflow occurs */ 812 ) 813 { 814 /*---------------------------------------------------------------------------- 815 CALL search_2i40 ( subNr = subNr 816 dn = dn 817 rr = rr 818 codvec = codvec ) 819 MODIFYING(nothing) 820 RETURNING(nothing) 821 ----------------------------------------------------------------------------*/ 822 search_2i40( 823 subNr, 824 dn, 825 rr, 826 codvec, 827 pOverflow); 828 829 return; 830 } 831 832 /****************************************************************************/ 833 834 /* 835 ------------------------------------------------------------------------------ 836 FUNCTION NAME: build_code 837 ------------------------------------------------------------------------------ 838 INPUT AND OUTPUT DEFINITIONS 839 840 Inputs: 841 subNr = subframe number (Word16) 842 codvec = vector containing the position of pulses (Word16) 843 dn_sign = vector containing the sign of pulses (Word16) 844 cod = innovative code vector (Word16) 845 h = vector containing the impulse response of the weighted 846 synthesis filter (Word16) 847 y = vector containing the filtered innovative code (Word16) 848 sign = vector containing the sign of 2 pulses (Word16) 849 850 Outputs: 851 cod vector contains the new innovative code 852 y vector contains the new filtered innovative code 853 sign vector contains the sign of 2 pulses 854 855 Returns: 856 indx = codebook index (Word16) 857 858 Global Variables Used: 859 None 860 861 Local Variables Needed: 862 trackTable = table used for tracking codewords (Word16) 863 864 ------------------------------------------------------------------------------ 865 FUNCTION DESCRIPTION 866 867 This function builds the codeword, the filtered codeword and index of the 868 codevector, based on the signs and positions of 2 pulses. 869 870 ------------------------------------------------------------------------------ 871 REQUIREMENTS 872 873 None 874 875 ------------------------------------------------------------------------------ 876 REFERENCES 877 878 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 879 880 ------------------------------------------------------------------------------ 881 PSEUDO-CODE 882 883 static Word16 build_code( 884 Word16 subNr, // i : subframe number 885 Word16 codvec[], // i : position of pulses 886 Word16 dn_sign[], // i : sign of pulses 887 Word16 cod[], // o : innovative code vector 888 Word16 h[], // i : impulse response of weighted synthesis filter 889 Word16 y[], // o : filtered innovative code 890 Word16 sign[] // o : sign of 2 pulses 891 ) 892 { 893 Word16 i, j, k, track, first, index, _sign[NB_PULSE], indx, rsign; 894 Word16 *p0, *p1, *pt; 895 Word32 s; 896 static Word16 trackTable[4*5] = { 897 0, 1, 0, 1, -1, // subframe 1; track to code; -1 do not code this position 898 0, -1, 1, 0, 1, // subframe 2 899 0, 1, 0, -1, 1, // subframe 3 900 0, 1, -1, 0, 1};// subframe 4 901 902 pt = &trackTable[add(subNr, shl(subNr, 2))]; 903 904 for (i = 0; i < L_CODE; i++) { 905 cod[i] = 0; 906 } 907 908 indx = 0; 909 rsign = 0; 910 for (k = 0; k < NB_PULSE; k++) { 911 i = codvec[k]; // read pulse position 912 j = dn_sign[i]; // read sign 913 914 index = mult(i, 6554); // index = pos/5 915 // track = pos%5 916 track = sub(i, extract_l(L_shr(L_mult(index, 5), 1))); 917 918 first = pt[track]; 919 920 if (first == 0) { 921 if (k == 0) { 922 track = 0; 923 } else { 924 track = 1; 925 index = shl(index, 3); 926 } 927 } else { 928 if (k == 0) { 929 track = 0; 930 index = add(index, 64); // table bit is MSB 931 } else { 932 track = 1; 933 index = shl(index, 3); 934 } 935 } 936 937 if (j > 0) { 938 cod[i] = 8191; 939 _sign[k] = 32767; 940 rsign = add(rsign, shl(1, track)); 941 } else { 942 cod[i] = -8192; 943 _sign[k] = (Word16) - 32768L; 944 } 945 946 indx = add(indx, index); 947 } 948 *sign = rsign; 949 950 p0 = h - codvec[0]; 951 p1 = h - codvec[1]; 952 953 for (i = 0; i < L_CODE; i++) { 954 s = 0; 955 s = L_mac(s, *p0++, _sign[0]); 956 s = L_mac(s, *p1++, _sign[1]); 957 y[i] = pv_round(s); 958 } 959 960 return indx; 961 } 962 963 ------------------------------------------------------------------------------ 964 RESOURCES USED [optional] 965 966 When the code is written for a specific target processor the 967 the resources used should be documented below. 968 969 HEAP MEMORY USED: x bytes 970 971 STACK MEMORY USED: x bytes 972 973 CLOCK CYCLES: (cycle count equation for this function) + (variable 974 used to represent cycle count for each subroutine 975 called) 976 where: (cycle count variable) = cycle count for [subroutine 977 name] 978 979 ------------------------------------------------------------------------------ 980 CAUTION [optional] 981 [State any special notes, constraints or cautions for users of this function] 982 983 ------------------------------------------------------------------------------ 984 */ 985 build_code(Word16 subNr,Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)986 static Word16 build_code( 987 Word16 subNr, /* i : subframe number */ 988 Word16 codvec[], /* i : position of pulses */ 989 Word16 dn_sign[], /* i : sign of pulses */ 990 Word16 cod[], /* o : innovative code vector */ 991 Word16 h[], /* i : impulse response of weighted synthesis */ 992 /* filter */ 993 Word16 y[], /* o : filtered innovative code */ 994 Word16 sign[], /* o : sign of 2 pulses */ 995 Flag *pOverflow /* o : Flag set when overflow occurs */ 996 ) 997 { 998 Word16 i; 999 Word16 j; 1000 Word16 k; 1001 Word16 track; 1002 Word16 first; 1003 Word16 index; 1004 Word16 rsign; 1005 Word16 indx; 1006 Word16 _sign[NB_PULSE]; 1007 Word16 *p0; 1008 Word16 *p1; 1009 1010 const Word16 *pt; 1011 1012 Word32 s; 1013 1014 pt = trackTable + subNr + (subNr << 2); 1015 1016 for (i = 0; i < L_CODE; i++) 1017 { 1018 *(cod + i) = 0; 1019 } 1020 1021 indx = 0; 1022 rsign = 0; 1023 1024 for (k = 0; k < NB_PULSE; k++) 1025 { 1026 i = *(codvec + k); /* read pulse position */ 1027 j = *(dn_sign + i); /* read sign */ 1028 1029 s = ((Word32)(i * 6554)) >> 15; 1030 index = (Word16) s; /* index = pos/5 */ 1031 1032 track = i - (5 * index); /* track = pos%5 */ 1033 1034 first = *(pt + track); 1035 1036 1037 if (k == 0) 1038 { 1039 track = 0; 1040 1041 if (first != 0) 1042 { 1043 index += 64; /* table bit is MSB */ 1044 } 1045 } 1046 else 1047 { 1048 track = 1; 1049 index <<= 3; 1050 } 1051 1052 if (j > 0) 1053 { 1054 *(cod + i) = 8191; 1055 *(_sign + k) = 32767; 1056 rsign += (1 << track); 1057 } 1058 else 1059 { 1060 *(cod + i) = ~(8192) + 1; 1061 *(_sign + k) = (Word16)(~(32768) + 1); 1062 } 1063 1064 indx += index; 1065 } 1066 1067 *sign = rsign; 1068 1069 p0 = h - *codvec; 1070 p1 = h - *(codvec + 1); 1071 1072 for (i = 0; i < L_CODE; i++) 1073 { 1074 s = 0; 1075 s = 1076 L_mult( 1077 *p0++, 1078 *_sign, 1079 pOverflow); 1080 1081 s = 1082 L_mac( 1083 s, 1084 *p1++, 1085 *(_sign + 1), 1086 pOverflow); 1087 1088 *(y + i) = 1089 pv_round( 1090 s, 1091 pOverflow); 1092 } 1093 1094 return(indx); 1095 } 1096 1097 /****************************************************************************/ 1098 1099 /* 1100 ------------------------------------------------------------------------------ 1101 FUNCTION NAME: Test_build_code 1102 ------------------------------------------------------------------------------ 1103 INPUT AND OUTPUT DEFINITIONS 1104 1105 Inputs: 1106 subNr = subframe number (Word16) 1107 codvec = vector containing the position of pulses (Word16) 1108 dn_sign = vector containing the sign of pulses (Word16) 1109 cod = innovative code vector (Word16) 1110 h = vector containing the impulse response of the weighted 1111 synthesis filter (Word16) 1112 y = vector containing the filtered innovative code (Word16) 1113 sign = vector containing the sign of 2 pulses (Word16) 1114 1115 Outputs: 1116 cod vector contains the new innovative code 1117 y vector contains the new filtered innovative code 1118 sign vector contains the sign of 2 pulses 1119 1120 Returns: 1121 indx = codebook index (Word16) 1122 1123 Global Variables Used: 1124 None 1125 1126 Local Variables Needed: 1127 trackTable = table used for tracking codewords (Word16) 1128 1129 ------------------------------------------------------------------------------ 1130 FUNCTION DESCRIPTION 1131 1132 This function provides external access to the local function build_code. 1133 1134 ------------------------------------------------------------------------------ 1135 REQUIREMENTS 1136 1137 None 1138 1139 ------------------------------------------------------------------------------ 1140 REFERENCES 1141 1142 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 1143 1144 ------------------------------------------------------------------------------ 1145 PSEUDO-CODE 1146 1147 CALL build_code ( subNr = subNr 1148 codvec = codvec 1149 dn_sign = dn_sign 1150 cod = cod 1151 h = h 1152 y = y 1153 sign = sign ) 1154 MODIFYING(nothing) 1155 RETURNING(indx) 1156 1157 ------------------------------------------------------------------------------ 1158 RESOURCES USED [optional] 1159 1160 When the code is written for a specific target processor the 1161 the resources used should be documented below. 1162 1163 HEAP MEMORY USED: x bytes 1164 1165 STACK MEMORY USED: x bytes 1166 1167 CLOCK CYCLES: (cycle count equation for this function) + (variable 1168 used to represent cycle count for each subroutine 1169 called) 1170 where: (cycle count variable) = cycle count for [subroutine 1171 name] 1172 1173 ------------------------------------------------------------------------------ 1174 CAUTION [optional] 1175 [State any special notes, constraints or cautions for users of this function] 1176 1177 ------------------------------------------------------------------------------ 1178 */ 1179 Test_build_code(Word16 subNr,Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)1180 Word16 Test_build_code( 1181 Word16 subNr, /* i : subframe number */ 1182 Word16 codvec[], /* i : position of pulses */ 1183 Word16 dn_sign[], /* i : sign of pulses */ 1184 Word16 cod[], /* o : innovative code vector */ 1185 Word16 h[], /* i : impulse response of weighted synthesis */ 1186 /* filter */ 1187 Word16 y[], /* o : filtered innovative code */ 1188 Word16 sign[], /* o : sign of 2 pulses */ 1189 Flag * pOverflow /* o : Flag set when overflow occurs */ 1190 ) 1191 { 1192 Word16 test_index; 1193 1194 /*---------------------------------------------------------------------------- 1195 CALL build_code ( subNr = subNr 1196 codvec = codvec 1197 dn_sign = dn_sign 1198 cod = cod 1199 h = h 1200 y = y 1201 sign = sign ) 1202 MODIFYING(nothing) 1203 RETURNING(indx) 1204 ----------------------------------------------------------------------------*/ 1205 test_index = 1206 build_code( 1207 subNr, 1208 codvec, 1209 dn_sign, 1210 cod, 1211 h, 1212 y, 1213 sign, 1214 pOverflow); 1215 1216 return(test_index); 1217 } 1218 1219 #ifdef __cplusplus 1220 } 1221 #endif 1222