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 35 Pathname: ./audio/gsm-amr/c/src/ec_gain.c 36 Funtions: 37 38 Date: 01/28/2002 39 40 ------------------------------------------------------------------------------ 41 REVISION HISTORY 42 43 Description: Removed the functions ec_gain_code_init, ec_gain_pitch_init, 44 ech_gain_code_exit, and ec_gain_pitch_exit. 45 46 The ec_gains related structures are no longer dynamically allocated. 47 48 Description: Updated include files and input/output sections. 49 50 Description: Replaced OSCL mem type functions and eliminated include 51 files that now are chosen by OSCL definitions 52 53 Description: Replaced "int" and/or "char" with OSCL defined types. 54 55 Description: Added #ifdef __cplusplus around extern'ed table. 56 57 Description: 58 59 ------------------------------------------------------------------------------ 60 MODULE DESCRIPTION 61 62 These modules execute the code book gains for error concealment. This module 63 contains the init, reset, exit, and "main" functions in this process. 64 65 ------------------------------------------------------------------------------ 66 */ 67 68 69 /*---------------------------------------------------------------------------- 70 ; INCLUDES 71 ----------------------------------------------------------------------------*/ 72 #include "ec_gains.h" 73 #include "typedef.h" 74 #include "cnst.h" 75 #include "gmed_n.h" 76 #include "gc_pred.h" 77 #include "basic_op.h" 78 79 80 /*--------------------------------------------------------------------------*/ 81 #ifdef __cplusplus 82 extern "C" 83 { 84 #endif 85 86 /*---------------------------------------------------------------------------- 87 ; MACROS 88 ; Define module specific macros here 89 ----------------------------------------------------------------------------*/ 90 91 92 /*---------------------------------------------------------------------------- 93 ; DEFINES 94 ; Include all pre-processor statements here. Include conditional 95 ; compile variables also. 96 ----------------------------------------------------------------------------*/ 97 98 99 /*---------------------------------------------------------------------------- 100 ; LOCAL FUNCTION DEFINITIONS 101 ; Function Prototype declaration 102 ----------------------------------------------------------------------------*/ 103 104 105 /*---------------------------------------------------------------------------- 106 ; LOCAL VARIABLE DEFINITIONS 107 ; Variable declaration - defined here and used outside this module 108 ----------------------------------------------------------------------------*/ 109 110 extern const Word16 qua_gain_pitch[]; 111 extern const Word16 qua_gain_code[]; 112 113 114 /*--------------------------------------------------------------------------*/ 115 #ifdef __cplusplus 116 } 117 #endif 118 119 /* 120 ------------------------------------------------------------------------------ 121 FUNCTION NAME: ec_gain_code_reset 122 ------------------------------------------------------------------------------ 123 INPUT AND OUTPUT DEFINITIONS 124 125 Inputs: 126 state = pointer to a pointer to a structure containing code state data of 127 stucture type ec_gain_codeState 128 129 Outputs: 130 None. 131 132 Returns: 133 None 134 135 Global Variables Used: 136 None. 137 138 Local Variables Needed: 139 None. 140 141 ------------------------------------------------------------------------------ 142 FUNCTION DESCRIPTION 143 144 This function resets the state data for the ec_gain module. 145 146 ------------------------------------------------------------------------------ 147 REQUIREMENTS 148 149 None 150 151 ------------------------------------------------------------------------------ 152 REFERENCES 153 154 None 155 156 ------------------------------------------------------------------------------ 157 PSEUDO-CODE 158 159 int ec_gain_code_reset (ec_gain_codeState *state) 160 { 161 Word16 i; 162 163 if (state == (ec_gain_codeState *) NULL){ 164 // fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); 165 return -1; 166 } 167 168 for ( i = 0; i < 5; i++) 169 state->gbuf[i] = 1; 170 state->past_gain_code = 0; 171 state->prev_gc = 1; 172 173 return 0; 174 } 175 176 ------------------------------------------------------------------------------ 177 RESOURCES USED [optional] 178 179 When the code is written for a specific target processor the 180 the resources used should be documented below. 181 182 HEAP MEMORY USED: x bytes 183 184 STACK MEMORY USED: x bytes 185 186 CLOCK CYCLES: (cycle count equation for this function) + (variable 187 used to represent cycle count for each subroutine 188 called) 189 where: (cycle count variable) = cycle count for [subroutine 190 name] 191 192 ------------------------------------------------------------------------------ 193 CAUTION [optional] 194 [State any special notes, constraints or cautions for users of this function] 195 196 ------------------------------------------------------------------------------ 197 */ 198 199 Word16 ec_gain_code_reset(ec_gain_codeState *state) 200 { 201 Word16 i; 202 203 if (state == (ec_gain_codeState *) NULL) 204 { 205 /* fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); */ 206 return -1; 207 } 208 209 for (i = 0; i < 5; i++) 210 state->gbuf[i] = 1; 211 state->past_gain_code = 0; 212 state->prev_gc = 1; 213 214 return 0; 215 } 216 217 /* 218 ------------------------------------------------------------------------------ 219 FUNCTION NAME: ec_gain_code 220 ------------------------------------------------------------------------------ 221 INPUT AND OUTPUT DEFINITIONS 222 223 Inputs: 224 st = pointer to a pointer to a structure containing code state data of 225 stucture type ec_gain_codeState 226 pred_state = pointer to MA predictor state of type gc_predState 227 state = state of the state machine of type Word16 228 gain_code = pointer to decoded innovation gain of type Word16 229 pOverflow = pointer to overflow indicator of type Flag 230 231 Outputs: 232 st = pointer to a pointer to a structure containing code state data of 233 stucture type ec_gain_codeState 234 pred_state = pointer to MA predictor state of type gc_predState 235 pOverflow = 1 if there is an overflow else it is zero. 236 237 Returns: 238 None. 239 240 Global Variables Used: 241 None. 242 243 Local Variables Needed: 244 None. 245 246 ------------------------------------------------------------------------------ 247 FUNCTION DESCRIPTION 248 249 This function does error concealment using the codebook. Call this function 250 only in BFI (instead of normal gain decoding function). 251 252 ------------------------------------------------------------------------------ 253 REQUIREMENTS 254 255 None. 256 257 ------------------------------------------------------------------------------ 258 REFERENCES 259 260 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 261 262 ------------------------------------------------------------------------------ 263 PSEUDO-CODE 264 265 static const Word16 cdown[7] = 266 { 267 32767, 32112, 32112, 32112, 268 32112, 32112, 22937 269 }; 270 271 Word16 tmp; 272 Word16 qua_ener_MR122; 273 Word16 qua_ener; 274 275 // calculate median of last five gain values 276 tmp = gmed_n (st->gbuf,5); 277 278 // new gain = minimum(median, past_gain) * cdown[state] 279 if (sub (tmp, st->past_gain_code) > 0) 280 { 281 tmp = st->past_gain_code; 282 } 283 tmp = mult (tmp, cdown[state]); 284 *gain_code = tmp; 285 286 // update table of past quantized energies with average of 287 // current values 288 289 gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener); 290 gc_pred_update(pred_state, qua_ener_MR122, qua_ener); 291 } 292 293 ------------------------------------------------------------------------------ 294 RESOURCES USED [optional] 295 296 When the code is written for a specific target processor the 297 the resources used should be documented below. 298 299 HEAP MEMORY USED: x bytes 300 301 STACK MEMORY USED: x bytes 302 303 CLOCK CYCLES: (cycle count equation for this function) + (variable 304 used to represent cycle count for each subroutine 305 called) 306 where: (cycle count variable) = cycle count for [subroutine 307 name] 308 309 ------------------------------------------------------------------------------ 310 CAUTION [optional] 311 [State any special notes, constraints or cautions for users of this function] 312 313 ------------------------------------------------------------------------------ 314 */ 315 void ec_gain_code( 316 ec_gain_codeState *st, /* i/o : State struct */ 317 gc_predState *pred_state, /* i/o : MA predictor state */ 318 Word16 state, /* i : state of the state machine */ 319 Word16 *gain_code, /* o : decoded innovation gain */ 320 Flag *pOverflow 321 ) 322 { 323 static const Word16 cdown[7] = 324 { 325 32767, 32112, 32112, 32112, 326 32112, 32112, 22937 327 }; 328 329 Word16 tmp; 330 Word16 qua_ener_MR122; 331 Word16 qua_ener; 332 333 /* calculate median of last five gain values */ 334 tmp = gmed_n(st->gbuf, 5); 335 336 /* new gain = minimum(median, past_gain) * cdown[state] */ 337 if (sub(tmp, st->past_gain_code, pOverflow) > 0) 338 { 339 tmp = st->past_gain_code; 340 } 341 tmp = mult(tmp, cdown[state], pOverflow); 342 *gain_code = tmp; 343 344 /* update table of past quantized energies with average of 345 * current values 346 */ 347 gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener, pOverflow); 348 gc_pred_update(pred_state, qua_ener_MR122, qua_ener); 349 } 350 351 /****************************************************************************/ 352 353 /* 354 ------------------------------------------------------------------------------ 355 FUNCTION NAME: ec_gain_code_update 356 ------------------------------------------------------------------------------ 357 INPUT AND OUTPUT DEFINITIONS 358 359 Inputs: 360 st = pointer to a pointer to a structure containing code state data of 361 stucture type ec_gain_codeState 362 bfi = a flag that indicates if the frame is bad of type Word16 363 prev_bf = a flag that indicates if the previous frame was bad of type Word16 364 gain_code = pointer to decoded innovation gain of type Word16 365 pOverflow = pointer to overflow indicator of type Flag 366 367 Outputs: 368 st = pointer to a pointer to a structure containing code state data of 369 stucture type ec_gain_codeState 370 gain_code = pointer to decoded innovation gain of type Word16 371 pOverflow = 1 if there is an overflow else it is zero. 372 373 Returns: 374 None. 375 376 Global Variables Used: 377 None. 378 379 Local Variables Needed: 380 None. 381 382 ------------------------------------------------------------------------------ 383 FUNCTION DESCRIPTION 384 385 Purpose : update the codebook gain concealment state; 386 limit gain_code if the previous frame was bad 387 Call this function always after decoding (or concealing) 388 the gain 389 390 ------------------------------------------------------------------------------ 391 REQUIREMENTS 392 393 None. 394 395 ------------------------------------------------------------------------------ 396 REFERENCES 397 398 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 399 400 ------------------------------------------------------------------------------ 401 PSEUDO-CODE 402 403 Word16 i; 404 405 // limit gain_code by previous good gain if previous frame was bad 406 if (bfi == 0) 407 { 408 if (prev_bf != 0) 409 { 410 if (sub (*gain_code, st->prev_gc) > 0) 411 { 412 *gain_code = st->prev_gc; 413 } 414 } 415 st->prev_gc = *gain_code; 416 } 417 418 // update EC states: previous gain, gain buffer 419 st->past_gain_code = *gain_code; 420 421 for (i = 1; i < 5; i++) 422 { 423 st->gbuf[i - 1] = st->gbuf[i]; 424 } 425 st->gbuf[4] = *gain_code; 426 427 return; 428 } 429 430 ------------------------------------------------------------------------------ 431 RESOURCES USED [optional] 432 433 When the code is written for a specific target processor the 434 the resources used should be documented below. 435 436 HEAP MEMORY USED: x bytes 437 438 STACK MEMORY USED: x bytes 439 440 CLOCK CYCLES: (cycle count equation for this function) + (variable 441 used to represent cycle count for each subroutine 442 called) 443 where: (cycle count variable) = cycle count for [subroutine 444 name] 445 446 ------------------------------------------------------------------------------ 447 CAUTION [optional] 448 [State any special notes, constraints or cautions for users of this function] 449 450 ------------------------------------------------------------------------------ 451 */ 452 void ec_gain_code_update( 453 ec_gain_codeState *st, /* i/o : State struct */ 454 Word16 bfi, /* i : flag: frame is bad */ 455 Word16 prev_bf, /* i : flag: previous frame was bad */ 456 Word16 *gain_code, /* i/o : decoded innovation gain */ 457 Flag *pOverflow 458 ) 459 { 460 Word16 i; 461 462 /* limit gain_code by previous good gain if previous frame was bad */ 463 if (bfi == 0) 464 { 465 if (prev_bf != 0) 466 { 467 if (sub(*gain_code, st->prev_gc, pOverflow) > 0) 468 { 469 *gain_code = st->prev_gc; 470 } 471 } 472 st->prev_gc = *gain_code; 473 } 474 475 /* update EC states: previous gain, gain buffer */ 476 st->past_gain_code = *gain_code; 477 478 for (i = 1; i < 5; i++) 479 { 480 st->gbuf[i - 1] = st->gbuf[i]; 481 } 482 st->gbuf[4] = *gain_code; 483 484 return; 485 } 486 487 /****************************************************************************/ 488 489 /* 490 ------------------------------------------------------------------------------ 491 FUNCTION NAME: ec_gain_pitch 492 ------------------------------------------------------------------------------ 493 INPUT AND OUTPUT DEFINITIONS 494 495 Inputs: 496 st = pointer to a pointer to a structure containing code 497 state data of stucture type ec_gain_pitchState 498 state = state of the state machine of type Word16 499 pOverflow = pointer to overflow indicator of type Flag 500 501 Outputs: 502 state = pointer to a pointer to a structure containing code 503 state data of stucture type ec_gain_pitchState 504 gain_pitch = pointer to pitch gain (Q14) of type Word16 505 pOverflow = 1 if there is an overflow else it is zero. 506 507 Returns: 508 None. 509 510 Global Variables Used: 511 None. 512 513 Local Variables Needed: 514 None. 515 516 ------------------------------------------------------------------------------ 517 FUNCTION DESCRIPTION 518 519 This function conceals the error using code gain implementation in this 520 function. 521 522 ------------------------------------------------------------------------------ 523 REQUIREMENTS 524 525 None. 526 527 ------------------------------------------------------------------------------ 528 REFERENCES 529 530 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 531 532 ------------------------------------------------------------------------------ 533 PSEUDO-CODE 534 535 536 static const Word16 pdown[7] = 537 { 538 32767, 32112, 32112, 26214, 539 9830, 6553, 6553 540 }; 541 542 Word16 tmp; 543 544 // calculate median of last five gains 545 tmp = gmed_n (st->pbuf, 5); 546 547 // new gain = minimum(median, past_gain) * pdown[state] 548 if (sub (tmp, st->past_gain_pit) > 0) 549 { 550 tmp = st->past_gain_pit; 551 } 552 *gain_pitch = mult (tmp, pdown[state]); 553 554 555 ------------------------------------------------------------------------------ 556 RESOURCES USED [optional] 557 558 When the code is written for a specific target processor the 559 the resources used should be documented below. 560 561 HEAP MEMORY USED: x bytes 562 563 STACK MEMORY USED: x bytes 564 565 CLOCK CYCLES: (cycle count equation for this function) + (variable 566 used to represent cycle count for each subroutine 567 called) 568 where: (cycle count variable) = cycle count for [subroutine 569 name] 570 571 ------------------------------------------------------------------------------ 572 CAUTION [optional] 573 [State any special notes, constraints or cautions for users of this function] 574 575 ------------------------------------------------------------------------------ 576 */ 577 void ec_gain_pitch( 578 ec_gain_pitchState *st, /* i/o : state variables */ 579 Word16 state, /* i : state of the state machine */ 580 Word16 *gain_pitch, /* o : pitch gain (Q14) */ 581 Flag *pOverflow 582 ) 583 { 584 static const Word16 pdown[7] = 585 { 586 32767, 32112, 32112, 26214, 587 9830, 6553, 6553 588 }; 589 590 Word16 tmp; 591 592 /* calculate median of last five gains */ 593 tmp = gmed_n(st->pbuf, 5); 594 595 /* new gain = minimum(median, past_gain) * pdown[state] */ 596 if (sub(tmp, st->past_gain_pit, pOverflow) > 0) 597 { 598 tmp = st->past_gain_pit; 599 } 600 *gain_pitch = mult(tmp, pdown[state], pOverflow); 601 } 602 603 /****************************************************************************/ 604 /* 605 ------------------------------------------------------------------------------ 606 FUNCTION NAME: ec_gain_pitch_reset 607 ------------------------------------------------------------------------------ 608 INPUT AND OUTPUT DEFINITIONS 609 610 Inputs: 611 state = state of the state machine of type Word16 612 pOverflow = pointer to overflow indicator of type Flag 613 614 Outputs: 615 state = pointer to a pointer to a structure containing code 616 state data of stucture type ec_gain_pitchState 617 pOverflow = 1 if there is an overflow else it is zero. 618 619 Returns: 620 None. 621 622 Global Variables Used: 623 None. 624 625 Local Variables Needed: 626 None. 627 628 ------------------------------------------------------------------------------ 629 FUNCTION DESCRIPTION 630 631 Function: ec_gain_pitch_reset 632 Purpose: Resets state memory 633 634 ------------------------------------------------------------------------------ 635 REQUIREMENTS 636 637 None. 638 639 ------------------------------------------------------------------------------ 640 REFERENCES 641 642 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 643 644 ------------------------------------------------------------------------------ 645 PSEUDO-CODE 646 647 int ec_gain_pitch_reset (ec_gain_pitchState *state) 648 { 649 Word16 i; 650 651 if (state == (ec_gain_pitchState *) NULL){ 652 // fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); 653 return -1; 654 } 655 656 for(i = 0; i < 5; i++) 657 state->pbuf[i] = 1640; 658 state->past_gain_pit = 0; 659 state->prev_gp = 16384; 660 661 return 0; 662 } 663 664 ------------------------------------------------------------------------------ 665 RESOURCES USED [optional] 666 667 When the code is written for a specific target processor the 668 the resources used should be documented below. 669 670 HEAP MEMORY USED: x bytes 671 672 STACK MEMORY USED: x bytes 673 674 CLOCK CYCLES: (cycle count equation for this function) + (variable 675 used to represent cycle count for each subroutine 676 called) 677 where: (cycle count variable) = cycle count for [subroutine 678 name] 679 680 ------------------------------------------------------------------------------ 681 CAUTION [optional] 682 [State any special notes, constraints or cautions for users of this function] 683 684 ------------------------------------------------------------------------------ 685 */ 686 Word16 ec_gain_pitch_reset(ec_gain_pitchState *state) 687 { 688 Word16 i; 689 690 if (state == (ec_gain_pitchState *) NULL) 691 { 692 /* fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); */ 693 return -1; 694 } 695 696 for (i = 0; i < 5; i++) 697 state->pbuf[i] = 1640; 698 state->past_gain_pit = 0; 699 state->prev_gp = 16384; 700 701 return 0; 702 } 703 704 /****************************************************************************/ 705 706 707 /* 708 ------------------------------------------------------------------------------ 709 FUNCTION NAME: ec_gain_pitch_update 710 ------------------------------------------------------------------------------ 711 INPUT AND OUTPUT DEFINITIONS 712 713 Inputs: 714 st = pointer to a pointer to a structure containing code 715 state data of stucture type ec_gain_pitchState 716 bfi = flag indicating the frame is bad of type Word16 717 prev_bf = flag indicating the previous frame was bad of type Word16 718 gain_pitch = pointer to pitch gain of type Word16 719 pOverflow = pointer to overflow indicator of type Flag 720 721 Outputs: 722 state = pointer to a pointer to a structure containing code 723 state data of stucture type ec_gain_pitchState 724 gain_pitch = pointer to pitch gain of type Word16 725 pOverflow = 1 if there is an overflow else it is zero. 726 727 Returns: 728 None. 729 730 Global Variables Used: 731 None. 732 733 Local Variables Needed: 734 None. 735 736 ------------------------------------------------------------------------------ 737 FUNCTION DESCRIPTION 738 739 Purpose : update the pitch gain concealment state; 740 limit gain_pitch if the previous frame was bad 741 Call this function always after decoding (or concealing) 742 the gain 743 744 ------------------------------------------------------------------------------ 745 REQUIREMENTS 746 747 None. 748 749 ------------------------------------------------------------------------------ 750 REFERENCES 751 752 ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 753 754 ------------------------------------------------------------------------------ 755 PSEUDO-CODE 756 757 Word16 i; 758 759 if (bfi == 0) 760 { 761 if (prev_bf != 0) 762 { 763 if (sub (*gain_pitch, st->prev_gp) > 0) 764 { 765 *gain_pitch = st->prev_gp; 766 } 767 } 768 st->prev_gp = *gain_pitch; 769 } 770 771 st->past_gain_pit = *gain_pitch; 772 773 if (sub (st->past_gain_pit, 16384) > 0) // if (st->past_gain_pit > 1.0) 774 { 775 st->past_gain_pit = 16384; 776 } 777 for (i = 1; i < 5; i++) 778 { 779 st->pbuf[i - 1] = st->pbuf[i]; 780 } 781 st->pbuf[4] = st->past_gain_pit; 782 783 784 ------------------------------------------------------------------------------ 785 RESOURCES USED [optional] 786 787 When the code is written for a specific target processor the 788 the resources used should be documented below. 789 790 HEAP MEMORY USED: x bytes 791 792 STACK MEMORY USED: x bytes 793 794 CLOCK CYCLES: (cycle count equation for this function) + (variable 795 used to represent cycle count for each subroutine 796 called) 797 where: (cycle count variable) = cycle count for [subroutine 798 name] 799 800 ------------------------------------------------------------------------------ 801 CAUTION [optional] 802 [State any special notes, constraints or cautions for users of this function] 803 804 ------------------------------------------------------------------------------ 805 */ 806 void ec_gain_pitch_update( 807 ec_gain_pitchState *st, /* i/o : state variables */ 808 Word16 bfi, /* i : flag: frame is bad */ 809 Word16 prev_bf, /* i : flag: previous frame was bad */ 810 Word16 *gain_pitch, /* i/o : pitch gain */ 811 Flag *pOverflow 812 ) 813 { 814 Word16 i; 815 816 if (bfi == 0) 817 { 818 if (prev_bf != 0) 819 { 820 if (sub(*gain_pitch, st->prev_gp, pOverflow) > 0) 821 { 822 *gain_pitch = st->prev_gp; 823 } 824 } 825 st->prev_gp = *gain_pitch; 826 } 827 828 st->past_gain_pit = *gain_pitch; 829 830 if (sub(st->past_gain_pit, 16384, pOverflow) > 0) 831 /* if (st->past_gain_pit > 1.0) */ 832 { 833 st->past_gain_pit = 16384; 834 } 835 for (i = 1; i < 5; i++) 836 { 837 st->pbuf[i - 1] = st->pbuf[i]; 838 } 839 st->pbuf[4] = st->past_gain_pit; 840 } 841 842 843