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 Word16 *p_codvec = &codvec[0]; 614 615 OSCL_UNUSED_ARG(pOverflow); 616 617 psk = -1; 618 alpk = 1; 619 620 /* Unrolled the following FOR loop to save MIPS */ 621 /* for (i = 0; i < NB_PULSE; i++) */ 622 /* { */ 623 /* *(codvec + i) = i; */ 624 /* } */ 625 626 *(p_codvec++) = 0; 627 *(p_codvec) = 1; 628 629 for (track1 = 0; track1 < 2; track1++) 630 { 631 /* fix starting position */ 632 633 i = (subNr << 1) + (track1 << 3); 634 *ipos = *(startPos + i); 635 *(ipos + 1) = *(startPos + i + 1); 636 637 638 /*----------------------------------------------------------* 639 * i0 loop: try 8 positions. * 640 *----------------------------------------------------------*/ 641 642 for (i0 = *ipos; i0 < L_CODE; i0 += STEP) 643 { 644 ps0 = *(dn + i0); 645 646 /* Left shift by 1 converts integer product to */ 647 /* fractional product. */ 648 alp0 = (Word32) rr[i0][i0] << 14; 649 650 /*--------------------------------------------------* 651 * i1 loop: 8 positions. * 652 *--------------------------------------------------*/ 653 654 sq = -1; 655 alp = 1; 656 ix = *(ipos + 1); 657 658 /*--------------------------------------------------* 659 * These index have low complexity address * 660 * computation because they are, in fact, pointers * 661 * with fixed increment. For example, "rr[i0][i2]" * 662 * is a pointer initialized to "&rr[i0][ipos[2]]" * 663 * and incremented by "STEP". * 664 *---------------------------------------------------*/ 665 666 for (i1 = *(ipos + 1); i1 < L_CODE; i1 += STEP) 667 { 668 /* idx increment = STEP */ 669 /* ps1 = add(ps0, *(dn + i1), pOverflow); */ 670 ps1 = ps0 + dn[i1]; 671 672 /* alp1 = alp0+rr[i0][i1]+1/2*rr[i1][i1]; */ 673 674 /* idx incr = STEP */ 675 /* Extra left shift by 1 converts integer */ 676 /* product to fractional product */ 677 /* alp1 = L_add(alp0, s, pOverflow); */ 678 alp1 = alp0 + ((Word32) rr[i1][i1] << 14); 679 680 /* idx incr = STEP */ 681 /* Extra left shift by 1 converts integer */ 682 /* product to fractional product */ 683 /* alp1 = L_add(alp1, s, pOverflow); */ 684 alp1 += (Word32) rr[i0][i1] << 15; 685 686 /* sq1 = mult(ps1, ps1, pOverflow); */ 687 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); 688 689 /* alp_16 = pv_round(alp1, pOverflow); */ 690 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); 691 692 /* L_temp = L_mult(alp, sq1, pOverflow); */ 693 L_temp = ((Word32) alp * sq1) << 1; 694 695 /* s = L_msu(L_temp, sq, alp_16, pOverflow); */ 696 s = L_temp - (((Word32) sq * alp_16) << 1); 697 698 if (s > 0) 699 { 700 sq = sq1; 701 alp = alp_16; 702 ix = i1; 703 } 704 } 705 706 /* memorize codevector if this one is better than the last one. */ 707 708 /* L_temp = L_mult(alpk, sq, pOverflow); */ 709 L_temp = ((Word32) alpk * sq) << 1; 710 711 /* s = L_msu(L_temp, psk, alp, pOverflow); */ 712 s = L_temp - (((Word32) psk * alp) << 1); 713 714 if (s > 0) 715 { 716 psk = sq; 717 alpk = alp; 718 p_codvec = &codvec[0]; 719 *(p_codvec++) = i0; 720 *(p_codvec) = ix; 721 } 722 } 723 } 724 725 return; 726 } 727 728 /****************************************************************************/ 729 730 /* 731 ------------------------------------------------------------------------------ 732 FUNCTION NAME: Test_search_2i40 733 ------------------------------------------------------------------------------ 734 INPUT AND OUTPUT DEFINITIONS 735 736 Inputs: 737 subNr = subframe number (Word16) 738 dn = vector containing the correlation between target and the impulse 739 response of the weighted synthesis filter (Word16) 740 rr = autocorrelation matrix (Word16) 741 codvec = algebraic codebook vector (Word16) 742 743 Outputs: 744 codvec contains the newly calculated codevectors 745 746 Returns: 747 None 748 749 Global Variables Used: 750 None 751 752 Local Variables Needed: 753 startPos = table containing the start positions used by fixed codebook 754 routines (const Word16) 755 756 ------------------------------------------------------------------------------ 757 FUNCTION DESCRIPTION 758 759 This function provides external access to the local function search_2i40. 760 761 ------------------------------------------------------------------------------ 762 REQUIREMENTS 763 764 None 765 766 ------------------------------------------------------------------------------ 767 REFERENCES 768 769 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 770 771 ------------------------------------------------------------------------------ 772 PSEUDO-CODE 773 774 CALL search_2i40 ( subNr = subNr 775 dn = dn 776 rr = rr 777 codvec = codvec ) 778 MODIFYING(nothing) 779 RETURNING(nothing) 780 781 ------------------------------------------------------------------------------ 782 RESOURCES USED [optional] 783 784 When the code is written for a specific target processor the 785 the resources used should be documented below. 786 787 HEAP MEMORY USED: x bytes 788 789 STACK MEMORY USED: x bytes 790 791 CLOCK CYCLES: (cycle count equation for this function) + (variable 792 used to represent cycle count for each subroutine 793 called) 794 where: (cycle count variable) = cycle count for [subroutine 795 name] 796 797 ------------------------------------------------------------------------------ 798 CAUTION [optional] 799 [State any special notes, constraints or cautions for users of this function] 800 801 ------------------------------------------------------------------------------ 802 */ 803 Test_search_2i40(Word16 subNr,Word16 dn[],Word16 rr[][L_CODE],Word16 codvec[],Flag * pOverflow)804 void Test_search_2i40( 805 Word16 subNr, /* i : subframe number */ 806 Word16 dn[], /* i : correlation between target and h[] */ 807 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ 808 Word16 codvec[], /* o : algebraic codebook vector */ 809 Flag * pOverflow /* o : Flag set when overflow occurs */ 810 ) 811 { 812 /*---------------------------------------------------------------------------- 813 CALL search_2i40 ( subNr = subNr 814 dn = dn 815 rr = rr 816 codvec = codvec ) 817 MODIFYING(nothing) 818 RETURNING(nothing) 819 ----------------------------------------------------------------------------*/ 820 search_2i40( 821 subNr, 822 dn, 823 rr, 824 codvec, 825 pOverflow); 826 827 return; 828 } 829 830 /****************************************************************************/ 831 832 /* 833 ------------------------------------------------------------------------------ 834 FUNCTION NAME: build_code 835 ------------------------------------------------------------------------------ 836 INPUT AND OUTPUT DEFINITIONS 837 838 Inputs: 839 subNr = subframe number (Word16) 840 codvec = vector containing the position of pulses (Word16) 841 dn_sign = vector containing the sign of pulses (Word16) 842 cod = innovative code vector (Word16) 843 h = vector containing the impulse response of the weighted 844 synthesis filter (Word16) 845 y = vector containing the filtered innovative code (Word16) 846 sign = vector containing the sign of 2 pulses (Word16) 847 848 Outputs: 849 cod vector contains the new innovative code 850 y vector contains the new filtered innovative code 851 sign vector contains the sign of 2 pulses 852 853 Returns: 854 indx = codebook index (Word16) 855 856 Global Variables Used: 857 None 858 859 Local Variables Needed: 860 trackTable = table used for tracking codewords (Word16) 861 862 ------------------------------------------------------------------------------ 863 FUNCTION DESCRIPTION 864 865 This function builds the codeword, the filtered codeword and index of the 866 codevector, based on the signs and positions of 2 pulses. 867 868 ------------------------------------------------------------------------------ 869 REQUIREMENTS 870 871 None 872 873 ------------------------------------------------------------------------------ 874 REFERENCES 875 876 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 877 878 ------------------------------------------------------------------------------ 879 PSEUDO-CODE 880 881 static Word16 build_code( 882 Word16 subNr, // i : subframe number 883 Word16 codvec[], // i : position of pulses 884 Word16 dn_sign[], // i : sign of pulses 885 Word16 cod[], // o : innovative code vector 886 Word16 h[], // i : impulse response of weighted synthesis filter 887 Word16 y[], // o : filtered innovative code 888 Word16 sign[] // o : sign of 2 pulses 889 ) 890 { 891 Word16 i, j, k, track, first, index, _sign[NB_PULSE], indx, rsign; 892 Word16 *p0, *p1, *pt; 893 Word32 s; 894 static Word16 trackTable[4*5] = { 895 0, 1, 0, 1, -1, // subframe 1; track to code; -1 do not code this position 896 0, -1, 1, 0, 1, // subframe 2 897 0, 1, 0, -1, 1, // subframe 3 898 0, 1, -1, 0, 1};// subframe 4 899 900 pt = &trackTable[add(subNr, shl(subNr, 2))]; 901 902 for (i = 0; i < L_CODE; i++) { 903 cod[i] = 0; 904 } 905 906 indx = 0; 907 rsign = 0; 908 for (k = 0; k < NB_PULSE; k++) { 909 i = codvec[k]; // read pulse position 910 j = dn_sign[i]; // read sign 911 912 index = mult(i, 6554); // index = pos/5 913 // track = pos%5 914 track = sub(i, extract_l(L_shr(L_mult(index, 5), 1))); 915 916 first = pt[track]; 917 918 if (first == 0) { 919 if (k == 0) { 920 track = 0; 921 } else { 922 track = 1; 923 index = shl(index, 3); 924 } 925 } else { 926 if (k == 0) { 927 track = 0; 928 index = add(index, 64); // table bit is MSB 929 } else { 930 track = 1; 931 index = shl(index, 3); 932 } 933 } 934 935 if (j > 0) { 936 cod[i] = 8191; 937 _sign[k] = 32767; 938 rsign = add(rsign, shl(1, track)); 939 } else { 940 cod[i] = -8192; 941 _sign[k] = (Word16) - 32768L; 942 } 943 944 indx = add(indx, index); 945 } 946 *sign = rsign; 947 948 p0 = h - codvec[0]; 949 p1 = h - codvec[1]; 950 951 for (i = 0; i < L_CODE; i++) { 952 s = 0; 953 s = L_mac(s, *p0++, _sign[0]); 954 s = L_mac(s, *p1++, _sign[1]); 955 y[i] = pv_round(s); 956 } 957 958 return indx; 959 } 960 961 ------------------------------------------------------------------------------ 962 RESOURCES USED [optional] 963 964 When the code is written for a specific target processor the 965 the resources used should be documented below. 966 967 HEAP MEMORY USED: x bytes 968 969 STACK MEMORY USED: x bytes 970 971 CLOCK CYCLES: (cycle count equation for this function) + (variable 972 used to represent cycle count for each subroutine 973 called) 974 where: (cycle count variable) = cycle count for [subroutine 975 name] 976 977 ------------------------------------------------------------------------------ 978 CAUTION [optional] 979 [State any special notes, constraints or cautions for users of this function] 980 981 ------------------------------------------------------------------------------ 982 */ 983 build_code(Word16 subNr,Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)984 static Word16 build_code( 985 Word16 subNr, /* i : subframe number */ 986 Word16 codvec[], /* i : position of pulses */ 987 Word16 dn_sign[], /* i : sign of pulses */ 988 Word16 cod[], /* o : innovative code vector */ 989 Word16 h[], /* i : impulse response of weighted synthesis */ 990 /* filter */ 991 Word16 y[], /* o : filtered innovative code */ 992 Word16 sign[], /* o : sign of 2 pulses */ 993 Flag *pOverflow /* o : Flag set when overflow occurs */ 994 ) 995 { 996 Word16 i; 997 Word16 j; 998 Word16 k; 999 Word16 track; 1000 Word16 first; 1001 Word16 index; 1002 Word16 rsign; 1003 Word16 indx; 1004 Word16 _sign[NB_PULSE]; 1005 Word16 *p0; 1006 Word16 *p1; 1007 1008 const Word16 *pt; 1009 1010 Word32 s; 1011 1012 pt = trackTable + subNr + (subNr << 2); 1013 1014 for (i = 0; i < L_CODE; i++) 1015 { 1016 *(cod + i) = 0; 1017 } 1018 1019 indx = 0; 1020 rsign = 0; 1021 1022 for (k = 0; k < NB_PULSE; k++) 1023 { 1024 i = *(codvec + k); /* read pulse position */ 1025 j = *(dn_sign + i); /* read sign */ 1026 1027 s = ((Word32)(i * 6554)) >> 15; 1028 index = (Word16) s; /* index = pos/5 */ 1029 1030 track = i - (5 * index); /* track = pos%5 */ 1031 1032 first = *(pt + track); 1033 1034 1035 if (k == 0) 1036 { 1037 track = 0; 1038 1039 if (first != 0) 1040 { 1041 index += 64; /* table bit is MSB */ 1042 } 1043 } 1044 else 1045 { 1046 track = 1; 1047 index <<= 3; 1048 } 1049 1050 if (j > 0) 1051 { 1052 *(cod + i) = 8191; 1053 *(_sign + k) = 32767; 1054 rsign += (1 << track); 1055 } 1056 else 1057 { 1058 *(cod + i) = ~(8192) + 1; 1059 *(_sign + k) = (Word16)(~(32768) + 1); 1060 } 1061 1062 indx += index; 1063 } 1064 1065 *sign = rsign; 1066 1067 p0 = h - *codvec; 1068 p1 = h - *(codvec + 1); 1069 1070 for (i = 0; i < L_CODE; i++) 1071 { 1072 s = 0; 1073 s = 1074 L_mult( 1075 *p0++, 1076 *_sign, 1077 pOverflow); 1078 1079 s = 1080 L_mac( 1081 s, 1082 *p1++, 1083 *(_sign + 1), 1084 pOverflow); 1085 1086 *(y + i) = 1087 pv_round( 1088 s, 1089 pOverflow); 1090 } 1091 1092 return(indx); 1093 } 1094 1095 /****************************************************************************/ 1096 1097 /* 1098 ------------------------------------------------------------------------------ 1099 FUNCTION NAME: Test_build_code 1100 ------------------------------------------------------------------------------ 1101 INPUT AND OUTPUT DEFINITIONS 1102 1103 Inputs: 1104 subNr = subframe number (Word16) 1105 codvec = vector containing the position of pulses (Word16) 1106 dn_sign = vector containing the sign of pulses (Word16) 1107 cod = innovative code vector (Word16) 1108 h = vector containing the impulse response of the weighted 1109 synthesis filter (Word16) 1110 y = vector containing the filtered innovative code (Word16) 1111 sign = vector containing the sign of 2 pulses (Word16) 1112 1113 Outputs: 1114 cod vector contains the new innovative code 1115 y vector contains the new filtered innovative code 1116 sign vector contains the sign of 2 pulses 1117 1118 Returns: 1119 indx = codebook index (Word16) 1120 1121 Global Variables Used: 1122 None 1123 1124 Local Variables Needed: 1125 trackTable = table used for tracking codewords (Word16) 1126 1127 ------------------------------------------------------------------------------ 1128 FUNCTION DESCRIPTION 1129 1130 This function provides external access to the local function build_code. 1131 1132 ------------------------------------------------------------------------------ 1133 REQUIREMENTS 1134 1135 None 1136 1137 ------------------------------------------------------------------------------ 1138 REFERENCES 1139 1140 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 1141 1142 ------------------------------------------------------------------------------ 1143 PSEUDO-CODE 1144 1145 CALL build_code ( subNr = subNr 1146 codvec = codvec 1147 dn_sign = dn_sign 1148 cod = cod 1149 h = h 1150 y = y 1151 sign = sign ) 1152 MODIFYING(nothing) 1153 RETURNING(indx) 1154 1155 ------------------------------------------------------------------------------ 1156 RESOURCES USED [optional] 1157 1158 When the code is written for a specific target processor the 1159 the resources used should be documented below. 1160 1161 HEAP MEMORY USED: x bytes 1162 1163 STACK MEMORY USED: x bytes 1164 1165 CLOCK CYCLES: (cycle count equation for this function) + (variable 1166 used to represent cycle count for each subroutine 1167 called) 1168 where: (cycle count variable) = cycle count for [subroutine 1169 name] 1170 1171 ------------------------------------------------------------------------------ 1172 CAUTION [optional] 1173 [State any special notes, constraints or cautions for users of this function] 1174 1175 ------------------------------------------------------------------------------ 1176 */ 1177 Test_build_code(Word16 subNr,Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)1178 Word16 Test_build_code( 1179 Word16 subNr, /* i : subframe number */ 1180 Word16 codvec[], /* i : position of pulses */ 1181 Word16 dn_sign[], /* i : sign of pulses */ 1182 Word16 cod[], /* o : innovative code vector */ 1183 Word16 h[], /* i : impulse response of weighted synthesis */ 1184 /* filter */ 1185 Word16 y[], /* o : filtered innovative code */ 1186 Word16 sign[], /* o : sign of 2 pulses */ 1187 Flag * pOverflow /* o : Flag set when overflow occurs */ 1188 ) 1189 { 1190 Word16 test_index; 1191 1192 /*---------------------------------------------------------------------------- 1193 CALL build_code ( subNr = subNr 1194 codvec = codvec 1195 dn_sign = dn_sign 1196 cod = cod 1197 h = h 1198 y = y 1199 sign = sign ) 1200 MODIFYING(nothing) 1201 RETURNING(indx) 1202 ----------------------------------------------------------------------------*/ 1203 test_index = 1204 build_code( 1205 subNr, 1206 codvec, 1207 dn_sign, 1208 cod, 1209 h, 1210 y, 1211 sign, 1212 pOverflow); 1213 1214 return(test_index); 1215 } 1216 1217 #ifdef __cplusplus 1218 } 1219 #endif 1220