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