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 Filename: pitch_fr.cpp 35 36 ------------------------------------------------------------------------------ 37 MODULE DESCRIPTION 38 39 File : pitch_fr.c 40 Purpose : Find the pitch period with 1/3 or 1/6 subsample 41 : resolution (closed loop). 42 43 ------------------------------------------------------------------------------ 44 */ 45 46 /*---------------------------------------------------------------------------- 47 ; INCLUDES 48 ----------------------------------------------------------------------------*/ 49 #include "pitch_fr.h" 50 #include "oper_32b.h" 51 #include "cnst.h" 52 #include "enc_lag3.h" 53 #include "enc_lag6.h" 54 #include "inter_36.h" 55 #include "inv_sqrt.h" 56 #include "convolve.h" 57 58 #include "basic_op.h" 59 #include "oscl_mem.h" 60 61 62 /*---------------------------------------------------------------------------- 63 ; MACROS 64 ; Define module specific macros here 65 ----------------------------------------------------------------------------*/ 66 67 /*---------------------------------------------------------------------------- 68 ; DEFINES 69 ; Include all pre-processor statements here. Include conditional 70 ; compile variables also. 71 ----------------------------------------------------------------------------*/ 72 73 /*---------------------------------------------------------------------------- 74 ; LOCAL FUNCTION DEFINITIONS 75 ; Function Prototype declaration 76 ----------------------------------------------------------------------------*/ 77 78 /*---------------------------------------------------------------------------- 79 ; LOCAL VARIABLE DEFINITIONS 80 ; Variable declaration - defined here and used outside this module 81 ----------------------------------------------------------------------------*/ 82 83 /* 84 * mode dependent parameters used in Pitch_fr() 85 * Note: order of MRxx in 'enum Mode' is important! 86 */ 87 static const struct 88 { 89 Word16 max_frac_lag; /* lag up to which fractional lags are used */ 90 Word16 flag3; /* enable 1/3 instead of 1/6 fract. resolution */ 91 Word16 first_frac; /* first fractional to check */ 92 Word16 last_frac; /* last fractional to check */ 93 Word16 delta_int_low; /* integer lag below TO to start search from */ 94 Word16 delta_int_range; /* integer range around T0 */ 95 Word16 delta_frc_low; /* fractional below T0 */ 96 Word16 delta_frc_range; /* fractional range around T0 */ 97 Word16 pit_min; /* minimum pitch */ 98 } mode_dep_parm[N_MODES] = 99 { 100 /* MR475 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, 101 /* MR515 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, 102 /* MR59 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, 103 /* MR67 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, 104 /* MR74 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, 105 /* MR795 */ { 84, 1, -2, 2, 3, 6, 10, 19, PIT_MIN }, 106 /* MR102 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, 107 /* MR122 */ { 94, 0, -3, 3, 3, 6, 5, 9, PIT_MIN_MR122 } 108 }; 109 110 /* 111 ------------------------------------------------------------------------------ 112 FUNCTION NAME: Norm_Corr 113 ------------------------------------------------------------------------------ 114 INPUT AND OUTPUT DEFINITIONS 115 116 Inputs: 117 exc[] = pointer to buffer of type Word16 118 xn[] = pointer to buffer of type Word16 119 h[] = pointer to buffer of type Word16 120 L_subfr = length of sub frame (Word16) 121 t_min = the minimum table value of type Word16 122 t_max = the maximum table value of type Word16 123 corr_norm[] = pointer to buffer of type Word16 124 125 Outputs: 126 pOverflow = 1 if the math functions called result in overflow else zero. 127 128 Returns: 129 None 130 131 Global Variables Used: 132 None 133 134 Local Variables Needed: 135 None 136 137 ------------------------------------------------------------------------------ 138 FUNCTION DESCRIPTION 139 140 FUNCTION: Norm_Corr() 141 142 PURPOSE: Find the normalized correlation between the target vector 143 and the filtered past excitation. 144 145 DESCRIPTION: 146 The normalized correlation is given by the correlation between the 147 target and filtered past excitation divided by the square root of 148 the energy of filtered excitation. 149 corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[]) 150 where x[] is the target vector and y_k[] is the filtered past 151 excitation at delay k. 152 153 154 ------------------------------------------------------------------------------ 155 REQUIREMENTS 156 157 None 158 159 ------------------------------------------------------------------------------ 160 REFERENCES 161 162 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 163 164 ------------------------------------------------------------------------------ 165 PSEUDO-CODE 166 167 static void Norm_Corr (Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr, 168 Word16 t_min, Word16 t_max, Word16 corr_norm[]) 169 { 170 Word16 i, j, k; 171 Word16 corr_h, corr_l, norm_h, norm_l; 172 Word32 s; 173 174 // Usally dynamic allocation of (L_subfr) 175 Word16 excf[L_SUBFR]; 176 Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR]; 177 178 k = -t_min; 179 180 // compute the filtered excitation for the first delay t_min 181 182 Convolve (&exc[k], h, excf, L_subfr); 183 184 // scale "excf[]" to avoid overflow 185 186 for (j = 0; j < L_subfr; j++) { 187 scaled_excf[j] = shr (excf[j], 2); 188 } 189 190 // Compute 1/sqrt(energy of excf[]) 191 192 s = 0; 193 for (j = 0; j < L_subfr; j++) { 194 s = L_mac (s, excf[j], excf[j]); 195 } 196 if (L_sub (s, 67108864L) <= 0) { // if (s <= 2^26) 197 s_excf = excf; 198 h_fac = 15 - 12; 199 scaling = 0; 200 } 201 else { 202 // "excf[]" is divided by 2 203 s_excf = scaled_excf; 204 h_fac = 15 - 12 - 2; 205 scaling = 2; 206 } 207 208 // loop for every possible period 209 210 for (i = t_min; i <= t_max; i++) { 211 // Compute 1/sqrt(energy of excf[]) 212 213 s = 0; 214 for (j = 0; j < L_subfr; j++) { 215 s = L_mac (s, s_excf[j], s_excf[j]); 216 } 217 218 s = Inv_sqrt (s); 219 L_Extract (s, &norm_h, &norm_l); 220 221 // Compute correlation between xn[] and excf[] 222 223 s = 0; 224 for (j = 0; j < L_subfr; j++) { 225 s = L_mac (s, xn[j], s_excf[j]); 226 } 227 L_Extract (s, &corr_h, &corr_l); 228 229 // Normalize correlation = correlation * (1/sqrt(energy)) 230 231 s = Mpy_32 (corr_h, corr_l, norm_h, norm_l); 232 233 corr_norm[i] = extract_h (L_shl (s, 16)); 234 235 // modify the filtered excitation excf[] for the next iteration 236 237 if (sub (i, t_max) != 0) { 238 k--; 239 for (j = L_subfr - 1; j > 0; j--) { 240 s = L_mult (exc[k], h[j]); 241 s = L_shl (s, h_fac); 242 s_excf[j] = add (extract_h (s), s_excf[j - 1]); 243 } 244 s_excf[0] = shr (exc[k], scaling); 245 } 246 } 247 return; 248 } 249 250 ------------------------------------------------------------------------------ 251 CAUTION [optional] 252 [State any special notes, constraints or cautions for users of this function] 253 254 ------------------------------------------------------------------------------ 255 */ 256 257 static void Norm_Corr(Word16 exc[], 258 Word16 xn[], 259 Word16 h[], 260 Word16 L_subfr, 261 Word16 t_min, 262 Word16 t_max, 263 Word16 corr_norm[], 264 Flag *pOverflow) 265 { 266 Word16 i; 267 Word16 j; 268 Word16 k; 269 Word16 corr_h; 270 Word16 corr_l; 271 Word16 norm_h; 272 Word16 norm_l; 273 Word32 s; 274 Word32 s2; 275 Word16 excf[L_SUBFR]; 276 Word16 scaling; 277 Word16 h_fac; 278 Word16 *s_excf; 279 Word16 scaled_excf[L_SUBFR]; 280 Word16 *p_s_excf; 281 Word16 *p_excf; 282 Word16 temp; 283 Word16 *p_x; 284 Word16 *p_h; 285 286 k = -t_min; 287 288 /* compute the filtered excitation for the first delay t_min */ 289 290 Convolve(&exc[k], h, excf, L_subfr); 291 292 /* scale "excf[]" to avoid overflow */ 293 s = 0; 294 p_s_excf = scaled_excf; 295 p_excf = excf; 296 297 for (j = (L_subfr >> 1); j != 0; j--) 298 { 299 temp = *(p_excf++); 300 *(p_s_excf++) = temp >> 2; 301 s += (Word32) temp * temp; 302 temp = *(p_excf++); 303 *(p_s_excf++) = temp >> 2; 304 s += (Word32) temp * temp; 305 } 306 307 308 if (s <= (67108864L >> 1)) 309 { 310 s_excf = excf; 311 h_fac = 12; 312 scaling = 0; 313 } 314 else 315 { 316 /* "excf[]" is divided by 2 */ 317 s_excf = scaled_excf; 318 h_fac = 14; 319 scaling = 2; 320 } 321 322 /* loop for every possible period */ 323 324 for (i = t_min; i <= t_max; i++) 325 { 326 /* Compute 1/sqrt(energy of excf[]) */ 327 328 s = s2 = 0; 329 p_x = xn; 330 p_s_excf = s_excf; 331 j = L_subfr >> 1; 332 333 while (j--) 334 { 335 s += (Word32) * (p_x++) * *(p_s_excf); 336 s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf))); 337 p_s_excf++; 338 s += (Word32) * (p_x++) * *(p_s_excf); 339 s2 += ((Word32)(*(p_s_excf)) * (*(p_s_excf))); 340 p_s_excf++; 341 } 342 343 s2 = s2 << 1; 344 s2 = Inv_sqrt(s2, pOverflow); 345 norm_h = (Word16)(s2 >> 16); 346 norm_l = (Word16)((s2 >> 1) - (norm_h << 15)); 347 corr_h = (Word16)(s >> 15); 348 corr_l = (Word16)((s) - (corr_h << 15)); 349 350 /* Normalize correlation = correlation * (1/sqrt(energy)) */ 351 352 s = Mpy_32(corr_h, corr_l, norm_h, norm_l, pOverflow); 353 354 corr_norm[i] = (Word16) s ; 355 356 /* modify the filtered excitation excf[] for the next iteration */ 357 if (i != t_max) 358 { 359 k--; 360 temp = exc[k]; 361 p_s_excf = &s_excf[L_subfr - 1]; 362 p_h = &h[L_subfr - 1]; 363 364 p_excf = &s_excf[L_subfr - 2]; 365 for (j = (L_subfr - 1) >> 1; j != 0; j--) 366 { 367 s = ((Word32) temp * *(p_h--)) >> h_fac; 368 *(p_s_excf--) = (Word16) s + *(p_excf--); 369 s = ((Word32) temp * *(p_h--)) >> h_fac; 370 *(p_s_excf--) = (Word16) s + *(p_excf--); 371 } 372 373 s = ((Word32) temp * *(p_h)) >> h_fac; 374 *(p_s_excf--) = (Word16) s + *(p_excf); 375 376 *(p_s_excf) = temp >> scaling; 377 } 378 379 } 380 return; 381 } 382 383 /****************************************************************************/ 384 385 386 /* 387 ------------------------------------------------------------------------------ 388 FUNCTION NAME: searchFrac 389 ------------------------------------------------------------------------------ 390 INPUT AND OUTPUT DEFINITIONS 391 392 Inputs: 393 lag = pointer to integer pitch of type Word16 394 frac = pointer to starting point of search fractional pitch of type Word16 395 last_frac = endpoint of search of type Word16 396 corr[] = pointer to normalized correlation of type Word16 397 flag3 = subsample resolution (3: =1 / 6: =0) of type Word16 398 399 Outputs: 400 None 401 402 Returns: 403 None 404 405 Global Variables Used: 406 None 407 408 Local Variables Needed: 409 None 410 411 ------------------------------------------------------------------------------ 412 FUNCTION DESCRIPTION 413 414 FUNCTION: searchFrac() 415 416 PURPOSE: Find fractional pitch 417 418 DESCRIPTION: 419 The function interpolates the normalized correlation at the 420 fractional positions around lag T0. The position at which the 421 interpolation function reaches its maximum is the fractional pitch. 422 Starting point of the search is frac, end point is last_frac. 423 frac is overwritten with the fractional pitch. 424 425 ------------------------------------------------------------------------------ 426 REQUIREMENTS 427 428 None 429 430 ------------------------------------------------------------------------------ 431 REFERENCES 432 433 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 434 435 ------------------------------------------------------------------------------ 436 PSEUDO-CODE 437 438 static void searchFrac ( 439 Word16 *lag, // i/o : integer pitch 440 Word16 *frac, // i/o : start point of search - 441 fractional pitch 442 Word16 last_frac, // i : endpoint of search 443 Word16 corr[], // i : normalized correlation 444 Word16 flag3 // i : subsample resolution 445 (3: =1 / 6: =0) 446 ) 447 { 448 Word16 i; 449 Word16 max; 450 Word16 corr_int; 451 452 // Test the fractions around T0 and choose the one which maximizes 453 // the interpolated normalized correlation. 454 455 max = Interpol_3or6 (&corr[*lag], *frac, flag3); // function result 456 457 for (i = add (*frac, 1); i <= last_frac; i++) { 458 corr_int = Interpol_3or6 (&corr[*lag], i, flag3); 459 if (sub (corr_int, max) > 0) { 460 max = corr_int; 461 *frac = i; 462 } 463 } 464 465 if (flag3 == 0) { 466 // Limit the fraction value in the interval [-2,-1,0,1,2,3] 467 468 if (sub (*frac, -3) == 0) { 469 *frac = 3; 470 *lag = sub (*lag, 1); 471 } 472 } 473 else { 474 // limit the fraction value between -1 and 1 475 476 if (sub (*frac, -2) == 0) { 477 *frac = 1; 478 *lag = sub (*lag, 1); 479 } 480 if (sub (*frac, 2) == 0) { 481 *frac = -1; 482 *lag = add (*lag, 1); 483 } 484 } 485 } 486 487 ------------------------------------------------------------------------------ 488 CAUTION [optional] 489 [State any special notes, constraints or cautions for users of this function] 490 491 ------------------------------------------------------------------------------ 492 */ 493 494 static void searchFrac( 495 Word16 *lag, /* i/o : integer pitch */ 496 Word16 *frac, /* i/o : start point of search - 497 fractional pitch */ 498 Word16 last_frac, /* i : endpoint of search */ 499 Word16 corr[], /* i : normalized correlation */ 500 Word16 flag3, /* i : subsample resolution 501 (3: =1 / 6: =0) */ 502 Flag *pOverflow 503 ) 504 { 505 Word16 i; 506 Word16 max; 507 Word16 corr_int; 508 509 /* Test the fractions around T0 and choose the one which maximizes */ 510 /* the interpolated normalized correlation. */ 511 512 max = Interpol_3or6(&corr[*lag], *frac, flag3, pOverflow); 513 /* function result */ 514 515 for (i = *frac + 1; i <= last_frac; i++) 516 { 517 corr_int = Interpol_3or6(&corr[*lag], i, flag3, pOverflow); 518 if (corr_int > max) 519 { 520 max = corr_int; 521 *frac = i; 522 } 523 } 524 525 if (flag3 == 0) 526 { 527 /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */ 528 529 if (*frac == -3) 530 { 531 *frac = 3; 532 (*lag)--; 533 } 534 } 535 else 536 { 537 /* limit the fraction value between -1 and 1 */ 538 539 if (*frac == -2) 540 { 541 *frac = 1; 542 (*lag)--; 543 } 544 if (*frac == 2) 545 { 546 *frac = -1; 547 (*lag)++; 548 } 549 } 550 } 551 552 /****************************************************************************/ 553 554 555 /* 556 ------------------------------------------------------------------------------ 557 FUNCTION NAME: getRange 558 ------------------------------------------------------------------------------ 559 INPUT AND OUTPUT DEFINITIONS 560 561 Inputs: 562 T0 = integer pitch of type Word16 563 delta_low = search start offset of type Word16 564 delta_range = search range of type Word16 565 pitmin = minimum pitch of type Word16 566 pitmax = maximum pitch of type Word16 567 t0_min = search range minimum of type Word16 568 t0_max = search range maximum of type Word16 569 570 Outputs: 571 pOverflow = 1 if the math functions called result in overflow else zero. 572 573 Returns: 574 None 575 576 Global Variables Used: 577 None 578 579 Local Variables Needed: 580 None 581 582 ------------------------------------------------------------------------------ 583 FUNCTION DESCRIPTION 584 585 FUNCTION: getRange() 586 587 PURPOSE: Sets range around open-loop pitch or integer pitch of last subframe 588 589 DESCRIPTION: 590 Takes integer pitch T0 and calculates a range around it with 591 t0_min = T0-delta_low and t0_max = (T0-delta_low) + delta_range 592 t0_min and t0_max are bounded by pitmin and pitmax 593 ------------------------------------------------------------------------------ 594 REQUIREMENTS 595 596 None 597 598 ------------------------------------------------------------------------------ 599 REFERENCES 600 601 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 602 603 ------------------------------------------------------------------------------ 604 PSEUDO-CODE 605 606 static void getRange ( 607 Word16 T0, // i : integer pitch 608 Word16 delta_low, // i : search start offset 609 Word16 delta_range, // i : search range 610 Word16 pitmin, // i : minimum pitch 611 Word16 pitmax, // i : maximum pitch 612 Word16 *t0_min, // o : search range minimum 613 Word16 *t0_max) // o : search range maximum 614 { 615 *t0_min = sub(T0, delta_low); 616 if (sub(*t0_min, pitmin) < 0) { 617 *t0_min = pitmin; 618 } 619 *t0_max = add(*t0_min, delta_range); 620 if (sub(*t0_max, pitmax) > 0) { 621 *t0_max = pitmax; 622 *t0_min = sub(*t0_max, delta_range); 623 } 624 } 625 626 ------------------------------------------------------------------------------ 627 CAUTION [optional] 628 [State any special notes, constraints or cautions for users of this function] 629 630 ------------------------------------------------------------------------------ 631 */ 632 static void getRange( 633 Word16 T0, /* i : integer pitch */ 634 Word16 delta_low, /* i : search start offset */ 635 Word16 delta_range, /* i : search range */ 636 Word16 pitmin, /* i : minimum pitch */ 637 Word16 pitmax, /* i : maximum pitch */ 638 Word16 *t0_min, /* o : search range minimum */ 639 Word16 *t0_max, /* o : search range maximum */ 640 Flag *pOverflow) 641 { 642 643 Word16 temp; 644 OSCL_UNUSED_ARG(pOverflow); 645 646 temp = *t0_min; 647 temp = T0 - delta_low; 648 if (temp < pitmin) 649 { 650 temp = pitmin; 651 } 652 *t0_min = temp; 653 654 temp += delta_range; 655 if (temp > pitmax) 656 { 657 temp = pitmax; 658 *t0_min = pitmax - delta_range; 659 } 660 *t0_max = temp; 661 662 } 663 664 665 /****************************************************************************/ 666 667 668 /* 669 ------------------------------------------------------------------------------ 670 FUNCTION NAME: Pitch_fr_init 671 ------------------------------------------------------------------------------ 672 INPUT AND OUTPUT DEFINITIONS 673 674 Inputs: 675 state = pointer to a pointer of structure type Pitch_fr_State. 676 677 Outputs: 678 None 679 680 Returns: 681 Returns a zero if successful and -1 if not successful. 682 683 Global Variables Used: 684 None 685 686 Local Variables Needed: 687 None 688 689 ------------------------------------------------------------------------------ 690 FUNCTION DESCRIPTION 691 692 Function: Pitch_fr_init 693 Purpose: Allocates state memory and initializes state memory 694 695 ------------------------------------------------------------------------------ 696 REQUIREMENTS 697 698 None 699 700 ------------------------------------------------------------------------------ 701 REFERENCES 702 703 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 704 705 ------------------------------------------------------------------------------ 706 PSEUDO-CODE 707 708 int Pitch_fr_init (Pitch_frState **state) 709 { 710 Pitch_frState* s; 711 712 if (state == (Pitch_frState **) NULL){ 713 // fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); 714 return -1; 715 } 716 *state = NULL; 717 718 // allocate memory 719 if ((s= (Pitch_frState *) malloc(sizeof(Pitch_frState))) == NULL){ 720 // fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); 721 return -1; 722 } 723 724 Pitch_fr_reset(s); 725 *state = s; 726 727 return 0; 728 } 729 730 ------------------------------------------------------------------------------ 731 CAUTION [optional] 732 [State any special notes, constraints or cautions for users of this function] 733 734 ------------------------------------------------------------------------------ 735 */ 736 Word16 Pitch_fr_init(Pitch_frState **state) 737 { 738 Pitch_frState* s; 739 740 if (state == (Pitch_frState **) NULL) 741 { 742 /* fprintf(stderr, "Pitch_fr_init: invalid parameter\n"); */ 743 return -1; 744 } 745 *state = NULL; 746 747 /* allocate memory */ 748 if ((s = (Pitch_frState *) oscl_malloc(sizeof(Pitch_frState))) == NULL) 749 { 750 /* fprintf(stderr, "Pitch_fr_init: can not malloc state structure\n"); */ 751 return -1; 752 } 753 754 Pitch_fr_reset(s); 755 *state = s; 756 757 return 0; 758 } 759 760 761 /****************************************************************************/ 762 763 764 /* 765 ------------------------------------------------------------------------------ 766 FUNCTION NAME: Pitch_fr_reset 767 ------------------------------------------------------------------------------ 768 INPUT AND OUTPUT DEFINITIONS 769 770 Inputs: 771 state = pointer to a pointer of structure type Pitch_fr_State. 772 773 Outputs: 774 None 775 776 Returns: 777 Returns a zero if successful and -1 if not successful. 778 779 Global Variables Used: 780 None 781 782 Local Variables Needed: 783 None 784 785 ------------------------------------------------------------------------------ 786 FUNCTION DESCRIPTION 787 788 Function: Pitch_fr_reset 789 Purpose: Initializes state memory to zero 790 791 ------------------------------------------------------------------------------ 792 REQUIREMENTS 793 794 None 795 796 ------------------------------------------------------------------------------ 797 REFERENCES 798 799 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 800 801 ------------------------------------------------------------------------------ 802 PSEUDO-CODE 803 804 int Pitch_fr_reset (Pitch_frState *state) 805 { 806 807 if (state == (Pitch_frState *) NULL){ 808 // fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); 809 return -1; 810 } 811 812 state->T0_prev_subframe = 0; 813 814 return 0; 815 } 816 817 ------------------------------------------------------------------------------ 818 CAUTION [optional] 819 [State any special notes, constraints or cautions for users of this function] 820 821 ------------------------------------------------------------------------------ 822 */ 823 Word16 Pitch_fr_reset(Pitch_frState *state) 824 { 825 826 if (state == (Pitch_frState *) NULL) 827 { 828 /* fprintf(stderr, "Pitch_fr_reset: invalid parameter\n"); */ 829 return -1; 830 } 831 832 state->T0_prev_subframe = 0; 833 834 return 0; 835 } 836 837 838 /****************************************************************************/ 839 840 841 /* 842 ------------------------------------------------------------------------------ 843 FUNCTION NAME: Pitch_fr_exit 844 ------------------------------------------------------------------------------ 845 INPUT AND OUTPUT DEFINITIONS 846 847 Inputs: 848 state = pointer to a pointer of structure type Pitch_fr_State. 849 850 Outputs: 851 None 852 853 Returns: 854 None 855 856 Global Variables Used: 857 None 858 859 Local Variables Needed: 860 None 861 862 ------------------------------------------------------------------------------ 863 FUNCTION DESCRIPTION 864 865 Function: Pitch_fr_exit 866 Purpose: The memory for state is freed. 867 868 ------------------------------------------------------------------------------ 869 REQUIREMENTS 870 871 None 872 873 ------------------------------------------------------------------------------ 874 REFERENCES 875 876 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 877 878 ------------------------------------------------------------------------------ 879 PSEUDO-CODE 880 881 void Pitch_fr_exit (Pitch_frState **state) 882 { 883 if (state == NULL || *state == NULL) 884 return; 885 886 // deallocate memory 887 free(*state); 888 *state = NULL; 889 890 return; 891 } 892 893 ------------------------------------------------------------------------------ 894 CAUTION [optional] 895 [State any special notes, constraints or cautions for users of this function] 896 897 ------------------------------------------------------------------------------ 898 */ 899 void Pitch_fr_exit(Pitch_frState **state) 900 { 901 if (state == NULL || *state == NULL) 902 return; 903 904 /* deallocate memory */ 905 oscl_free(*state); 906 *state = NULL; 907 908 return; 909 } 910 911 /****************************************************************************/ 912 913 914 /* 915 ------------------------------------------------------------------------------ 916 FUNCTION NAME: Pitch_fr 917 ------------------------------------------------------------------------------ 918 INPUT AND OUTPUT DEFINITIONS 919 920 Inputs: 921 st = pointer to stat structure of type Pitch_frState 922 mode = codec mode of type enum Mode 923 T_op[] = pointer to open loop pitch lags of type Word16 924 exc[] = pointer to excitation buffer of type Word16 925 xn[] = pointer to target vector of type Word16 926 h[] = pointer to impulse response of synthesis and weighting filters 927 of type Word16 928 L_subfr = length of subframe of type Word16 929 i_subfr = subframe offset of type Word16 930 931 Outputs: 932 pit_frac = pointer to pitch period (fractional) of type Word16 933 resu3 = pointer to subsample resolution of type Word16 934 ana_index = pointer to index of encoding of type Word16 935 936 Returns: 937 None 938 939 Global Variables Used: 940 None 941 942 Local Variables Needed: 943 None 944 945 ------------------------------------------------------------------------------ 946 FUNCTION DESCRIPTION 947 948 FUNCTION: Pitch_fr() 949 950 PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution 951 (closed loop). 952 953 DESCRIPTION: 954 - find the normalized correlation between the target and filtered 955 past excitation in the search range. 956 - select the delay with maximum normalized correlation. 957 - interpolate the normalized correlation at fractions -3/6 to 3/6 958 with step 1/6 around the chosen delay. 959 - The fraction which gives the maximum interpolated value is chosen. 960 961 ------------------------------------------------------------------------------ 962 REQUIREMENTS 963 964 None 965 966 ------------------------------------------------------------------------------ 967 REFERENCES 968 969 pitch_fr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 970 971 ------------------------------------------------------------------------------ 972 PSEUDO-CODE 973 974 Word16 Pitch_fr ( // o : pitch period (integer) 975 Pitch_frState *st, // i/o : State struct 976 enum Mode mode, // i : codec mode 977 Word16 T_op[], // i : open loop pitch lags 978 Word16 exc[], // i : excitation buffer Q0 979 Word16 xn[], // i : target vector Q0 980 Word16 h[], // i : impulse response of synthesis and 981 weighting filters Q12 982 Word16 L_subfr, // i : Length of subframe 983 Word16 i_subfr, // i : subframe offset 984 Word16 *pit_frac, // o : pitch period (fractional) 985 Word16 *resu3, // o : subsample resolution 1/3 (=1) or 1/6 (=0) 986 Word16 *ana_index // o : index of encoding 987 ) 988 { 989 Word16 i; 990 Word16 t_min, t_max; 991 Word16 t0_min, t0_max; 992 Word16 max, lag, frac; 993 Word16 tmp_lag; 994 Word16 *corr; 995 Word16 corr_v[40]; // Total length = t0_max-t0_min+1+2*L_INTER_SRCH 996 997 Word16 max_frac_lag; 998 Word16 flag3, flag4; 999 Word16 last_frac; 1000 Word16 delta_int_low, delta_int_range; 1001 Word16 delta_frc_low, delta_frc_range; 1002 Word16 pit_min; 1003 Word16 frame_offset; 1004 Word16 delta_search; 1005 1006 //----------------------------------------------------------------------- 1007 // set mode specific variables 1008 //---------------------------------------------------------------------- 1009 1010 max_frac_lag = mode_dep_parm[mode].max_frac_lag; 1011 flag3 = mode_dep_parm[mode].flag3; 1012 frac = mode_dep_parm[mode].first_frac; 1013 last_frac = mode_dep_parm[mode].last_frac; 1014 delta_int_low = mode_dep_parm[mode].delta_int_low; 1015 delta_int_range = mode_dep_parm[mode].delta_int_range; 1016 1017 delta_frc_low = mode_dep_parm[mode].delta_frc_low; 1018 delta_frc_range = mode_dep_parm[mode].delta_frc_range; 1019 pit_min = mode_dep_parm[mode].pit_min; 1020 1021 //----------------------------------------------------------------------- 1022 // decide upon full or differential search 1023 //----------------------------------------------------------------------- 1024 1025 delta_search = 1; 1026 1027 if ((i_subfr == 0) || (sub(i_subfr,L_FRAME_BY2) == 0)) { 1028 1029 // Subframe 1 and 3 1030 1031 if (((sub((Word16)mode, (Word16)MR475) != 0) && (sub((Word16)mode, 1032 (Word16)MR515) != 0)) || 1033 (sub(i_subfr,L_FRAME_BY2) != 0)) { 1034 1035 // set t0_min, t0_max for full search 1036 // this is *not* done for mode MR475, MR515 in subframe 3 1037 1038 delta_search = 0; // no differential search 1039 1040 // calculate index into T_op which contains the open-loop 1041 // pitch estimations for the 2 big subframes 1042 1043 frame_offset = 1; 1044 if (i_subfr == 0) 1045 frame_offset = 0; 1046 1047 // get T_op from the corresponding half frame and 1048 // set t0_min, t0_max 1049 1050 getRange (T_op[frame_offset], delta_int_low, delta_int_range, 1051 pit_min, PIT_MAX, &t0_min, &t0_max); 1052 } 1053 else { 1054 1055 // mode MR475, MR515 and 3. Subframe: delta search as well 1056 getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range, 1057 pit_min, PIT_MAX, &t0_min, &t0_max); 1058 } 1059 } 1060 else { 1061 1062 // for Subframe 2 and 4 1063 // get range around T0 of previous subframe for delta search 1064 1065 getRange (st->T0_prev_subframe, delta_frc_low, delta_frc_range, 1066 pit_min, PIT_MAX, &t0_min, &t0_max); 1067 } 1068 1069 //----------------------------------------------------------------------- 1070 Find interval to compute normalized correlation 1071 ----------------------------------------------------------------------- 1072 1073 t_min = sub (t0_min, L_INTER_SRCH); 1074 t_max = add (t0_max, L_INTER_SRCH); 1075 1076 corr = &corr_v[-t_min]; 1077 1078 //----------------------------------------------------------------------- 1079 Compute normalized correlation between target and filtered excitation 1080 ----------------------------------------------------------------------- 1081 1082 Norm_Corr (exc, xn, h, L_subfr, t_min, t_max, corr); 1083 1084 //----------------------------------------------------------------------- 1085 Find integer pitch 1086 ----------------------------------------------------------------------- 1087 1088 max = corr[t0_min]; 1089 lag = t0_min; 1090 1091 for (i = t0_min + 1; i <= t0_max; i++) { 1092 if (sub (corr[i], max) >= 0) { 1093 max = corr[i]; 1094 lag = i; 1095 } 1096 } 1097 1098 //----------------------------------------------------------------------- 1099 Find fractional pitch 1100 ----------------------------------------------------------------------- 1101 if ((delta_search == 0) && (sub (lag, max_frac_lag) > 0)) { 1102 1103 // full search and integer pitch greater than max_frac_lag 1104 // fractional search is not needed, set fractional to zero 1105 1106 frac = 0; 1107 } 1108 else { 1109 1110 // if differential search AND mode MR475 OR MR515 OR MR59 OR MR67 1111 // then search fractional with 4 bits resolution 1112 1113 if ((delta_search != 0) && 1114 ((sub ((Word16)mode, (Word16)MR475) == 0) || 1115 (sub ((Word16)mode, (Word16)MR515) == 0) || 1116 (sub ((Word16)mode, (Word16)MR59) == 0) || 1117 (sub ((Word16)mode, (Word16)MR67) == 0))) { 1118 1119 // modify frac or last_frac according to position of last 1120 // integer pitch: either search around integer pitch, 1121 // or only on left or right side 1122 1123 tmp_lag = st->T0_prev_subframe; 1124 if ( sub( sub(tmp_lag, t0_min), 5) > 0) 1125 tmp_lag = add (t0_min, 5); 1126 if ( sub( sub(t0_max, tmp_lag), 4) > 0) 1127 tmp_lag = sub (t0_max, 4); 1128 1129 if ((sub (lag, tmp_lag) == 0) || 1130 (sub (lag, sub(tmp_lag, 1)) == 0)) { 1131 1132 // normal search in fractions around T0 1133 1134 searchFrac (&lag, &frac, last_frac, corr, flag3); 1135 1136 } 1137 else if (sub (lag, sub (tmp_lag, 2)) == 0) { 1138 // limit search around T0 to the right side 1139 frac = 0; 1140 searchFrac (&lag, &frac, last_frac, corr, flag3); 1141 } 1142 else if (sub (lag, add(tmp_lag, 1)) == 0) { 1143 // limit search around T0 to the left side 1144 last_frac = 0; 1145 searchFrac (&lag, &frac, last_frac, corr, flag3); 1146 } 1147 else { 1148 // no fractional search 1149 frac = 0; 1150 } 1151 } 1152 else 1153 // test the fractions around T0 1154 searchFrac (&lag, &frac, last_frac, corr, flag3); 1155 } 1156 1157 //----------------------------------------------------------------------- 1158 // encode pitch 1159 //----------------------------------------------------------------------- 1160 1161 if (flag3 != 0) { 1162 // flag4 indicates encoding with 4 bit resolution; 1163 // this is needed for mode MR475, MR515 and MR59 1164 1165 flag4 = 0; 1166 if ( (sub ((Word16)mode, (Word16)MR475) == 0) || 1167 (sub ((Word16)mode, (Word16)MR515) == 0) || 1168 (sub ((Word16)mode, (Word16)MR59) == 0) || 1169 (sub ((Word16)mode, (Word16)MR67) == 0) ) { 1170 flag4 = 1; 1171 } 1172 1173 // encode with 1/3 subsample resolution 1174 1175 *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe, 1176 t0_min, t0_max, delta_search, flag4); 1177 // function result 1178 1179 } 1180 else 1181 { 1182 // encode with 1/6 subsample resolution 1183 1184 *ana_index = Enc_lag6(lag, frac, t0_min, delta_search); 1185 // function result 1186 } 1187 1188 //----------------------------------------------------------------------- 1189 // update state variables 1190 //----------------------------------------------------------------------- 1191 1192 st->T0_prev_subframe = lag; 1193 1194 //----------------------------------------------------------------------- 1195 // update output variables 1196 //----------------------------------------------------------------------- 1197 1198 *resu3 = flag3; 1199 1200 *pit_frac = frac; 1201 1202 return (lag); 1203 } 1204 1205 1206 ------------------------------------------------------------------------------ 1207 CAUTION [optional] 1208 [State any special notes, constraints or cautions for users of this function] 1209 1210 ------------------------------------------------------------------------------ 1211 */ 1212 Word16 Pitch_fr( /* o : pitch period (integer) */ 1213 Pitch_frState *st, /* i/o : State struct */ 1214 enum Mode mode, /* i : codec mode */ 1215 Word16 T_op[], /* i : open loop pitch lags */ 1216 Word16 exc[], /* i : excitation buffer Q0 */ 1217 Word16 xn[], /* i : target vector Q0 */ 1218 Word16 h[], /* i : impulse response of synthesis and 1219 weighting filters Q12 */ 1220 Word16 L_subfr, /* i : Length of subframe */ 1221 Word16 i_subfr, /* i : subframe offset */ 1222 Word16 *pit_frac, /* o : pitch period (fractional) */ 1223 Word16 *resu3, /* o : subsample resolution 1/3 (=1) or 1/6 (=0) */ 1224 Word16 *ana_index, /* o : index of encoding */ 1225 Flag *pOverflow 1226 ) 1227 { 1228 Word16 i; 1229 Word16 t_min; 1230 Word16 t_max; 1231 Word16 t0_min = 0; 1232 Word16 t0_max; 1233 Word16 max; 1234 Word16 lag; 1235 Word16 frac; 1236 Word16 tmp_lag; 1237 Word16 *corr; 1238 Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */ 1239 1240 Word16 max_frac_lag; 1241 Word16 flag3; 1242 Word16 flag4; 1243 Word16 last_frac; 1244 Word16 delta_int_low; 1245 Word16 delta_int_range; 1246 Word16 delta_frc_low; 1247 Word16 delta_frc_range; 1248 Word16 pit_min; 1249 Word16 frame_offset; 1250 Word16 delta_search; 1251 1252 /*-----------------------------------------------------------------------* 1253 * set mode specific variables * 1254 *-----------------------------------------------------------------------*/ 1255 1256 max_frac_lag = mode_dep_parm[mode].max_frac_lag; 1257 flag3 = mode_dep_parm[mode].flag3; 1258 frac = mode_dep_parm[mode].first_frac; 1259 last_frac = mode_dep_parm[mode].last_frac; 1260 delta_int_low = mode_dep_parm[mode].delta_int_low; 1261 delta_int_range = mode_dep_parm[mode].delta_int_range; 1262 1263 delta_frc_low = mode_dep_parm[mode].delta_frc_low; 1264 delta_frc_range = mode_dep_parm[mode].delta_frc_range; 1265 pit_min = mode_dep_parm[mode].pit_min; 1266 1267 /*-----------------------------------------------------------------------* 1268 * decide upon full or differential search * 1269 *-----------------------------------------------------------------------*/ 1270 1271 delta_search = 1; 1272 1273 if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2)) 1274 { 1275 1276 /* Subframe 1 and 3 */ 1277 1278 if (((mode != MR475) && (mode != MR515)) || (i_subfr != L_FRAME_BY2)) 1279 { 1280 1281 /* set t0_min, t0_max for full search */ 1282 /* this is *not* done for mode MR475, MR515 in subframe 3 */ 1283 1284 delta_search = 0; /* no differential search */ 1285 1286 /* calculate index into T_op which contains the open-loop */ 1287 /* pitch estimations for the 2 big subframes */ 1288 1289 frame_offset = 1; 1290 if (i_subfr == 0) 1291 frame_offset = 0; 1292 1293 /* get T_op from the corresponding half frame and */ 1294 /* set t0_min, t0_max */ 1295 1296 getRange(T_op[frame_offset], delta_int_low, delta_int_range, 1297 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow); 1298 } 1299 else 1300 { 1301 1302 /* mode MR475, MR515 and 3. Subframe: delta search as well */ 1303 getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range, 1304 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow); 1305 } 1306 } 1307 else 1308 { 1309 1310 /* for Subframe 2 and 4 */ 1311 /* get range around T0 of previous subframe for delta search */ 1312 1313 getRange(st->T0_prev_subframe, delta_frc_low, delta_frc_range, 1314 pit_min, PIT_MAX, &t0_min, &t0_max, pOverflow); 1315 } 1316 1317 /*-----------------------------------------------------------------------* 1318 * Find interval to compute normalized correlation * 1319 *-----------------------------------------------------------------------*/ 1320 1321 t_min = t0_min - L_INTER_SRCH; 1322 t_max = t0_max + L_INTER_SRCH; 1323 1324 corr = &corr_v[-t_min]; 1325 1326 /*-----------------------------------------------------------------------* 1327 * Compute normalized correlation between target and filtered excitation * 1328 *-----------------------------------------------------------------------*/ 1329 1330 Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr, pOverflow); 1331 1332 /*-----------------------------------------------------------------------* 1333 * Find integer pitch * 1334 *-----------------------------------------------------------------------*/ 1335 1336 max = corr[t0_min]; 1337 lag = t0_min; 1338 1339 for (i = t0_min + 1; i <= t0_max; i++) 1340 { 1341 if (corr[i] >= max) 1342 { 1343 max = corr[i]; 1344 lag = i; 1345 } 1346 } 1347 1348 /*-----------------------------------------------------------------------* 1349 * Find fractional pitch * 1350 *-----------------------------------------------------------------------*/ 1351 if ((delta_search == 0) && (lag > max_frac_lag)) 1352 { 1353 1354 /* full search and integer pitch greater than max_frac_lag */ 1355 /* fractional search is not needed, set fractional to zero */ 1356 1357 frac = 0; 1358 } 1359 else 1360 { 1361 1362 /* if differential search AND mode MR475 OR MR515 OR MR59 OR MR67 */ 1363 /* then search fractional with 4 bits resolution */ 1364 1365 if ((delta_search != 0) && 1366 ((mode == MR475) || (mode == MR515) || 1367 (mode == MR59) || (mode == MR67))) 1368 { 1369 1370 /* modify frac or last_frac according to position of last */ 1371 /* integer pitch: either search around integer pitch, */ 1372 /* or only on left or right side */ 1373 1374 tmp_lag = st->T0_prev_subframe; 1375 if ((tmp_lag - t0_min) > 5) 1376 { 1377 tmp_lag = t0_min + 5; 1378 } 1379 if ((t0_max - tmp_lag) > 4) 1380 { 1381 tmp_lag = t0_max - 4; 1382 } 1383 1384 if ((lag == tmp_lag) || (lag == (tmp_lag - 1))) 1385 { 1386 1387 /* normal search in fractions around T0 */ 1388 1389 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); 1390 1391 } 1392 else if (lag == (tmp_lag - 2)) 1393 { 1394 /* limit search around T0 to the right side */ 1395 frac = 0; 1396 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); 1397 } 1398 else if (lag == (tmp_lag + 1)) 1399 { 1400 /* limit search around T0 to the left side */ 1401 last_frac = 0; 1402 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); 1403 } 1404 else 1405 { 1406 /* no fractional search */ 1407 frac = 0; 1408 } 1409 } 1410 else 1411 /* test the fractions around T0 */ 1412 searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow); 1413 } 1414 1415 /*-----------------------------------------------------------------------* 1416 * encode pitch * 1417 *-----------------------------------------------------------------------*/ 1418 1419 if (flag3 != 0) 1420 { 1421 /* flag4 indicates encoding with 4 bit resolution; */ 1422 /* this is needed for mode MR475, MR515 and MR59 */ 1423 1424 flag4 = 0; 1425 if ((mode == MR475) || (mode == MR515) || 1426 (mode == MR59) || (mode == MR67)) 1427 { 1428 flag4 = 1; 1429 } 1430 1431 /* encode with 1/3 subsample resolution */ 1432 1433 *ana_index = Enc_lag3(lag, frac, st->T0_prev_subframe, 1434 t0_min, t0_max, delta_search, flag4, pOverflow); 1435 /* function result */ 1436 1437 } 1438 else 1439 { 1440 /* encode with 1/6 subsample resolution */ 1441 1442 *ana_index = Enc_lag6(lag, frac, t0_min, delta_search, pOverflow); 1443 /* function result */ 1444 } 1445 1446 /*-----------------------------------------------------------------------* 1447 * update state variables * 1448 *-----------------------------------------------------------------------*/ 1449 1450 st->T0_prev_subframe = lag; 1451 1452 /*-----------------------------------------------------------------------* 1453 * update output variables * 1454 *-----------------------------------------------------------------------*/ 1455 1456 *resu3 = flag3; 1457 1458 *pit_frac = frac; 1459 1460 return (lag); 1461 } 1462 1463