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 Pathname: ./audio/gsm-amr/c/src/gc_pred.c 32 Functions: 33 gc_pred_reset 34 gc_pred 35 gc_pred_update 36 gc_pred_average_limited 37 38 ------------------------------------------------------------------------------ 39 MODULE DESCRIPTION 40 41 This file contains the functions that perform codebook gain MA prediction. 42 43 ------------------------------------------------------------------------------ 44 */ 45 46 /*---------------------------------------------------------------------------- 47 ; INCLUDES 48 ----------------------------------------------------------------------------*/ 49 #include "gc_pred.h" 50 #include "basicop_malloc.h" 51 #include "basic_op.h" 52 #include "cnst.h" 53 #include "log2.h" 54 55 /*---------------------------------------------------------------------------- 56 ; MACROS 57 ; Define module specific macros here 58 ----------------------------------------------------------------------------*/ 59 60 /*---------------------------------------------------------------------------- 61 ; DEFINES 62 ; Include all pre-processor statements here. Include conditional 63 ; compile variables also. 64 ----------------------------------------------------------------------------*/ 65 #define NPRED 4 /* number of prediction taps */ 66 67 /* average innovation energy. */ 68 /* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */ 69 #define MEAN_ENER_MR122 783741L /* 36/(20*log10(2)) (Q17) */ 70 71 /* minimum quantized energy: -14 dB */ 72 #define MIN_ENERGY -14336 /* 14 Q10 */ 73 #define MIN_ENERGY_MR122 -2381 /* 14 / (20*log10(2)) Q10 */ 74 75 /*---------------------------------------------------------------------------- 76 ; LOCAL FUNCTION DEFINITIONS 77 ; Function Prototype declaration 78 ----------------------------------------------------------------------------*/ 79 80 /*---------------------------------------------------------------------------- 81 ; LOCAL VARIABLE DEFINITIONS 82 ; Variable declaration - defined here and used outside this module 83 ----------------------------------------------------------------------------*/ 84 85 /* MA prediction coefficients (Q13) */ 86 static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556}; 87 88 /* MA prediction coefficients (Q6) */ 89 static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12}; 90 91 /* 92 ------------------------------------------------------------------------------ 93 FUNCTION NAME: gc_pred_reset 94 ------------------------------------------------------------------------------ 95 INPUT AND OUTPUT DEFINITIONS 96 97 Inputs: 98 state = pointer to a structure of type gc_predState 99 100 Outputs: 101 past_qua_en field in the structure pointed to by state is initialized 102 to MIN_ENERGY 103 past_qua_en_MR122 field in the structure pointed to by state is 104 initialized to MIN_ENERGY_MR122 105 106 Returns: 107 return_value = 0, if reset was successful; -1, otherwise (int) 108 109 Global Variables Used: 110 None 111 112 Local Variables Needed: 113 None 114 115 ------------------------------------------------------------------------------ 116 FUNCTION DESCRIPTION 117 118 This function initializes the state memory used by gc_pred to zero. 119 120 ------------------------------------------------------------------------------ 121 REQUIREMENTS 122 123 None 124 125 ------------------------------------------------------------------------------ 126 REFERENCES 127 128 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 129 130 ------------------------------------------------------------------------------ 131 PSEUDO-CODE 132 133 int gc_pred_reset (gc_predState *state) 134 { 135 Word16 i; 136 137 if (state == (gc_predState *) NULL){ 138 fprintf(stderr, "gc_pred_reset: invalid parameter\n"); 139 return -1; 140 } 141 142 for(i = 0; i < NPRED; i++) 143 { 144 state->past_qua_en[i] = MIN_ENERGY; 145 state->past_qua_en_MR122[i] = MIN_ENERGY_MR122; 146 } 147 return 0; 148 } 149 150 ------------------------------------------------------------------------------ 151 RESOURCES USED [optional] 152 153 When the code is written for a specific target processor the 154 the resources used should be documented below. 155 156 HEAP MEMORY USED: x bytes 157 158 STACK MEMORY USED: x bytes 159 160 CLOCK CYCLES: (cycle count equation for this function) + (variable 161 used to represent cycle count for each subroutine 162 called) 163 where: (cycle count variable) = cycle count for [subroutine 164 name] 165 166 ------------------------------------------------------------------------------ 167 CAUTION [optional] 168 [State any special notes, constraints or cautions for users of this function] 169 170 ------------------------------------------------------------------------------ 171 */ 172 173 Word16 gc_pred_reset(gc_predState *state) 174 { 175 Word16 i; 176 177 if (state == (gc_predState *) NULL) 178 { 179 /* fprintf(stderr, "gc_pred_reset: invalid parameter\n"); */ 180 return -1; 181 } 182 183 for (i = 0; i < NPRED; i++) 184 { 185 state->past_qua_en[i] = MIN_ENERGY; 186 state->past_qua_en_MR122[i] = MIN_ENERGY_MR122; 187 } 188 189 return(0); 190 } 191 192 /****************************************************************************/ 193 194 /* 195 ------------------------------------------------------------------------------ 196 FUNCTION NAME: gc_pred 197 ------------------------------------------------------------------------------ 198 INPUT AND OUTPUT DEFINITIONS 199 200 Inputs: 201 st = pointer to a structure of type gc_predState 202 mode = AMR mode (enum Mode) 203 code = pointer to the innovative codebook vector; Q12 in MR122 mode, 204 otherwise, Q13 (Word16) 205 exp_gcode0 = pointer to the exponent part of predicted gain factor 206 (Q0) (Word16) 207 frac_gcode0 = pointer to the fractional part of predicted gain factor 208 (Q15) (Word16) 209 exp_en = pointer to the exponent part of the innovation energy; this 210 is calculated for MR795 mode, Q0 (Word16) 211 frac_en = pointer to the fractional part of the innovation energy; 212 this is calculated for MR795 mode, Q15 (Word16) 213 pOverflow = pointer to overflow (Flag) 214 215 Outputs: 216 store pointed to by exp_gcode0 contains the exponent part of the 217 recently calculated predicted gain factor 218 store pointed to by frac_gcode0 contains the fractional part of the 219 recently calculated predicted gain factor 220 store pointed to by exp_en contains the exponent part of the 221 recently calculated innovation energy 222 store pointed to by frac_en contains the fractional part of the 223 recently calculated innovation energy 224 pOverflow = 1 if the math functions called by gc_pred 225 results in overflow else zero. 226 227 Returns: 228 None 229 230 Global Variables Used: 231 None 232 233 Local Variables Needed: 234 pred = table of MA prediction coefficients (Q13) (Word16) 235 pred_MR122 = table of MA prediction coefficients (Q6) (Word16) 236 237 ------------------------------------------------------------------------------ 238 FUNCTION DESCRIPTION 239 240 This function performs the MA prediction of the innovation energy (in 241 dB/(20*log10(2))), with the mean removed. 242 243 ------------------------------------------------------------------------------ 244 REQUIREMENTS 245 246 None 247 248 ------------------------------------------------------------------------------ 249 REFERENCES 250 251 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 252 253 ------------------------------------------------------------------------------ 254 PSEUDO-CODE 255 256 The original etsi reference code uses a global flag Overflow. However, in the 257 actual implementation a pointer to a the overflow flag is passed in. 258 259 void 260 gc_pred( 261 gc_predState *st, // i/o: State struct 262 enum Mode mode, // i : AMR mode 263 Word16 *code, // i : innovative codebook vector (L_SUBFR) 264 // MR122: Q12, other modes: Q13 265 Word16 *exp_gcode0, // o : exponent of predicted gain factor, Q0 266 Word16 *frac_gcode0,// o : fraction of predicted gain factor Q15 267 Word16 *exp_en, // o : exponent of innovation energy, Q0 268 // (only calculated for MR795) 269 Word16 *frac_en // o : fraction of innovation energy, Q15 270 // (only calculated for MR795) 271 ) 272 { 273 Word16 i; 274 Word32 ener_code; 275 Word16 exp, frac; 276 277 *-------------------------------------------------------------------* 278 * energy of code: * 279 * ~~~~~~~~~~~~~~~ * 280 * ener_code = sum(code[i]^2) * 281 *-------------------------------------------------------------------* 282 ener_code = L_mac((Word32) 0, code[0], code[0]); 283 // MR122: Q12*Q12 -> Q25 284 // others: Q13*Q13 -> Q27 285 for (i = 1; i < L_SUBFR; i++) 286 ener_code = L_mac(ener_code, code[i], code[i]); 287 288 if (sub (mode, MR122) == 0) 289 { 290 Word32 ener; 291 292 // ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 293 ener_code = L_mult (pv_round (ener_code), 26214); // Q9 * Q20 -> Q30 294 295 *-------------------------------------------------------------------* 296 * energy of code: * 297 * ~~~~~~~~~~~~~~~ * 298 * ener_code(Q17) = 10 * Log10(energy) / constant * 299 * = 1/2 * Log2(energy) * 300 * constant = 20*Log10(2) * 301 *-------------------------------------------------------------------* 302 // ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 303 Log2(ener_code, &exp, &frac); 304 ener_code = L_Comp (sub (exp, 30), frac); // Q16 for log() 305 // ->Q17 for 1/2 log() 306 307 *-------------------------------------------------------------------* 308 * predicted energy: * 309 * ~~~~~~~~~~~~~~~~~ * 310 * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant * 311 * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) * 312 * constant = 20*Log10(2) * 313 *-------------------------------------------------------------------* 314 315 ener = MEAN_ENER_MR122; // Q24 (Q17) 316 for (i = 0; i < NPRED; i++) 317 { 318 ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]); 319 // Q10 * Q13 -> Q24 320 // Q10 * Q6 -> Q17 321 } 322 323 *-------------------------------------------------------------------* 324 * predicted codebook gain * 325 * ~~~~~~~~~~~~~~~~~~~~~~~ * 326 * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) * 327 * = Pow2(ener-ener_code) * 328 * = Pow2(int(d)+frac(d)) * 329 * * 330 * (store exp and frac for pow2()) * 331 *-------------------------------------------------------------------* 332 333 ener = L_shr (L_sub (ener, ener_code), 1); // Q16 334 L_Extract(ener, exp_gcode0, frac_gcode0); 335 } 336 else // all modes except 12.2 337 { 338 Word32 L_tmp; 339 Word16 exp_code, gcode0; 340 341 *-----------------------------------------------------------------* 342 * Compute: means_ener - 10log10(ener_code/ L_sufr) * 343 *-----------------------------------------------------------------* 344 345 exp_code = norm_l (ener_code); 346 ener_code = L_shl (ener_code, exp_code); 347 348 // Log2 = log2 + 27 349 Log2_norm (ener_code, exp_code, &exp, &frac); 350 351 // fact = 10/log2(10) = 3.01 = 24660 Q13 352 L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14 353 354 * L_tmp = means_ener - 10log10(ener_code/L_SUBFR) 355 * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR) 356 * = K - fact * Log2(ener_code) 357 * = K - fact * log2(ener_code) - fact*27 358 * 359 * ==> K = means_ener + fact*27 + 10log10(L_SUBFR) 360 * 361 * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59) 362 * means_ener = 28.75 = 471040 Q14 (MR67) 363 * means_ener = 30 = 491520 Q14 (MR74) 364 * means_ener = 36 = 589824 Q14 (MR795) 365 * means_ener = 33 = 540672 Q14 (MR102) 366 * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14 367 * fact * 27 = 1331640 Q14 368 * ----------------------------------------- 369 * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2 370 * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2 371 * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2 372 * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2 373 * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2 374 375 376 if (sub (mode, MR102) == 0) 377 { 378 // mean = 33 dB 379 L_tmp = L_mac(L_tmp, 16678, 64); // Q14 380 } 381 else if (sub (mode, MR795) == 0) 382 { 383 // ener_code = <xn xn> * 2^27*2^exp_code 384 // frac_en = ener_code / 2^16 385 // = <xn xn> * 2^11*2^exp_code 386 // <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en 387 // := frac_en * 2^exp_en 388 389 // ==> exp_en = -11-exp_code; 390 391 *frac_en = extract_h (ener_code); 392 *exp_en = sub (-11, exp_code); 393 394 // mean = 36 dB 395 L_tmp = L_mac(L_tmp, 17062, 64); // Q14 396 } 397 else if (sub (mode, MR74) == 0) 398 { 399 // mean = 30 dB 400 L_tmp = L_mac(L_tmp, 32588, 32); // Q14 401 } 402 else if (sub (mode, MR67) == 0) 403 { 404 // mean = 28.75 dB 405 L_tmp = L_mac(L_tmp, 32268, 32); // Q14 406 } 407 else // MR59, MR515, MR475 408 { 409 // mean = 33 dB 410 L_tmp = L_mac(L_tmp, 16678, 64); // Q14 411 } 412 413 *-----------------------------------------------------------------* 414 * Compute gcode0. * 415 * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * 416 *-----------------------------------------------------------------* 417 418 L_tmp = L_shl(L_tmp, 10); // Q24 419 for (i = 0; i < 4; i++) 420 L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]); 421 // Q13 * Q10 -> Q24 422 423 gcode0 = extract_h(L_tmp); // Q8 424 425 *-----------------------------------------------------------------* 426 * gcode0 = pow(10.0, gcode0/20) * 427 * = pow(2, 3.3219*gcode0/20) * 428 * = pow(2, 0.166*gcode0) * 429 *-----------------------------------------------------------------* 430 431 // 5439 Q15 = 0.165985 432 // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) 433 if (sub (mode, MR74) == 0) // For IS641 bitexactness 434 L_tmp = L_mult(gcode0, 5439); // Q8 * Q15 -> Q24 435 else 436 L_tmp = L_mult(gcode0, 5443); // Q8 * Q15 -> Q24 437 438 L_tmp = L_shr(L_tmp, 8); // -> Q16 439 L_Extract(L_tmp, exp_gcode0, frac_gcode0); // -> Q0.Q15 440 } 441 } 442 443 ------------------------------------------------------------------------------ 444 RESOURCES USED [optional] 445 446 When the code is written for a specific target processor the 447 the resources used should be documented below. 448 449 HEAP MEMORY USED: x bytes 450 451 STACK MEMORY USED: x bytes 452 453 CLOCK CYCLES: (cycle count equation for this function) + (variable 454 used to represent cycle count for each subroutine 455 called) 456 where: (cycle count variable) = cycle count for [subroutine 457 name] 458 459 ------------------------------------------------------------------------------ 460 CAUTION [optional] 461 [State any special notes, constraints or cautions for users of this function] 462 463 ------------------------------------------------------------------------------ 464 */ 465 466 void gc_pred( 467 gc_predState *st, /* i/o: State struct */ 468 enum Mode mode, /* i : AMR mode */ 469 Word16 *code, /* i : innovative codebook vector (L_SUBFR) */ 470 /* MR122: Q12, other modes: Q13 */ 471 Word16 *exp_gcode0, /* o : exponent of predicted gain factor, Q0 */ 472 Word16 *frac_gcode0,/* o : fraction of predicted gain factor Q15 */ 473 Word16 *exp_en, /* o : exponent of innovation energy, Q0 */ 474 /* (only calculated for MR795) */ 475 Word16 *frac_en, /* o : fraction of innovation energy, Q15 */ 476 /* (only calculated for MR795) */ 477 Flag *pOverflow 478 ) 479 { 480 register Word16 i; 481 register Word32 L_temp1, L_temp2; 482 register Word32 L_tmp; 483 Word32 ener_code; 484 Word32 ener; 485 Word16 exp, frac; 486 Word16 exp_code, gcode0; 487 Word16 tmp; 488 Word16 *p_code = &code[0]; 489 490 /*-------------------------------------------------------------------* 491 * energy of code: * 492 * ~~~~~~~~~~~~~~~ * 493 * ener_code = sum(code[i]^2) * 494 *-------------------------------------------------------------------*/ 495 ener_code = 0; 496 497 /* MR122: Q12*Q12 -> Q25 */ 498 /* others: Q13*Q13 -> Q27 */ 499 500 for (i = L_SUBFR >> 2; i != 0; i--) 501 { 502 tmp = *(p_code++); 503 ener_code += ((Word32) tmp * tmp) >> 3; 504 tmp = *(p_code++); 505 ener_code += ((Word32) tmp * tmp) >> 3; 506 tmp = *(p_code++); 507 ener_code += ((Word32) tmp * tmp) >> 3; 508 tmp = *(p_code++); 509 ener_code += ((Word32) tmp * tmp) >> 3; 510 } 511 512 ener_code <<= 4; 513 514 if (ener_code < 0) /* Check for saturation */ 515 { 516 ener_code = MAX_32; 517 } 518 519 if (mode == MR122) 520 { 521 /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */ 522 /* Q9 * Q20 -> Q30 */ 523 524 ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1; 525 526 /*-------------------------------------------------------------* 527 * energy of code: * 528 * ~~~~~~~~~~~~~~~ * 529 * ener_code(Q17) = 10 * Log10(energy) / constant * 530 * = 1/2 * Log2(energy) * 531 * constant = 20*Log10(2) * 532 *-------------------------------------------------------------*/ 533 /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */ 534 Log2(ener_code, &exp, &frac, pOverflow); 535 536 /* Q16 for log() */ 537 /* ->Q17 for 1/2 log()*/ 538 539 L_temp1 = (Word32)(exp - 30) << 16; 540 ener_code = L_temp1 + ((Word32)frac << 1); 541 542 /*-------------------------------------------------------------* 543 * predicted energy: * 544 * ~~~~~~~~~~~~~~~~~ * 545 * ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant * 546 * = MEAN_ENER + sum(pred[i]*past_qua_en[i]) * 547 * constant = 20*Log10(2) * 548 *-------------------------------------------------------------*/ 549 550 ener = MEAN_ENER_MR122; /* Q24 (Q17) */ 551 for (i = 0; i < NPRED; i++) 552 { 553 L_temp1 = (((Word32) st->past_qua_en_MR122[i]) * 554 pred_MR122[i]) << 1; 555 ener = L_add(ener, L_temp1, pOverflow); 556 557 /* Q10 * Q13 -> Q24 */ 558 /* Q10 * Q6 -> Q17 */ 559 } 560 561 /*---------------------------------------------------------------* 562 * predicted codebook gain * 563 * ~~~~~~~~~~~~~~~~~~~~~~~ * 564 * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 ) * 565 * = Pow2(ener-ener_code) * 566 * = Pow2(int(d)+frac(d)) * 567 * * 568 * (store exp and frac for pow2()) * 569 *---------------------------------------------------------------*/ 570 /* Q16 */ 571 572 L_temp1 = L_sub(ener, ener_code, pOverflow); 573 574 575 *exp_gcode0 = (Word16)(L_temp1 >> 17); 576 577 L_temp2 = (Word32) * exp_gcode0 << 15; 578 L_temp1 >>= 2; 579 580 *frac_gcode0 = (Word16)(L_temp1 - L_temp2); 581 582 } 583 else /* all modes except 12.2 */ 584 { 585 /*-----------------------------------------------------------------* 586 * Compute: means_ener - 10log10(ener_code/ L_sufr) * 587 *-----------------------------------------------------------------*/ 588 589 exp_code = norm_l(ener_code); 590 ener_code = L_shl(ener_code, exp_code, pOverflow); 591 592 /* Log2 = log2 + 27 */ 593 Log2_norm(ener_code, exp_code, &exp, &frac); 594 595 /* fact = 10/log2(10) = 3.01 = 24660 Q13 */ 596 /* Q0.Q15 * Q13 -> Q14 */ 597 598 L_temp2 = (((Word32) exp) * -24660) << 1; 599 L_tmp = (((Word32) frac) * -24660) >> 15; 600 601 /* Sign-extend resulting product */ 602 if (L_tmp & (Word32) 0x00010000L) 603 { 604 L_tmp = L_tmp | (Word32) 0xffff0000L; 605 } 606 607 L_tmp = L_tmp << 1; 608 L_tmp = L_add(L_tmp, L_temp2, pOverflow); 609 610 611 /* L_tmp = means_ener - 10log10(ener_code/L_SUBFR) 612 * = means_ener - 10log10(ener_code) + 10log10(L_SUBFR) 613 * = K - fact * Log2(ener_code) 614 * = K - fact * log2(ener_code) - fact*27 615 * 616 * ==> K = means_ener + fact*27 + 10log10(L_SUBFR) 617 * 618 * means_ener = 33 = 540672 Q14 (MR475, MR515, MR59) 619 * means_ener = 28.75 = 471040 Q14 (MR67) 620 * means_ener = 30 = 491520 Q14 (MR74) 621 * means_ener = 36 = 589824 Q14 (MR795) 622 * means_ener = 33 = 540672 Q14 (MR102) 623 * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14 624 * fact * 27 = 1331640 Q14 625 * ----------------------------------------- 626 * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2 627 * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2 628 * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2 629 * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2 630 * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2 631 */ 632 633 if (mode == MR102) 634 { 635 /* mean = 33 dB */ 636 L_temp2 = (Word32) 16678 << 7; 637 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ 638 } 639 else if (mode == MR795) 640 { 641 /* ener_code = <xn xn> * 2^27*2^exp_code 642 frac_en = ener_code / 2^16 643 = <xn xn> * 2^11*2^exp_code 644 <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en 645 : = frac_en * 2^exp_en 646 ==> exp_en = -11-exp_code; */ 647 *frac_en = (Word16)(ener_code >> 16); 648 *exp_en = sub(-11, exp_code, pOverflow); 649 650 /* mean = 36 dB */ 651 L_temp2 = (Word32) 17062 << 7; 652 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ 653 } 654 else if (mode == MR74) 655 { 656 /* mean = 30 dB */ 657 L_temp2 = (Word32) 32588 << 6; 658 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ 659 } 660 else if (mode == MR67) 661 { 662 /* mean = 28.75 dB */ 663 L_temp2 = (Word32) 32268 << 6; 664 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ 665 } 666 else /* MR59, MR515, MR475 */ 667 { 668 /* mean = 33 dB */ 669 L_temp2 = (Word32) 16678 << 7; 670 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q14 */ 671 } 672 673 /*-------------------------------------------------------------* 674 * Compute gcode0. * 675 * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener * 676 *--------------------------------------------------------------*/ 677 /* Q24 */ 678 if (L_tmp > (Word32) 0X001fffffL) 679 { 680 *pOverflow = 1; 681 L_tmp = MAX_32; 682 } 683 else if (L_tmp < (Word32) 0xffe00000L) 684 { 685 *pOverflow = 1; 686 L_tmp = MIN_32; 687 } 688 else 689 { 690 L_tmp = L_tmp << 10; 691 } 692 693 for (i = 0; i < 4; i++) 694 { 695 L_temp2 = ((((Word32) pred[i]) * st->past_qua_en[i]) << 1); 696 L_tmp = L_add(L_tmp, L_temp2, pOverflow); /* Q13 * Q10 -> Q24 */ 697 } 698 699 gcode0 = (Word16)(L_tmp >> 16); /* Q8 */ 700 701 /*-----------------------------------------------------------* 702 * gcode0 = pow(10.0, gcode0/20) * 703 * = pow(2, 3.3219*gcode0/20) * 704 * = pow(2, 0.166*gcode0) * 705 *-----------------------------------------------------------*/ 706 707 /* 5439 Q15 = 0.165985 */ 708 /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */ 709 710 if (mode == MR74) /* For IS641 bitexactness */ 711 { 712 L_tmp = (((Word32) gcode0) * 5439) << 1; /* Q8 * Q15 -> Q24 */ 713 } 714 else 715 { 716 L_tmp = (((Word32) gcode0) * 5443) << 1; /* Q8 * Q15 -> Q24 */ 717 } 718 719 if (L_tmp < 0) 720 { 721 L_tmp = ~((~L_tmp) >> 8); 722 } 723 else 724 { 725 L_tmp = L_tmp >> 8; /* -> Q16 */ 726 } 727 728 *exp_gcode0 = (Word16)(L_tmp >> 16); 729 if (L_tmp < 0) 730 { 731 L_temp1 = ~((~L_tmp) >> 1); 732 } 733 else 734 { 735 L_temp1 = L_tmp >> 1; 736 } 737 L_temp2 = (Word32) * exp_gcode0 << 15; 738 *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow)); 739 /* -> Q0.Q15 */ 740 } 741 742 return; 743 } 744 745 /****************************************************************************/ 746 747 /* 748 ------------------------------------------------------------------------------ 749 FUNCTION NAME: gc_pred_update 750 ------------------------------------------------------------------------------ 751 INPUT AND OUTPUT DEFINITIONS 752 753 Inputs: 754 st = pointer to a structure of type gc_predState 755 qua_ener_MR122 = quantized energy for update (Q10); calculated as 756 (log2(qua_err)) (Word16) 757 qua_ener = quantized energy for update (Q10); calculated as 758 (20*log10(qua_err)) (Word16) 759 760 Outputs: 761 structure pointed to by st contains the calculated quantized energy 762 for update 763 764 Returns: 765 None 766 767 Global Variables Used: 768 None 769 770 Local Variables Needed: 771 None 772 773 ------------------------------------------------------------------------------ 774 FUNCTION DESCRIPTION 775 776 This function updates the MA predictor with the last quantized energy. 777 778 ------------------------------------------------------------------------------ 779 REQUIREMENTS 780 781 None 782 783 ------------------------------------------------------------------------------ 784 REFERENCES 785 786 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 787 788 ------------------------------------------------------------------------------ 789 PSEUDO-CODE 790 791 void gc_pred_update( 792 gc_predState *st, // i/o: State struct 793 Word16 qua_ener_MR122, // i : quantized energy for update, Q10 794 // (log2(qua_err)) 795 Word16 qua_ener // i : quantized energy for update, Q10 796 // (20*log10(qua_err)) 797 ) 798 { 799 Word16 i; 800 801 for (i = 3; i > 0; i--) 802 { 803 st->past_qua_en[i] = st->past_qua_en[i - 1]; 804 st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1]; 805 } 806 807 st->past_qua_en_MR122[0] = qua_ener_MR122; // log2 (qua_err), Q10 808 809 st->past_qua_en[0] = qua_ener; // 20*log10(qua_err), Q10 810 811 } 812 813 ------------------------------------------------------------------------------ 814 RESOURCES USED [optional] 815 816 When the code is written for a specific target processor the 817 the resources used should be documented below. 818 819 HEAP MEMORY USED: x bytes 820 821 STACK MEMORY USED: x bytes 822 823 CLOCK CYCLES: (cycle count equation for this function) + (variable 824 used to represent cycle count for each subroutine 825 called) 826 where: (cycle count variable) = cycle count for [subroutine 827 name] 828 829 ------------------------------------------------------------------------------ 830 CAUTION [optional] 831 [State any special notes, constraints or cautions for users of this function] 832 833 ------------------------------------------------------------------------------ 834 */ 835 836 void gc_pred_update( 837 gc_predState *st, /* i/o: State struct */ 838 Word16 qua_ener_MR122, /* i : quantized energy for update, Q10 */ 839 /* (log2(qua_err)) */ 840 Word16 qua_ener /* i : quantized energy for update, Q10 */ 841 /* (20*log10(qua_err)) */ 842 ) 843 { 844 st->past_qua_en[3] = st->past_qua_en[2]; 845 st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2]; 846 847 st->past_qua_en[2] = st->past_qua_en[1]; 848 st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1]; 849 850 st->past_qua_en[1] = st->past_qua_en[0]; 851 st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0]; 852 853 st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (qua_err), Q10 */ 854 855 st->past_qua_en[0] = qua_ener; /* 20*log10(qua_err), Q10 */ 856 857 return; 858 } 859 860 /****************************************************************************/ 861 862 /* 863 ------------------------------------------------------------------------------ 864 FUNCTION NAME: gc_pred_average_limited 865 ------------------------------------------------------------------------------ 866 INPUT AND OUTPUT DEFINITIONS 867 868 Inputs: 869 st = pointer to a structure of type gc_predState 870 ener_avg_MR122 = pointer to the averaged quantized energy (Q10); 871 calculated as (log2(qua_err)) (Word16) 872 ener_avg = pointer to the averaged quantized energy (Q10); calculated 873 as (20*log10(qua_err)) (Word16) 874 pOverflow = pointer to overflow (Flag) 875 876 Outputs: 877 store pointed to by ener_avg_MR122 contains the new averaged quantized 878 energy 879 store pointed to by ener_avg contains the new averaged quantized 880 energy 881 pOverflow = 1 if the math functions called by gc_pred_average_limited 882 results in overflow else zero. 883 884 Returns: 885 None 886 887 Global Variables Used: 888 None 889 890 Local Variables Needed: 891 None 892 893 ------------------------------------------------------------------------------ 894 FUNCTION DESCRIPTION 895 896 This function calculates the average of MA predictor state values (with a 897 lower limit) used in error concealment. 898 899 ------------------------------------------------------------------------------ 900 REQUIREMENTS 901 902 None 903 904 ------------------------------------------------------------------------------ 905 REFERENCES 906 907 gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 908 909 ------------------------------------------------------------------------------ 910 PSEUDO-CODE 911 912 The original etsi reference code uses a global flag Overflow. However, in the 913 actual implementation a pointer to a the overflow flag is passed in. 914 915 void gc_pred_average_limited( 916 gc_predState *st, // i: State struct 917 Word16 *ener_avg_MR122, // o: everaged quantized energy, Q10 918 // (log2(qua_err)) 919 Word16 *ener_avg // o: averaged quantized energy, Q10 920 // (20*log10(qua_err)) 921 ) 922 { 923 Word16 av_pred_en; 924 Word16 i; 925 926 // do average in MR122 mode (log2() domain) 927 av_pred_en = 0; 928 for (i = 0; i < NPRED; i++) 929 { 930 av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]); 931 } 932 933 // av_pred_en = 0.25*av_pred_en 934 av_pred_en = mult (av_pred_en, 8192); 935 936 // if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. 937 938 if (sub (av_pred_en, MIN_ENERGY_MR122) < 0) 939 { 940 av_pred_en = MIN_ENERGY_MR122; 941 } 942 *ener_avg_MR122 = av_pred_en; 943 944 // do average for other modes (20*log10() domain) 945 av_pred_en = 0; 946 for (i = 0; i < NPRED; i++) 947 { 948 av_pred_en = add (av_pred_en, st->past_qua_en[i]); 949 } 950 951 // av_pred_en = 0.25*av_pred_en 952 av_pred_en = mult (av_pred_en, 8192); 953 954 // if (av_pred_en < -14) av_pred_en = .. 955 956 if (sub (av_pred_en, MIN_ENERGY) < 0) 957 { 958 av_pred_en = MIN_ENERGY; 959 } 960 *ener_avg = av_pred_en; 961 } 962 963 ------------------------------------------------------------------------------ 964 RESOURCES USED [optional] 965 966 When the code is written for a specific target processor the 967 the resources used should be documented below. 968 969 HEAP MEMORY USED: x bytes 970 971 STACK MEMORY USED: x bytes 972 973 CLOCK CYCLES: (cycle count equation for this function) + (variable 974 used to represent cycle count for each subroutine 975 called) 976 where: (cycle count variable) = cycle count for [subroutine 977 name] 978 979 ------------------------------------------------------------------------------ 980 CAUTION [optional] 981 [State any special notes, constraints or cautions for users of this function] 982 983 ------------------------------------------------------------------------------ 984 */ 985 986 void gc_pred_average_limited( 987 gc_predState *st, /* i: State struct */ 988 Word16 *ener_avg_MR122, /* o: everaged quantized energy, Q10 */ 989 /* (log2(qua_err)) */ 990 Word16 *ener_avg, /* o: averaged quantized energy, Q10 */ 991 /* (20*log10(qua_err)) */ 992 Flag *pOverflow 993 ) 994 { 995 Word16 av_pred_en; 996 register Word16 i; 997 998 /* do average in MR122 mode (log2() domain) */ 999 av_pred_en = 0; 1000 for (i = 0; i < NPRED; i++) 1001 { 1002 av_pred_en = 1003 add(av_pred_en, st->past_qua_en_MR122[i], pOverflow); 1004 } 1005 1006 /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/ 1007 if (av_pred_en < 0) 1008 { 1009 av_pred_en = (av_pred_en >> 2) | 0xc000; 1010 } 1011 else 1012 { 1013 av_pred_en >>= 2; 1014 } 1015 1016 /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */ 1017 if (av_pred_en < MIN_ENERGY_MR122) 1018 { 1019 av_pred_en = MIN_ENERGY_MR122; 1020 } 1021 *ener_avg_MR122 = av_pred_en; 1022 1023 /* do average for other modes (20*log10() domain) */ 1024 av_pred_en = 0; 1025 for (i = 0; i < NPRED; i++) 1026 { 1027 av_pred_en = add(av_pred_en, st->past_qua_en[i], pOverflow); 1028 } 1029 1030 /* av_pred_en = 0.25*av_pred_en (with sign-extension)*/ 1031 if (av_pred_en < 0) 1032 { 1033 av_pred_en = (av_pred_en >> 2) | 0xc000; 1034 } 1035 else 1036 { 1037 av_pred_en >>= 2; 1038 } 1039 1040 /* if (av_pred_en < -14) av_pred_en = .. */ 1041 if (av_pred_en < MIN_ENERGY) 1042 { 1043 av_pred_en = MIN_ENERGY; 1044 } 1045 *ener_avg = av_pred_en; 1046 } 1047