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/c8_31pf.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 file to reduce clock cycle usage. Updated copyright 46 year. Removed unnecessary include files and unused #defines. 47 48 Description: Changed round function name to pv_round to avoid conflict with 49 round function in C standard library. 50 51 Description: Replaced "int" and/or "char" with OSCL defined types. 52 53 Description: 54 55 ------------------------------------------------------------------------------ 56 MODULE DESCRIPTION 57 58 Purpose : Searches a 31 bit algebraic codebook containing 59 : 8 pulses in a frame of 40 samples. 60 : in the same manner as GSM-EFR 61 ------------------------------------------------------------------------------ 62 */ 63 64 /*---------------------------------------------------------------------------- 65 ; INCLUDES 66 ----------------------------------------------------------------------------*/ 67 #include "c8_31pf.h" 68 #include "typedef.h" 69 #include "cnst.h" 70 #include "inv_sqrt.h" 71 #include "cor_h.h" 72 #include "cor_h_x2.h" 73 #include "set_sign.h" 74 #include "s10_8pf.h" 75 #include "basic_op.h" 76 77 /*---------------------------------------------------------------------------- 78 ; MACROS 79 ; Define module specific macros here 80 ----------------------------------------------------------------------------*/ 81 82 /*---------------------------------------------------------------------------- 83 ; DEFINES 84 ; Include all pre-processor statements here. Include conditional 85 ; compile variables also. 86 ----------------------------------------------------------------------------*/ 87 #define NB_PULSE 8 88 89 /* define values/representation for output codevector and sign */ 90 #define POS_CODE 8191 91 #define NEG_CODE 8191 92 #define POS_SIGN 32767 93 #define NEG_SIGN (Word16) (-32768L) 94 95 /*---------------------------------------------------------------------------- 96 ; LOCAL FUNCTION DEFINITIONS 97 ; Function Prototype declaration 98 ----------------------------------------------------------------------------*/ 99 100 /*---------------------------------------------------------------------------- 101 ; LOCAL VARIABLE DEFINITIONS 102 ; Variable declaration - defined here and used outside this module 103 ----------------------------------------------------------------------------*/ 104 105 /*---------------------------------------------------------------------------- 106 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 107 ; Declare variables used in this module but defined elsewhere 108 ----------------------------------------------------------------------------*/ 109 110 /* 111 ------------------------------------------------------------------------------ 112 FUNCTION NAME: 113 ------------------------------------------------------------------------------ 114 INPUT AND OUTPUT DEFINITIONS 115 116 Inputs: 117 codvec[] Array of type Word16 -- position of pulses 118 sign[] Array of type Word16 -- sign of pulses 119 h[] Array of type Word16 -- impulse response of 120 weighted synthesis filter 121 Outputs: 122 cod[] Array of type Word16 -- innovative code vector 123 y[] Array of type Word16 -- filtered innovative code 124 sign_indx[] Array of type Word16 -- signs of 4 pulses (signs only) 125 pos_indx[] Array of type Word16 -- 126 position index of 8 pulses(position only) 127 128 pOverflow Pointer to Flag -- set when overflow occurs 129 130 Returns: 131 indx 132 133 Global Variables Used: 134 None 135 136 Local Variables Needed: 137 138 ------------------------------------------------------------------------------ 139 FUNCTION DESCRIPTION 140 141 142 ------------------------------------------------------------------------------ 143 REQUIREMENTS 144 145 None 146 147 ------------------------------------------------------------------------------ 148 REFERENCES 149 150 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 151 152 ------------------------------------------------------------------------------ 153 PSEUDO-CODE 154 155 ------------------------------------------------------------------------------ 156 RESOURCES USED [optional] 157 158 When the code is written for a specific target processor the 159 the resources used should be documented below. 160 161 HEAP MEMORY USED: x bytes 162 163 STACK MEMORY USED: x bytes 164 165 CLOCK CYCLES: (cycle count equation for this function) + (variable 166 used to represent cycle count for each subroutine 167 called) 168 where: (cycle count variable) = cycle count for [subroutine 169 name] 170 171 ------------------------------------------------------------------------------ 172 CAUTION [optional] 173 [State any special notes, constraints or cautions for users of this function] 174 175 ------------------------------------------------------------------------------ 176 */ 177 178 /************************************************************************* 179 * 180 * FUNCTION: build_code() 181 * 182 * PURPOSE: Builds the codeword, the filtered codeword and a 183 * linear uncombined version of the index of the 184 * codevector, based on the signs and positions of 8 pulses. 185 * 186 *************************************************************************/ 187 188 static void build_code( 189 Word16 codvec[], /* i : position of pulses */ 190 Word16 sign[], /* i : sign of d[n] */ 191 Word16 cod[], /* o : innovative code vector */ 192 Word16 h[], /* i : impulse response of weighted synthesis filter*/ 193 Word16 y[], /* o : filtered innovative code */ 194 Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */ 195 Word16 pos_indx[], /* o : position index of 8 pulses(position only) */ 196 Flag * pOverflow /* o : Flag set when overflow occurs */ 197 ) 198 { 199 Word16 i; 200 Word16 j; 201 Word16 k; 202 Word16 track; 203 Word16 sign_index; 204 Word16 pos_index; 205 Word16 _sign[NB_PULSE]; 206 207 Word16 *p0; 208 Word16 *p1; 209 Word16 *p2; 210 Word16 *p3; 211 Word16 *p4; 212 Word16 *p5; 213 Word16 *p6; 214 Word16 *p7; 215 216 Word16 *p_cod = &cod[0]; 217 Word16 *p_codvec = &codvec[0]; 218 219 Word32 s; 220 221 for (i = 0; i < L_CODE; i++) 222 { 223 *(p_cod++) = 0; 224 } 225 226 for (i = 0; i < NB_TRACK_MR102; i++) 227 { 228 pos_indx[i] = -1; 229 sign_indx[i] = -1; 230 } 231 232 for (k = 0; k < NB_PULSE; k++) 233 { 234 /* read pulse position */ 235 i = codvec[k]; 236 /* read sign */ 237 j = sign[i]; 238 239 pos_index = i >> 2; /* index = pos/4 */ 240 241 track = i & 3; /* track = pos%4 */ 242 243 if (j > 0) 244 { 245 cod[i] = (Word16)((Word32) cod[i] + POS_CODE); 246 247 _sign[k] = POS_SIGN; 248 sign_index = 0; /* bit=0 -> positive pulse */ 249 } 250 else 251 { 252 cod[i] = (Word16)((Word32) cod[i] - NEG_CODE); 253 254 _sign[k] = NEG_SIGN; 255 sign_index = 1; /* bit=1 => negative pulse */ 256 /* index = add (index, 8); 1 = negative old code */ 257 } 258 259 if (pos_indx[track] < 0) 260 { /* first set first NB_TRACK pulses */ 261 pos_indx[track] = pos_index; 262 sign_indx[track] = sign_index; 263 } 264 else 265 { /* 2nd row of pulses , test if positions needs to be switched */ 266 if (((sign_index ^ sign_indx[track]) & 1) == 0) 267 { 268 /* sign of 1st pulse == sign of 2nd pulse */ 269 270 if (pos_indx[track] <= pos_index) 271 { /* no swap */ 272 pos_indx[track + NB_TRACK_MR102] = pos_index; 273 } 274 else 275 { /* swap*/ 276 pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; 277 278 pos_indx[track] = pos_index; 279 sign_indx[track] = sign_index; 280 } 281 } 282 else 283 { 284 /* sign of 1st pulse != sign of 2nd pulse */ 285 286 if (pos_indx[track] <= pos_index) 287 { /*swap*/ 288 pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; 289 290 pos_indx[track] = pos_index; 291 sign_indx[track] = sign_index; 292 } 293 else 294 { /*no swap */ 295 pos_indx[track + NB_TRACK_MR102] = pos_index; 296 } 297 } 298 } 299 } 300 301 p0 = h - *(p_codvec++); 302 p1 = h - *(p_codvec++); 303 p2 = h - *(p_codvec++); 304 p3 = h - *(p_codvec++); 305 p4 = h - *(p_codvec++); 306 p5 = h - *(p_codvec++); 307 p6 = h - *(p_codvec++); 308 p7 = h - *(p_codvec); 309 310 for (i = 0; i < L_CODE; i++) 311 { 312 s = 0; 313 314 s = 315 L_mac( 316 s, 317 *p0++, 318 _sign[0], 319 pOverflow); 320 s = 321 L_mac( 322 s, 323 *p1++, 324 _sign[1], 325 pOverflow); 326 s = 327 L_mac( 328 s, 329 *p2++, 330 _sign[2], 331 pOverflow); 332 s = 333 L_mac( 334 s, 335 *p3++, 336 _sign[3], 337 pOverflow); 338 s = 339 L_mac( 340 s, 341 *p4++, 342 _sign[4], 343 pOverflow); 344 s = 345 L_mac( 346 s, 347 *p5++, 348 _sign[5], 349 pOverflow); 350 s = 351 L_mac( 352 s, 353 *p6++, 354 _sign[6], 355 pOverflow); 356 s = 357 L_mac( 358 s, 359 *p7++, 360 _sign[7], 361 pOverflow); 362 363 y[i] = 364 pv_round( 365 s, 366 pOverflow); 367 368 } /* for (i = 0; i < L_CODE; i++) */ 369 370 } /* build_code */ 371 372 /****************************************************************************/ 373 374 /* 375 ------------------------------------------------------------------------------ 376 FUNCTION NAME: compress_code() 377 ------------------------------------------------------------------------------ 378 INPUT AND OUTPUT DEFINITIONS 379 380 Inputs: 381 382 Outputs: 383 384 Returns: 385 None 386 387 Global Variables Used: 388 None 389 390 Local Variables Needed: 391 392 ------------------------------------------------------------------------------ 393 FUNCTION DESCRIPTION 394 395 FUNCTION: 396 397 PURPOSE: compression of three indeces [0..9] to one 10 bit index 398 minimizing the phase shift of a bit error. 399 400 ------------------------------------------------------------------------------ 401 REQUIREMENTS 402 403 None 404 405 ------------------------------------------------------------------------------ 406 REFERENCES 407 408 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 409 410 ------------------------------------------------------------------------------ 411 PSEUDO-CODE 412 413 ------------------------------------------------------------------------------ 414 RESOURCES USED [optional] 415 416 When the code is written for a specific target processor the 417 the resources used should be documented below. 418 419 HEAP MEMORY USED: x bytes 420 421 STACK MEMORY USED: x bytes 422 423 CLOCK CYCLES: (cycle count equation for this function) + (variable 424 used to represent cycle count for each subroutine 425 called) 426 where: (cycle count variable) = cycle count for [subroutine 427 name] 428 429 ------------------------------------------------------------------------------ 430 CAUTION [optional] 431 [State any special notes, constraints or cautions for users of this function] 432 433 ------------------------------------------------------------------------------ 434 */ 435 436 static Word16 compress10( 437 Word16 pos_indxA, /* i : signs of 4 pulses (signs only) */ 438 Word16 pos_indxB, /* i : position index of 8 pulses (pos only) */ 439 Word16 pos_indxC, /* i : position and sign of 8 pulses (compressed) */ 440 Flag *pOverflow) /* o : Flag set when overflow occurs */ 441 { 442 Word16 indx; 443 Word16 ia; 444 Word16 ib; 445 Word16 ic; 446 447 Word32 tempWord32; 448 449 OSCL_UNUSED_ARG(pOverflow); 450 451 ia = pos_indxA >> 1; 452 453 ib = pos_indxB >> 1; 454 455 tempWord32 = ((Word32) ib * 5) << 1; 456 457 tempWord32 = tempWord32 >> 1; 458 459 ib = (Word16) tempWord32; 460 461 ic = pos_indxC >> 1; 462 463 tempWord32 = ((Word32) ic * 25) << 1; 464 465 tempWord32 = tempWord32 >> 1; 466 467 ic = (Word16) tempWord32; 468 469 ib += ic; 470 471 ib += ia; 472 473 indx = ib << 3; 474 475 ia = pos_indxA & 1; 476 477 ib = ((Word16)(pos_indxB & 1)) << 1; 478 479 ic = ((Word16)(pos_indxC & 1)) << 2; 480 481 ib += ic; 482 483 ib += ia; 484 485 indx += ib; 486 487 return indx; 488 489 } 490 491 /****************************************************************************/ 492 493 /* 494 ------------------------------------------------------------------------------ 495 FUNCTION NAME: compress_code() 496 ------------------------------------------------------------------------------ 497 INPUT AND OUTPUT DEFINITIONS 498 499 Inputs: 500 sign_indx Array of type Word16 -- signs of 4 pulses (signs only) 501 pos_indx Array of type Word16 -- position index of 8 pulses 502 (position only) 503 504 Outputs: 505 indx Array of type Word16 -- position and sign of 8 pulses 506 (compressed) 507 pOverflow Pointer to Flag -- set when overflow occurs 508 509 Returns: 510 None 511 512 Global Variables Used: 513 None 514 515 Local Variables Needed: 516 None 517 518 ------------------------------------------------------------------------------ 519 FUNCTION DESCRIPTION 520 521 PURPOSE: compression of the linear codewords to 4+three indeces 522 one bit from each pulse is made robust to errors by 523 minimizing the phase shift of a bit error. 524 4 signs (one for each track) 525 i0,i4,i1 => one index (7+3) bits, 3 LSBs more robust 526 i2,i6,i5 => one index (7+3) bits, 3 LSBs more robust 527 i3,i7 => one index (5+2) bits, 2-3 LSbs more robust 528 529 ------------------------------------------------------------------------------ 530 REQUIREMENTS 531 532 None 533 534 ------------------------------------------------------------------------------ 535 REFERENCES 536 537 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 538 539 ------------------------------------------------------------------------------ 540 PSEUDO-CODE 541 542 ------------------------------------------------------------------------------ 543 RESOURCES USED [optional] 544 545 When the code is written for a specific target processor the 546 the resources used should be documented below. 547 548 HEAP MEMORY USED: x bytes 549 550 STACK MEMORY USED: x bytes 551 552 CLOCK CYCLES: (cycle count equation for this function) + (variable 553 used to represent cycle count for each subroutine 554 called) 555 where: (cycle count variable) = cycle count for [subroutine 556 name] 557 558 ------------------------------------------------------------------------------ 559 CAUTION [optional] 560 [State any special notes, constraints or cautions for users of this function] 561 562 ------------------------------------------------------------------------------ 563 */ 564 565 static void compress_code( 566 Word16 sign_indx[], /* i : signs of 4 pulses (signs only) */ 567 Word16 pos_indx[], /* i : position index of 8 pulses (position only) */ 568 Word16 indx[], /* o : position and sign of 8 pulses (compressed) */ 569 Flag *pOverflow) /* o : Flag set when overflow occurs */ 570 { 571 Word16 i; 572 Word16 ia; 573 Word16 ib; 574 Word16 ic; 575 576 Word16 *p_indx = &indx[0]; 577 Word16 *p_sign_indx = &sign_indx[0]; 578 579 Word32 tempWord32; 580 581 for (i = 0; i < NB_TRACK_MR102; i++) 582 { 583 *(p_indx++) = *(p_sign_indx++); 584 } 585 586 /* First index 587 indx[NB_TRACK] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */ 588 589 indx[NB_TRACK_MR102] = 590 compress10( 591 pos_indx[0], 592 pos_indx[4], 593 pos_indx[1], 594 pOverflow); 595 596 /* Second index 597 indx[NB_TRACK+1] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */ 598 599 indx[NB_TRACK_MR102+1] = 600 compress10( 601 pos_indx[2], 602 pos_indx[6], 603 pos_indx[5], 604 pOverflow); 605 606 /* 607 Third index 608 if ((ib/2)%2 == 1) 609 indx[NB_TRACK+2] = ((((4-ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2; 610 else 611 indx[NB_TRACK+2] = ((((ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2; 612 */ 613 614 ib = pos_indx[7] >> 1; 615 616 ib &= 1; 617 618 ia = pos_indx[3] >> 1; 619 620 if (ib == 1) 621 { 622 ia = 4 - ia; 623 } 624 625 ib = pos_indx[7] >> 1; 626 627 tempWord32 = ((Word32) ib * 5) << 1; 628 629 tempWord32 = tempWord32 >> 1; 630 631 ib = (Word16) tempWord32; 632 633 ib += ia; 634 635 ib <<= 5; 636 637 ib += 12; 638 639 ic = (Word16)(((Word32) ib * 1311) >> 15); 640 641 ic <<= 2; 642 643 ia = pos_indx[3] & 1; 644 645 ib = ((Word16)(pos_indx[7] & 1)) << 1; 646 647 ib += ic; 648 649 ib += ia; 650 651 indx[NB_TRACK_MR102+2] = ib; 652 653 } /* compress_code */ 654 655 656 /****************************************************************************/ 657 658 /* 659 ------------------------------------------------------------------------------ 660 FUNCTION NAME: code_8i40_31bits() 661 ------------------------------------------------------------------------------ 662 INPUT AND OUTPUT DEFINITIONS 663 664 Inputs: 665 x Array of type Word16 -- target vector 666 cn Array of type Word16 -- residual after long term prediction 667 h Array of type Word16 -- impulse response of weighted synthesis filter 668 669 670 Outputs: 671 cod Array of type Word16 -- algebraic (fixed) codebook excitation 672 y Array of type Word16 -- filtered fixed codebook excitation 673 indx Array of type Word16 -- index of 8 pulses (signs+positions) 674 pOverflow Pointer to Flag -- set when overflow occurs 675 676 Returns: 677 None 678 679 Global Variables Used: 680 None 681 682 Local Variables Needed: 683 None 684 685 ------------------------------------------------------------------------------ 686 FUNCTION DESCRIPTION 687 688 FUNCTION: 689 690 PURPOSE: Searches a 31 bit algebraic codebook containing 8 pulses 691 in a frame of 40 samples. 692 693 DESCRIPTION: 694 The code contains 8 nonzero pulses: i0...i7. 695 All pulses can have two possible amplitudes: +1 or -1. 696 The 40 positions in a subframe are divided into 4 tracks of 697 interleaved positions. Each track contains two pulses. 698 The pulses can have the following possible positions: 699 700 i0, i4 : 0, 4, 8, 12, 16, 20, 24, 28, 32, 36 701 i1, i5 : 1, 5, 9, 13, 17, 21, 25, 29, 33, 37 702 i2, i6 : 2, 6, 10, 14, 18, 22, 26, 30, 34, 38 703 i3, i7 : 3, 7, 11, 15, 19, 23, 27, 31, 35, 39 704 705 Each pair of pulses require 1 bit for their signs. The positions 706 are encoded together 3,3 and 2 resulting in 707 (7+3) + (7+3) + (5+2) bits for their 708 positions. This results in a 31 (4 sign and 27 pos) bit codebook. 709 The function determines the optimal pulse signs and positions, builds 710 the codevector, and computes the filtered codevector. 711 712 ------------------------------------------------------------------------------ 713 REQUIREMENTS 714 715 None 716 717 ------------------------------------------------------------------------------ 718 REFERENCES 719 720 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 721 722 ------------------------------------------------------------------------------ 723 PSEUDO-CODE 724 725 ------------------------------------------------------------------------------ 726 RESOURCES USED [optional] 727 728 When the code is written for a specific target processor the 729 the resources used should be documented below. 730 731 HEAP MEMORY USED: x bytes 732 733 STACK MEMORY USED: x bytes 734 735 CLOCK CYCLES: (cycle count equation for this function) + (variable 736 used to represent cycle count for each subroutine 737 called) 738 where: (cycle count variable) = cycle count for [subroutine 739 name] 740 741 ------------------------------------------------------------------------------ 742 CAUTION [optional] 743 [State any special notes, constraints or cautions for users of this function] 744 745 ------------------------------------------------------------------------------ 746 */ 747 void code_8i40_31bits( 748 Word16 x[], /* i : target vector */ 749 Word16 cn[], /* i : residual after long term prediction */ 750 Word16 h[], /* i : impulse response of weighted synthesis 751 filter */ 752 Word16 cod[], /* o : algebraic (fixed) codebook excitation */ 753 Word16 y[], /* o : filtered fixed codebook excitation */ 754 Word16 indx[], /* o : 7 Word16, index of 8 pulses (signs+positions) */ 755 Flag *pOverflow /* o : Flag set when overflow occurs */ 756 ) 757 { 758 Word16 ipos[NB_PULSE]; 759 Word16 pos_max[NB_TRACK_MR102]; 760 Word16 codvec[NB_PULSE]; 761 762 Word16 dn[L_CODE]; 763 Word16 sign[L_CODE]; 764 765 Word16 rr[L_CODE][L_CODE]; 766 Word16 linear_signs[NB_TRACK_MR102]; 767 Word16 linear_codewords[NB_PULSE]; 768 769 cor_h_x2( 770 h, 771 x, 772 dn, 773 2, 774 NB_TRACK_MR102, 775 STEP_MR102, 776 pOverflow); 777 778 /* 2 = use GSMEFR scaling */ 779 780 set_sign12k2( 781 dn, 782 cn, 783 sign, 784 pos_max, 785 NB_TRACK_MR102, 786 ipos, 787 STEP_MR102, 788 pOverflow); 789 790 /* same setsign alg as GSM-EFR new constants though*/ 791 792 cor_h( 793 h, 794 sign, 795 rr, 796 pOverflow); 797 798 search_10and8i40( 799 NB_PULSE, 800 STEP_MR102, 801 NB_TRACK_MR102, 802 dn, 803 rr, 804 ipos, 805 pos_max, 806 codvec, 807 pOverflow); 808 809 build_code( 810 codvec, 811 sign, 812 cod, 813 h, 814 y, 815 linear_signs, 816 linear_codewords, 817 pOverflow); 818 819 compress_code( 820 linear_signs, 821 linear_codewords, 822 indx, 823 pOverflow); 824 825 } /* code_8i40_31bits */ 826 827 828 829