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/ph_disp.c 35 Functions: 36 ph_disp_reset 37 ph_disp_lock 38 ph_disp_release 39 ph_disp 40 41 Date: 04/05/2000 42 43 ------------------------------------------------------------------------------ 44 REVISION HISTORY 45 46 Description: Changed template used to PV coding template. First attempt at 47 optimizing C code. 48 49 Description: Updated file per comments gathered from Phase 2/3 review. 50 51 Description: Clarified grouping in the equation to calculated L_temp from the 52 product of state->prevCbGain and ONFACTPLUS1 in the ph_disp 53 function. 54 55 Description: Added setting of Overflow flag in inlined code. 56 57 Description: Synchronized file with UMTS version 3.2.0. Updated coding 58 coding template. Removed unnecessary include files. 59 60 Description: Replaced basic_op.h with the header file of the math functions 61 used in the file. 62 63 Description: Removed the functions ph_disp_init and ph_disp_exit. 64 The ph_disp related structure is no longer dynamically allocated. 65 66 Description: Pass in pointer to overflow flag for EPOC compatibility. 67 Change code for ph_disp() function to reflect this. Remove 68 inclusion of ph_disp.tab. This table will now be referenced 69 externally. 70 71 Description: Optimized ph_disp() to reduce clock cycle usage. Updated 72 copyright year and removed unused files in Include section. 73 74 Description: Replaced OSCL mem type functions and eliminated include 75 files that now are chosen by OSCL definitions 76 77 Description: Replaced "int" and/or "char" with defined types. 78 Added proper casting (Word32) to some left shifting operations 79 80 Description: Changed round function name to pv_round to avoid conflict with 81 round function in C standard library. 82 83 Description: 84 85 ------------------------------------------------------------------------------ 86 MODULE DESCRIPTION 87 88 This file contains the function that performs adaptive phase dispersion of 89 the excitation signal. The phase dispersion initialization, reset, and 90 exit functions are included in this file, as well as, the phase dispersion 91 lock and release functions. 92 93 ------------------------------------------------------------------------------ 94 */ 95 96 /*---------------------------------------------------------------------------- 97 ; INCLUDES 98 ----------------------------------------------------------------------------*/ 99 #include "ph_disp.h" 100 #include "typedef.h" 101 #include "basic_op.h" 102 #include "cnst.h" 103 104 /*---------------------------------------------------------------------------- 105 ; MACROS 106 ; Define module specific macros here 107 ----------------------------------------------------------------------------*/ 108 109 /*---------------------------------------------------------------------------- 110 ; DEFINES 111 ; Include all pre-processor statements here. Include conditional 112 ; compile variables also. 113 ----------------------------------------------------------------------------*/ 114 115 /*---------------------------------------------------------------------------- 116 ; LOCAL FUNCTION DEFINITIONS 117 ; Function Prototype declaration 118 ----------------------------------------------------------------------------*/ 119 120 /*---------------------------------------------------------------------------- 121 ; LOCAL VARIABLE DEFINITIONS 122 ; Variable declaration - defined here and used outside this module 123 ----------------------------------------------------------------------------*/ 124 125 126 /* 127 ------------------------------------------------------------------------------ 128 FUNCTION NAME: ph_disp_reset 129 ------------------------------------------------------------------------------ 130 INPUT AND OUTPUT DEFINITIONS 131 132 Inputs: 133 state = pointer to a structure of type ph_dispState 134 135 Outputs: 136 Structure pointed to by state is initialized to zeros 137 138 Returns: 139 return_value = 0, if reset was successful; -1, otherwise (int) 140 141 Global Variables Used: 142 None 143 144 Local Variables Needed: 145 None 146 147 ------------------------------------------------------------------------------ 148 FUNCTION DESCRIPTION 149 150 This function resets the variables used by the phase dispersion function. 151 152 ------------------------------------------------------------------------------ 153 REQUIREMENTS 154 155 None 156 157 ------------------------------------------------------------------------------ 158 REFERENCES 159 160 ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 161 162 ------------------------------------------------------------------------------ 163 PSEUDO-CODE 164 165 int ph_disp_reset (ph_dispState *state) 166 { 167 Word16 i; 168 169 if (state == (ph_dispState *) NULL){ 170 fprint(stderr, "ph_disp_reset: invalid parameter\n"); 171 return -1; 172 } 173 for (i=0; i<PHDGAINMEMSIZE; i++) 174 { 175 state->gainMem[i] = 0; 176 } 177 state->prevState = 0; 178 state->prevCbGain = 0; 179 state->lockFull = 0; 180 state->onset = 0; // assume no onset in start 181 182 return 0; 183 } 184 185 ------------------------------------------------------------------------------ 186 RESOURCES USED [optional] 187 188 When the code is written for a specific target processor the 189 the resources used should be documented below. 190 191 HEAP MEMORY USED: x bytes 192 193 STACK MEMORY USED: x bytes 194 195 CLOCK CYCLES: (cycle count equation for this function) + (variable 196 used to represent cycle count for each subroutine 197 called) 198 where: (cycle count variable) = cycle count for [subroutine 199 name] 200 201 ------------------------------------------------------------------------------ 202 CAUTION [optional] 203 [State any special notes, constraints or cautions for users of this function] 204 205 ------------------------------------------------------------------------------ 206 */ 207 208 Word16 ph_disp_reset(ph_dispState *state) 209 { 210 register Word16 i; 211 212 if (state == (ph_dispState *) NULL) 213 { 214 /* fprint(stderr, "ph_disp_reset: invalid parameter\n"); */ 215 return(-1); 216 } 217 for (i = 0; i < PHDGAINMEMSIZE; i++) 218 { 219 state->gainMem[i] = 0; 220 } 221 state->prevState = 0; 222 state->prevCbGain = 0; 223 state->lockFull = 0; 224 state->onset = 0; /* assume no onset in start */ 225 226 return(0); 227 } 228 229 /****************************************************************************/ 230 231 /* 232 ------------------------------------------------------------------------------ 233 FUNCTION NAME: ph_disp_lock 234 ------------------------------------------------------------------------------ 235 INPUT AND OUTPUT DEFINITIONS 236 237 Inputs: 238 state = pointer to a structure of type ph_dispState 239 240 Outputs: 241 lockFull field of the structure pointed to by state is set to 1 242 243 Returns: 244 None 245 246 Global Variables Used: 247 None 248 249 Local Variables Needed: 250 None 251 252 ------------------------------------------------------------------------------ 253 FUNCTION DESCRIPTION 254 255 This function sets the lockFull flag to indicate a lock condition. 256 257 ------------------------------------------------------------------------------ 258 REQUIREMENTS 259 260 None 261 262 ------------------------------------------------------------------------------ 263 REFERENCES 264 265 ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 266 267 ------------------------------------------------------------------------------ 268 PSEUDO-CODE 269 270 void ph_disp_lock (ph_dispState *state) 271 { 272 state->lockFull = 1; 273 return; 274 } 275 276 ------------------------------------------------------------------------------ 277 RESOURCES USED [optional] 278 279 When the code is written for a specific target processor the 280 the resources used should be documented below. 281 282 HEAP MEMORY USED: x bytes 283 284 STACK MEMORY USED: x bytes 285 286 CLOCK CYCLES: (cycle count equation for this function) + (variable 287 used to represent cycle count for each subroutine 288 called) 289 where: (cycle count variable) = cycle count for [subroutine 290 name] 291 292 ------------------------------------------------------------------------------ 293 CAUTION [optional] 294 [State any special notes, constraints or cautions for users of this function] 295 296 ------------------------------------------------------------------------------ 297 */ 298 299 void ph_disp_lock(ph_dispState *state) 300 { 301 state->lockFull = 1; 302 303 return; 304 } 305 306 /****************************************************************************/ 307 308 /* 309 ------------------------------------------------------------------------------ 310 FUNCTION NAME: ph_disp_release 311 ------------------------------------------------------------------------------ 312 INPUT AND OUTPUT DEFINITIONS 313 314 Inputs: 315 state = pointer to a structure of type ph_dispState 316 317 Outputs: 318 lockFull field of the structure pointed to by state is set to 0 319 320 Returns: 321 None 322 323 Global Variables Used: 324 None 325 326 Local Variables Needed: 327 None 328 329 ------------------------------------------------------------------------------ 330 FUNCTION DESCRIPTION 331 332 This function clears the lockFull flag to indicate an unlocked state. 333 334 ------------------------------------------------------------------------------ 335 REQUIREMENTS 336 337 None 338 339 ------------------------------------------------------------------------------ 340 REFERENCES 341 342 ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 343 344 ------------------------------------------------------------------------------ 345 PSEUDO-CODE 346 347 void ph_disp_release (ph_dispState *state) 348 { 349 state->lockFull = 0; 350 return; 351 } 352 353 ------------------------------------------------------------------------------ 354 RESOURCES USED [optional] 355 356 When the code is written for a specific target processor the 357 the resources used should be documented below. 358 359 HEAP MEMORY USED: x bytes 360 361 STACK MEMORY USED: x bytes 362 363 CLOCK CYCLES: (cycle count equation for this function) + (variable 364 used to represent cycle count for each subroutine 365 called) 366 where: (cycle count variable) = cycle count for [subroutine 367 name] 368 369 ------------------------------------------------------------------------------ 370 CAUTION [optional] 371 [State any special notes, constraints or cautions for users of this function] 372 373 ------------------------------------------------------------------------------ 374 */ 375 376 void ph_disp_release(ph_dispState *state) 377 { 378 state->lockFull = 0; 379 380 return; 381 } 382 383 /****************************************************************************/ 384 385 /* 386 ------------------------------------------------------------------------------ 387 FUNCTION NAME: ph_disp 388 ------------------------------------------------------------------------------ 389 INPUT AND OUTPUT DEFINITIONS 390 391 Inputs: 392 state = pointer to a structure of type ph_dispState 393 mode = codec mode (enum Mode) 394 x = LTP excitation signal buffer (Word16) 395 cbGain = codebook gain (Word16) 396 ltpGain = LTP gain (Word16) 397 inno = innovation buffer (Word16) 398 pitch_fac = pitch factor used to scale the LTP excitation (Word16) 399 tmp_shift = shift factor applied to sum of scaled LTP excitation and 400 innovation before rounding (Word16) 401 pOverflow = pointer to overflow indicator (Flag) 402 403 Outputs: 404 structure pointed to by state contains the updated gainMem array, 405 prevState, prevCbGain, and onset fields 406 x buffer contains the new excitation signal 407 inno buffer contains the new innovation signal 408 pOverflow -> 1 if there is overflow 409 410 Returns: 411 None 412 413 Global Variables Used: 414 None 415 416 Local Variables Needed: 417 None 418 419 ------------------------------------------------------------------------------ 420 FUNCTION DESCRIPTION 421 422 This function performs adaptive phase dispersion, i.e., forming of total 423 excitation for the synthesis part of the decoder. 424 425 ------------------------------------------------------------------------------ 426 REQUIREMENTS 427 428 None 429 430 ------------------------------------------------------------------------------ 431 REFERENCES 432 433 ph_disp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 434 435 ------------------------------------------------------------------------------ 436 PSEUDO-CODE 437 438 void ph_disp ( 439 ph_dispState *state, // i/o : State struct 440 enum Mode mode, // i : codec mode 441 Word16 x[], // i/o Q0 : in: LTP excitation signal 442 // out: total excitation signal 443 Word16 cbGain, // i Q1 : Codebook gain 444 Word16 ltpGain, // i Q14 : LTP gain 445 Word16 inno[], // i/o Q13 : Innovation vector (Q12 for 12.2) 446 Word16 pitch_fac, // i Q14 : pitch factor used to scale the 447 LTP excitation (Q13 for 12.2) 448 Word16 tmp_shift // i Q0 : shift factor applied to sum of 449 scaled LTP ex & innov. before 450 rounding 451 ) 452 { 453 Word16 i, i1; 454 Word16 tmp1; 455 Word32 L_temp; 456 Word16 impNr; // indicator for amount of disp./filter used 457 458 Word16 inno_sav[L_SUBFR]; 459 Word16 ps_poss[L_SUBFR]; 460 Word16 j, nze, nPulse, ppos; 461 const Word16 *ph_imp; // Pointer to phase dispersion filter 462 463 // Update LTP gain memory 464 for (i = PHDGAINMEMSIZE-1; i > 0; i--) 465 { 466 state->gainMem[i] = state->gainMem[i-1]; 467 } 468 state->gainMem[0] = ltpGain; 469 470 // basic adaption of phase dispersion 471 if (sub(ltpGain, PHDTHR2LTP) < 0) { // if (ltpGain < 0.9) 472 if (sub(ltpGain, PHDTHR1LTP) > 0) 473 { // if (ltpGain > 0.6 474 impNr = 1; // medium dispersion 475 } 476 else 477 { 478 impNr = 0; // maximum dispersion 479 } 480 } 481 else 482 { 483 impNr = 2; // no dispersion 484 } 485 486 // onset indicator 487 // onset = (cbGain > onFact * cbGainMem[0]) 488 tmp1 = pv_round(L_shl(L_mult(state->prevCbGain, ONFACTPLUS1), 2)); 489 if (sub(cbGain, tmp1) > 0) 490 { 491 state->onset = ONLENGTH; 492 } 493 else 494 { 495 if (state->onset > 0) 496 { 497 state->onset = sub (state->onset, 1); 498 } 499 } 500 501 // if not onset, check ltpGain buffer and use max phase dispersion if 502 half or more of the ltpGain-parameters say so 503 if (state->onset == 0) 504 { 505 // Check LTP gain memory and set filter accordingly 506 i1 = 0; 507 for (i = 0; i < PHDGAINMEMSIZE; i++) 508 { 509 if (sub(state->gainMem[i], PHDTHR1LTP) < 0) 510 { 511 i1 = add (i1, 1); 512 } 513 } 514 if (sub(i1, 2) > 0) 515 { 516 impNr = 0; 517 } 518 519 } 520 // Restrict decrease in phase dispersion to one step if not onset 521 if ((sub(impNr, add(state->prevState, 1)) > 0) && (state->onset == 0)) 522 { 523 impNr = sub (impNr, 1); 524 } 525 // if onset, use one step less phase dispersion 526 if((sub(impNr, 2) < 0) && (state->onset > 0)) 527 { 528 impNr = add (impNr, 1); 529 } 530 531 // disable for very low levels 532 if(sub(cbGain, 10) < 0) 533 { 534 impNr = 2; 535 } 536 537 if(sub(state->lockFull, 1) == 0) 538 { 539 impNr = 0; 540 } 541 542 // update static memory 543 state->prevState = impNr; 544 state->prevCbGain = cbGain; 545 546 // do phase dispersion for all modes but 12.2 and 7.4; 547 // don't modify the innovation if impNr >=2 (= no phase disp) 548 if (sub(mode, MR122) != 0 && 549 sub(mode, MR102) != 0 && 550 sub(mode, MR74) != 0 && 551 sub(impNr, 2) < 0) 552 { 553 // track pulse positions, save innovation, 554 and initialize new innovation 555 nze = 0; 556 for (i = 0; i < L_SUBFR; i++) 557 { 558 if (inno[i] != 0) 559 { 560 ps_poss[nze] = i; 561 nze = add (nze, 1); 562 } 563 inno_sav[i] = inno[i]; 564 inno[i] = 0; 565 } 566 // Choose filter corresponding to codec mode and dispersion criterium 567 if (sub (mode, MR795) == 0) 568 { 569 if (impNr == 0) 570 { 571 ph_imp = ph_imp_low_MR795; 572 } 573 else 574 { 575 ph_imp = ph_imp_mid_MR795; 576 } 577 } 578 else 579 { 580 if (impNr == 0) 581 { 582 ph_imp = ph_imp_low; 583 } 584 else 585 { 586 ph_imp = ph_imp_mid; 587 } 588 } 589 590 // Do phase dispersion of innovation 591 for (nPulse = 0; nPulse < nze; nPulse++) 592 { 593 ppos = ps_poss[nPulse]; 594 595 // circular convolution with impulse response 596 j = 0; 597 for (i = ppos; i < L_SUBFR; i++) 598 { 599 // inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] 600 tmp1 = mult(inno_sav[ppos], ph_imp[j++]); 601 inno[i] = add(inno[i], tmp1); 602 } 603 604 for (i = 0; i < ppos; i++) 605 { 606 // inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] 607 tmp1 = mult(inno_sav[ppos], ph_imp[j++]); 608 inno[i] = add(inno[i], tmp1); 609 } 610 } 611 } 612 613 // compute total excitation for synthesis part of decoder 614 // (using modified innovation if phase dispersion is active) 615 for (i = 0; i < L_SUBFR; i++) 616 { 617 // x[i] = gain_pit*x[i] + cbGain*code[i]; 618 L_temp = L_mult ( x[i], pitch_fac); 619 // 12.2: Q0 * Q13 620 // 7.4: Q0 * Q14 621 L_temp = L_mac (L_temp, inno[i], cbGain); 622 // 12.2: Q12 * Q1 623 // 7.4: Q13 * Q1 624 L_temp = L_shl (L_temp, tmp_shift); // Q16 625 x[i] = pv_round (L_temp); 626 } 627 628 return; 629 } 630 631 ------------------------------------------------------------------------------ 632 RESOURCES USED [optional] 633 634 When the code is written for a specific target processor the 635 the resources used should be documented below. 636 637 HEAP MEMORY USED: x bytes 638 639 STACK MEMORY USED: x bytes 640 641 CLOCK CYCLES: (cycle count equation for this function) + (variable 642 used to represent cycle count for each subroutine 643 called) 644 where: (cycle count variable) = cycle count for [subroutine 645 name] 646 647 ------------------------------------------------------------------------------ 648 CAUTION [optional] 649 [State any special notes, constraints or cautions for users of this function] 650 651 ------------------------------------------------------------------------------ 652 */ 653 654 void ph_disp( 655 ph_dispState *state, /* i/o : State struct */ 656 enum Mode mode, /* i : codec mode */ 657 Word16 x[], /* i/o Q0 : in: LTP excitation signal */ 658 /* out: total excitation signal */ 659 Word16 cbGain, /* i Q1 : Codebook gain */ 660 Word16 ltpGain, /* i Q14 : LTP gain */ 661 Word16 inno[], /* i/o Q13 : Innovation vector (Q12 for 12.2) */ 662 Word16 pitch_fac, /* i Q14 : pitch factor used to scale the 663 LTP excitation (Q13 for 12.2) */ 664 Word16 tmp_shift, /* i Q0 : shift factor applied to sum of 665 scaled LTP ex & innov. before 666 rounding */ 667 Flag *pOverflow /* i/o : oveflow indicator */ 668 ) 669 { 670 register Word16 i, i1; 671 register Word16 tmp1; 672 Word32 L_temp; 673 Word32 L_temp2; 674 Word16 impNr; /* indicator for amount of disp./filter used */ 675 676 Word16 inno_sav[L_SUBFR]; 677 Word16 ps_poss[L_SUBFR]; 678 register Word16 nze, nPulse; 679 Word16 ppos; 680 const Word16 *ph_imp; /* Pointer to phase dispersion filter */ 681 682 Word16 *p_inno; 683 Word16 *p_inno_sav; 684 Word16 *p_x; 685 const Word16 *p_ph_imp; 686 Word16 c_inno_sav; 687 688 /* Update LTP gain memory */ 689 /* Unrolled FOR loop below since PHDGAINMEMSIZE is assumed to stay */ 690 /* the same. */ 691 /* for (i = PHDGAINMEMSIZE-1; i > 0; i--) */ 692 /* { */ 693 /* state->gainMem[i] = state->gainMem[i-1]; */ 694 /* } */ 695 state->gainMem[4] = state->gainMem[3]; 696 state->gainMem[3] = state->gainMem[2]; 697 state->gainMem[2] = state->gainMem[1]; 698 state->gainMem[1] = state->gainMem[0]; 699 state->gainMem[0] = ltpGain; 700 701 /* basic adaption of phase dispersion */ 702 703 if (ltpGain < PHDTHR2LTP) /* if (ltpGain < 0.9) */ 704 { 705 if (ltpGain > PHDTHR1LTP) 706 { /* if (ltpGain > 0.6 */ 707 impNr = 1; /* medium dispersion */ 708 } 709 else 710 { 711 impNr = 0; /* maximum dispersion */ 712 } 713 } 714 else 715 { 716 impNr = 2; /* no dispersion */ 717 } 718 719 /* onset indicator */ 720 /* onset = (cbGain > onFact * cbGainMem[0]) */ 721 722 L_temp = ((Word32) state->prevCbGain * ONFACTPLUS1) << 1; 723 724 /* (L_temp << 2) calculation with saturation check */ 725 if (L_temp > (Word32) 0X1fffffffL) 726 { 727 *pOverflow = 1; 728 L_temp = MAX_32; 729 } 730 else if (L_temp < (Word32) 0xe0000000L) 731 { 732 *pOverflow = 1; 733 L_temp = MIN_32; 734 } 735 else 736 { 737 L_temp <<= 2; 738 } 739 740 tmp1 = pv_round(L_temp, pOverflow); 741 742 if (cbGain > tmp1) 743 { 744 state->onset = ONLENGTH; 745 } 746 else 747 { 748 749 if (state->onset > 0) 750 { 751 state->onset -= 1; 752 } 753 } 754 755 /* if not onset, check ltpGain buffer and use max phase dispersion if 756 half or more of the ltpGain-parameters say so */ 757 if (state->onset == 0) 758 { 759 /* Check LTP gain memory and set filter accordingly */ 760 i1 = 0; 761 for (i = 0; i < PHDGAINMEMSIZE; i++) 762 { 763 if (state->gainMem[i] < PHDTHR1LTP) 764 { 765 i1 += 1; 766 } 767 } 768 769 if (i1 > 2) 770 { 771 impNr = 0; 772 } 773 } 774 /* Restrict decrease in phase dispersion to one step if not onset */ 775 if ((impNr > ((state->prevState) + 1)) && (state->onset == 0)) 776 { 777 impNr -= 1; 778 } 779 780 /* if onset, use one step less phase dispersion */ 781 if ((impNr < 2) && (state->onset > 0)) 782 { 783 impNr += 1; 784 } 785 786 /* disable for very low levels */ 787 if (cbGain < 10) 788 { 789 impNr = 2; 790 } 791 792 if (state->lockFull == 1) 793 { 794 impNr = 0; 795 } 796 797 /* update static memory */ 798 state->prevState = impNr; 799 state->prevCbGain = cbGain; 800 801 /* do phase dispersion for all modes but 12.2 and 7.4; 802 don't modify the innovation if impNr >=2 (= no phase disp) */ 803 if ((mode != MR122) && (mode != MR102) && (mode != MR74) && (impNr < 2)) 804 { 805 /* track pulse positions, save innovation, 806 and initialize new innovation */ 807 nze = 0; 808 p_inno = &inno[0]; 809 p_inno_sav = &inno_sav[0]; 810 811 for (i = 0; i < L_SUBFR; i++) 812 { 813 if (*(p_inno) != 0) 814 { 815 ps_poss[nze] = i; 816 nze += 1; 817 } 818 *(p_inno_sav++) = *(p_inno); 819 *(p_inno++) = 0; 820 } 821 822 /* Choose filter corresponding to codec mode and dispersion criterium */ 823 if (mode == MR795) 824 { 825 if (impNr == 0) 826 { 827 ph_imp = ph_imp_low_MR795; 828 } 829 else 830 { 831 ph_imp = ph_imp_mid_MR795; 832 } 833 } 834 else 835 { 836 if (impNr == 0) 837 { 838 ph_imp = ph_imp_low; 839 } 840 else 841 { 842 ph_imp = ph_imp_mid; 843 } 844 } 845 846 /* Do phase dispersion of innovation */ 847 for (nPulse = 0; nPulse < nze; nPulse++) 848 { 849 ppos = ps_poss[nPulse]; 850 851 /* circular convolution with impulse response */ 852 c_inno_sav = inno_sav[ppos]; 853 p_inno = &inno[ppos]; 854 p_ph_imp = ph_imp; 855 856 for (i = ppos; i < L_SUBFR; i++) 857 { 858 /* inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] */ 859 L_temp = ((Word32) c_inno_sav * *(p_ph_imp++)) >> 15; 860 tmp1 = (Word16) L_temp; 861 *(p_inno) = add(*(p_inno), tmp1, pOverflow); 862 p_inno += 1; 863 } 864 865 p_inno = &inno[0]; 866 867 for (i = 0; i < ppos; i++) 868 { 869 /* inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] */ 870 L_temp = ((Word32) c_inno_sav * *(p_ph_imp++)) >> 15; 871 tmp1 = (Word16) L_temp; 872 *(p_inno) = add(*(p_inno), tmp1, pOverflow); 873 p_inno += 1; 874 } 875 } 876 } 877 878 /* compute total excitation for synthesis part of decoder 879 (using modified innovation if phase dispersion is active) */ 880 p_inno = &inno[0]; 881 p_x = &x[0]; 882 883 for (i = 0; i < L_SUBFR; i++) 884 { 885 /* x[i] = gain_pit*x[i] + cbGain*code[i]; */ 886 L_temp = L_mult(x[i], pitch_fac, pOverflow); 887 /* 12.2: Q0 * Q13 */ 888 /* 7.4: Q0 * Q14 */ 889 L_temp2 = ((Word32) * (p_inno++) * cbGain) << 1; 890 L_temp = L_add(L_temp, L_temp2, pOverflow); 891 /* 12.2: Q12 * Q1 */ 892 /* 7.4: Q13 * Q1 */ 893 L_temp = L_shl(L_temp, tmp_shift, pOverflow); /* Q16 */ 894 *(p_x++) = pv_round(L_temp, pOverflow); 895 } 896 897 return; 898 } 899