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/gain_q.c 35 Functions: 36 37 Date: 02/05/2002 38 39 ------------------------------------------------------------------------------ 40 REVISION HISTORY 41 42 Description: Updated template used to PV coding template. 43 Changed to accept the pOverflow flag for EPOC compatibility. 44 45 Description: Removed everything associated with gc_pred_init 46 and gc_pred_exit. gc_pred_exit was simply removed -- gc_pred_init 47 was replaced with calls to gc_pred_reset. This is because the gc_pred 48 related structures are no longer dynamically allocated via malloc. 49 50 Description: For gainQuant() 51 1. Replaced gc_pred_copy() with memcpy. 52 2. Eliminated unused include file gc_pred.h. 53 54 Description: Replaced OSCL mem type functions and eliminated include 55 files that now are chosen by OSCL definitions 56 57 Description: Replaced "int" and/or "char" with OSCL defined types. 58 59 Description: 60 61 ------------------------------------------------------------------------------ 62 MODULE DESCRIPTION 63 64 Quantazation of gains 65 ------------------------------------------------------------------------------ 66 */ 67 68 /*---------------------------------------------------------------------------- 69 ; INCLUDES 70 ----------------------------------------------------------------------------*/ 71 #include <stdlib.h> 72 #include <string.h> 73 74 #include "gain_q.h" 75 #include "typedef.h" 76 #include "basic_op.h" 77 #include "qua_gain.h" 78 #include "cnst.h" 79 #include "mode.h" 80 #include "g_code.h" 81 #include "q_gain_c.h" 82 #include "calc_en.h" 83 #include "qgain795.h" 84 #include "qgain475.h" 85 #include "set_zero.h" 86 87 88 /*---------------------------------------------------------------------------- 89 ; MACROS 90 ; Define module specific macros here 91 ----------------------------------------------------------------------------*/ 92 93 /*---------------------------------------------------------------------------- 94 ; DEFINES 95 ; Include all pre-processor statements here. Include conditional 96 ; compile variables also. 97 ----------------------------------------------------------------------------*/ 98 #define NPRED 4 /* number of prediction taps */ 99 100 /*---------------------------------------------------------------------------- 101 ; LOCAL FUNCTION DEFINITIONS 102 ; Function Prototype declaration 103 ----------------------------------------------------------------------------*/ 104 105 /*---------------------------------------------------------------------------- 106 ; LOCAL VARIABLE DEFINITIONS 107 ; Variable declaration - defined here and used outside this module 108 ----------------------------------------------------------------------------*/ 109 110 /* 111 ------------------------------------------------------------------------------ 112 FUNCTION NAME: gainQuant_init 113 ------------------------------------------------------------------------------ 114 INPUT AND OUTPUT DEFINITIONS 115 116 Inputs: 117 st -- double pointer to gainQuantState 118 119 Outputs: 120 st -- double ponter to gainQuantState 121 122 Returns: 123 -1 if an error occurs during memory initialization 124 0 if OK 125 126 Global Variables Used: 127 None 128 129 Local Variables Needed: 130 None 131 132 ------------------------------------------------------------------------------ 133 FUNCTION DESCRIPTION 134 135 Allocates state memory and initializes state memory 136 137 ------------------------------------------------------------------------------ 138 REQUIREMENTS 139 140 None 141 142 ------------------------------------------------------------------------------ 143 REFERENCES 144 145 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 146 147 ------------------------------------------------------------------------------ 148 PSEUDO-CODE 149 150 151 ------------------------------------------------------------------------------ 152 RESOURCES USED [optional] 153 154 When the code is written for a specific target processor the 155 the resources used should be documented below. 156 157 HEAP MEMORY USED: x bytes 158 159 STACK MEMORY USED: x bytes 160 161 CLOCK CYCLES: (cycle count equation for this function) + (variable 162 used to represent cycle count for each subroutine 163 called) 164 where: (cycle count variable) = cycle count for [subroutine 165 name] 166 167 ------------------------------------------------------------------------------ 168 CAUTION [optional] 169 [State any special notes, constraints or cautions for users of this function] 170 171 ------------------------------------------------------------------------------ 172 */ 173 174 Word16 gainQuant_init(gainQuantState **state) 175 { 176 gainQuantState* s; 177 178 if (state == (gainQuantState **) NULL) 179 { 180 /* fprintf(stderr, "gainQuant_init: invalid parameter\n"); */ 181 return -1; 182 } 183 *state = NULL; 184 185 /* allocate memory */ 186 if ((s = (gainQuantState *) malloc(sizeof(gainQuantState))) == NULL) 187 { 188 /* fprintf(stderr, "gainQuant_init: can not malloc state structure\n"); */ 189 return -1; 190 } 191 192 s->gain_idx_ptr = NULL; 193 194 s->adaptSt = NULL; 195 196 /* Init sub states */ 197 if (gc_pred_reset(&s->gc_predSt) 198 || gc_pred_reset(&s->gc_predUnqSt) 199 || gain_adapt_init(&s->adaptSt)) 200 { 201 gainQuant_exit(&s); 202 return -1; 203 } 204 205 gainQuant_reset(s); 206 *state = s; 207 208 return 0; 209 } 210 211 /* 212 ------------------------------------------------------------------------------ 213 FUNCTION NAME: gainQuant_reset 214 ------------------------------------------------------------------------------ 215 INPUT AND OUTPUT DEFINITIONS 216 217 Inputs: 218 st -- double pointer to gainQuantState 219 220 Outputs: 221 st -- double ponter to gainQuantState 222 223 Returns: 224 -1 if an error occurs 225 0 if OK 226 227 Global Variables Used: 228 None 229 230 Local Variables Needed: 231 None 232 233 ------------------------------------------------------------------------------ 234 FUNCTION DESCRIPTION 235 236 Initializes state memory to zero 237 ------------------------------------------------------------------------------ 238 REQUIREMENTS 239 240 None 241 242 ------------------------------------------------------------------------------ 243 REFERENCES 244 245 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 246 247 ------------------------------------------------------------------------------ 248 PSEUDO-CODE 249 250 251 ------------------------------------------------------------------------------ 252 RESOURCES USED [optional] 253 254 When the code is written for a specific target processor the 255 the resources used should be documented below. 256 257 HEAP MEMORY USED: x bytes 258 259 STACK MEMORY USED: x bytes 260 261 CLOCK CYCLES: (cycle count equation for this function) + (variable 262 used to represent cycle count for each subroutine 263 called) 264 where: (cycle count variable) = cycle count for [subroutine 265 name] 266 267 ------------------------------------------------------------------------------ 268 CAUTION [optional] 269 [State any special notes, constraints or cautions for users of this function] 270 271 ------------------------------------------------------------------------------ 272 */ 273 274 Word16 gainQuant_reset(gainQuantState *state) 275 { 276 277 if (state == (gainQuantState *) NULL) 278 { 279 /* fprintf(stderr, "gainQuant_reset: invalid parameter\n"); */ 280 return -1; 281 } 282 283 state->sf0_exp_gcode0 = 0; 284 state->sf0_frac_gcode0 = 0; 285 state->sf0_exp_target_en = 0; 286 state->sf0_frac_target_en = 0; 287 288 Set_zero(state->sf0_exp_coeff, 5); 289 Set_zero(state->sf0_frac_coeff, 5); 290 state->gain_idx_ptr = NULL; 291 292 gc_pred_reset(&(state->gc_predSt)); 293 gc_pred_reset(&(state->gc_predUnqSt)); 294 gain_adapt_reset(state->adaptSt); 295 296 return 0; 297 } 298 299 /* 300 ------------------------------------------------------------------------------ 301 FUNCTION NAME: gainQuant_exit 302 ------------------------------------------------------------------------------ 303 INPUT AND OUTPUT DEFINITIONS 304 305 Inputs: 306 st -- double pointer to gainQuantState 307 308 Outputs: 309 None 310 311 Returns: 312 None 313 314 Global Variables Used: 315 None 316 317 Local Variables Needed: 318 None 319 320 ------------------------------------------------------------------------------ 321 FUNCTION DESCRIPTION 322 323 The memory used for state memory is freed 324 ------------------------------------------------------------------------------ 325 REQUIREMENTS 326 327 None 328 329 ------------------------------------------------------------------------------ 330 REFERENCES 331 332 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 333 334 ------------------------------------------------------------------------------ 335 PSEUDO-CODE 336 337 338 ------------------------------------------------------------------------------ 339 RESOURCES USED [optional] 340 341 When the code is written for a specific target processor the 342 the resources used should be documented below. 343 344 HEAP MEMORY USED: x bytes 345 346 STACK MEMORY USED: x bytes 347 348 CLOCK CYCLES: (cycle count equation for this function) + (variable 349 used to represent cycle count for each subroutine 350 called) 351 where: (cycle count variable) = cycle count for [subroutine 352 name] 353 354 ------------------------------------------------------------------------------ 355 CAUTION [optional] 356 [State any special notes, constraints or cautions for users of this function] 357 358 ------------------------------------------------------------------------------ 359 */ 360 361 void gainQuant_exit(gainQuantState **state) 362 { 363 if (state == NULL || *state == NULL) 364 return; 365 366 gain_adapt_exit(&(*state)->adaptSt); 367 368 /* deallocate memory */ 369 free(*state); 370 *state = NULL; 371 372 return; 373 } 374 375 376 377 /* 378 ------------------------------------------------------------------------------ 379 FUNCTION NAME: gainQuant 380 ------------------------------------------------------------------------------ 381 INPUT AND OUTPUT DEFINITIONS 382 383 Inputs: 384 st -- pointer to gainQuantState 385 mode -- enum Mode -- coder mode 386 res -- Word16 array -- LP residual, Q0 387 exc -- Word16 array -- LTP excitation (unfiltered), Q0 388 code -- Word16 array -- CB innovation (unfiltered), Q13 389 (unsharpened for MR475) 390 xn -- Word16 array -- Target vector. 391 xn2 -- Word16 array -- Target vector. 392 y1 -- Word16 array -- Adaptive codebook. 393 Y2 -- Word16 array -- Filtered innovative vector. 394 g_coeff -- Word16 array -- Correlations <xn y1> <y1 y1> 395 Compute in G_pitch(). 396 397 even_subframe -- Word16 -- even subframe indicator flag 398 gp_limit -- Word16 -- pitch gain limit 399 gain_pit -- Word16 Pointer -- Pitch gain. 400 401 Outputs: 402 st -- pointer to gainQuantState 403 sf0_gain_pit -- Word16 Pointer -- Pitch gain sf 0. MR475 404 sf0_gain_cod -- Word16 Pointer -- Code gain sf 0. MR475 405 gain_pit -- Word16 Pointer -- Pitch gain. 406 gain_cod -- Word16 Pointer -- Code gain. 407 MR475: gain_* unquantized in even 408 subframes, quantized otherwise 409 410 anap -- Word16 Double Pointer -- Index of quantization 411 412 pOverflow -- Flag Pointer -- overflow indicator 413 414 Returns: 415 Zero 416 417 Global Variables Used: 418 None 419 420 Local Variables Needed: 421 None 422 423 ------------------------------------------------------------------------------ 424 FUNCTION DESCRIPTION 425 426 Quantazation of gains 427 428 ------------------------------------------------------------------------------ 429 REQUIREMENTS 430 431 None 432 433 ------------------------------------------------------------------------------ 434 REFERENCES 435 436 gain_q.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 437 438 ------------------------------------------------------------------------------ 439 PSEUDO-CODE 440 441 442 ------------------------------------------------------------------------------ 443 RESOURCES USED [optional] 444 445 When the code is written for a specific target processor the 446 the resources used should be documented below. 447 448 HEAP MEMORY USED: x bytes 449 450 STACK MEMORY USED: x bytes 451 452 CLOCK CYCLES: (cycle count equation for this function) + (variable 453 used to represent cycle count for each subroutine 454 called) 455 where: (cycle count variable) = cycle count for [subroutine 456 name] 457 458 ------------------------------------------------------------------------------ 459 CAUTION [optional] 460 [State any special notes, constraints or cautions for users of this function] 461 462 ------------------------------------------------------------------------------ 463 */ 464 465 466 467 void gainQuant( 468 gainQuantState *st, /* i/o : State struct */ 469 enum Mode mode, /* i : coder mode */ 470 Word16 res[], /* i : LP residual, Q0 */ 471 Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ 472 Word16 code[], /* i : CB innovation (unfiltered), Q13 */ 473 /* (unsharpened for MR475) */ 474 Word16 xn[], /* i : Target vector. */ 475 Word16 xn2[], /* i : Target vector. */ 476 Word16 y1[], /* i : Adaptive codebook. */ 477 Word16 Y2[], /* i : Filtered innovative vector. */ 478 Word16 g_coeff[], /* i : Correlations <xn y1> <y1 y1> */ 479 /* Compute in G_pitch(). */ 480 Word16 even_subframe, /* i : even subframe indicator flag */ 481 Word16 gp_limit, /* i : pitch gain limit */ 482 Word16 *sf0_gain_pit, /* o : Pitch gain sf 0. MR475 */ 483 Word16 *sf0_gain_cod, /* o : Code gain sf 0. MR475 */ 484 Word16 *gain_pit, /* i/o : Pitch gain. */ 485 Word16 *gain_cod, /* o : Code gain. */ 486 /* MR475: gain_* unquantized in even */ 487 /* subframes, quantized otherwise */ 488 Word16 **anap, /* o : Index of quantization */ 489 Flag *pOverflow /* o : overflow indicator */ 490 ) 491 { 492 Word16 exp_gcode0; 493 Word16 frac_gcode0; 494 Word16 qua_ener_MR122; 495 Word16 qua_ener; 496 Word16 frac_coeff[5]; 497 Word16 exp_coeff[5]; 498 Word16 exp_en; 499 Word16 frac_en; 500 Word16 cod_gain_exp; 501 Word16 cod_gain_frac; 502 Word16 temp; 503 504 if (mode == MR475) 505 { 506 if (even_subframe != 0) 507 { 508 /* save position in output parameter stream and current 509 state of codebook gain predictor */ 510 st->gain_idx_ptr = (*anap)++; 511 512 // gc_pred_copy(&(st->gc_predSt), &(st->gc_predUnqSt)); 513 514 memcpy(st->gc_predUnqSt.past_qua_en, 515 st->gc_predSt.past_qua_en, 516 NPRED*sizeof(Word16)); 517 memcpy(st->gc_predUnqSt.past_qua_en_MR122, 518 st->gc_predSt.past_qua_en_MR122, 519 NPRED*sizeof(Word16)); 520 521 522 /* predict codebook gain (using "unquantized" predictor)*/ 523 /* (note that code[] is unsharpened in MR475) */ 524 gc_pred( 525 &(st->gc_predUnqSt), 526 mode, 527 code, 528 &st->sf0_exp_gcode0, 529 &st->sf0_frac_gcode0, 530 &exp_en, 531 &frac_en, 532 pOverflow); 533 534 /* calculate energy coefficients for quantization 535 and store them in state structure (will be used 536 in next subframe when real quantizer is run) */ 537 calc_filt_energies( 538 mode, 539 xn, 540 xn2, 541 y1, 542 Y2, 543 g_coeff, 544 st->sf0_frac_coeff, 545 st->sf0_exp_coeff, 546 &cod_gain_frac, 547 &cod_gain_exp, 548 pOverflow); 549 550 /* store optimum codebook gain (Q1) */ 551 temp = 552 add( 553 cod_gain_exp, 554 1, 555 pOverflow); 556 557 *gain_cod = 558 shl( 559 cod_gain_frac, 560 temp, 561 pOverflow); 562 563 calc_target_energy( 564 xn, 565 &st->sf0_exp_target_en, 566 &st->sf0_frac_target_en, 567 pOverflow); 568 569 /* calculate optimum codebook gain and update 570 "unquantized" predictor */ 571 MR475_update_unq_pred( 572 &(st->gc_predUnqSt), 573 st->sf0_exp_gcode0, 574 st->sf0_frac_gcode0, 575 cod_gain_exp, 576 cod_gain_frac, 577 pOverflow); 578 579 /* the real quantizer is not run here... */ 580 } 581 else 582 { 583 /* predict codebook gain (using "unquantized" predictor) */ 584 /* (note that code[] is unsharpened in MR475) */ 585 gc_pred( 586 &(st->gc_predUnqSt), 587 mode, 588 code, 589 &exp_gcode0, 590 &frac_gcode0, 591 &exp_en, 592 &frac_en, 593 pOverflow); 594 595 /* calculate energy coefficients for quantization */ 596 calc_filt_energies( 597 mode, 598 xn, 599 xn2, 600 y1, 601 Y2, 602 g_coeff, 603 frac_coeff, 604 exp_coeff, 605 &cod_gain_frac, 606 &cod_gain_exp, 607 pOverflow); 608 609 calc_target_energy( 610 xn, 611 &exp_en, 612 &frac_en, 613 pOverflow); 614 615 /* run real (4-dim) quantizer and update real gain predictor */ 616 *st->gain_idx_ptr = 617 MR475_gain_quant( 618 &(st->gc_predSt), 619 st->sf0_exp_gcode0, 620 st->sf0_frac_gcode0, 621 st->sf0_exp_coeff, 622 st->sf0_frac_coeff, 623 st->sf0_exp_target_en, 624 st->sf0_frac_target_en, 625 code, 626 exp_gcode0, 627 frac_gcode0, 628 exp_coeff, 629 frac_coeff, 630 exp_en, 631 frac_en, 632 gp_limit, 633 sf0_gain_pit, 634 sf0_gain_cod, 635 gain_pit, 636 gain_cod, 637 pOverflow); 638 } 639 } 640 else 641 { 642 /*-------------------------------------------------------------------* 643 * predict codebook gain and quantize * 644 * (also compute normalized CB innovation energy for MR795) * 645 *-------------------------------------------------------------------*/ 646 gc_pred( 647 &(st->gc_predSt), 648 mode, 649 code, 650 &exp_gcode0, 651 &frac_gcode0, 652 &exp_en, 653 &frac_en, 654 pOverflow); 655 656 if (mode == MR122) 657 { 658 *gain_cod = 659 G_code( 660 xn2, 661 Y2, 662 pOverflow); 663 664 *(*anap)++ = 665 q_gain_code( 666 mode, 667 exp_gcode0, 668 frac_gcode0, 669 gain_cod, 670 &qua_ener_MR122, 671 &qua_ener, 672 pOverflow); 673 } 674 else 675 { 676 /* calculate energy coefficients for quantization */ 677 calc_filt_energies( 678 mode, 679 xn, 680 xn2, 681 y1, 682 Y2, 683 g_coeff, 684 frac_coeff, 685 exp_coeff, 686 &cod_gain_frac, 687 &cod_gain_exp, 688 pOverflow); 689 690 if (mode == MR795) 691 { 692 MR795_gain_quant( 693 st->adaptSt, 694 res, 695 exc, 696 code, 697 frac_coeff, 698 exp_coeff, 699 exp_en, 700 frac_en, 701 exp_gcode0, 702 frac_gcode0, 703 L_SUBFR, 704 cod_gain_frac, 705 cod_gain_exp, 706 gp_limit, 707 gain_pit, 708 gain_cod, 709 &qua_ener_MR122, 710 &qua_ener, 711 anap, 712 pOverflow); 713 } 714 else 715 { 716 *(*anap)++ = 717 Qua_gain( 718 mode, 719 exp_gcode0, 720 frac_gcode0, 721 frac_coeff, 722 exp_coeff, 723 gp_limit, 724 gain_pit, 725 gain_cod, 726 &qua_ener_MR122, 727 &qua_ener, 728 pOverflow); 729 } 730 } 731 732 /*------------------------------------------------------------------* 733 * update table of past quantized energies * 734 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * 735 * st->past_qua_en(Q10) = 20 * Log10(qua_gain_code) / constant * 736 * = Log2(qua_gain_code) * 737 * = qua_ener * 738 * constant = 20*Log10(2) * 739 *------------------------------------------------------------------*/ 740 gc_pred_update( 741 &(st->gc_predSt), 742 qua_ener_MR122, 743 qua_ener); 744 } 745 746 return; 747 } 748