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