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/calc_en.c 35 Funtions: calc_unfilt_energies 36 calc_filt_energies 37 calc_target_energy 38 39 ------------------------------------------------------------------------------ 40 MODULE DESCRIPTION 41 42 This file contains the functions that calculate the energy coefficients 43 for unfiltered and filtered excitation signals, the LTP coding gain, and 44 the target energy. 45 46 ------------------------------------------------------------------------------ 47 */ 48 49 50 /*---------------------------------------------------------------------------- 51 ; INCLUDES 52 ----------------------------------------------------------------------------*/ 53 54 #include "calc_en.h" 55 #include "typedef.h" 56 #include "basicop_malloc.h" 57 #include "l_comp.h" 58 #include "cnst.h" 59 #include "log2.h" 60 #include "basic_op.h" 61 62 /*---------------------------------------------------------------------------- 63 ; MACROS 64 ; Define module specific macros here 65 ----------------------------------------------------------------------------*/ 66 67 68 /*---------------------------------------------------------------------------- 69 ; DEFINES 70 ; Include all pre-processor statements here. Include conditional 71 ; compile variables also. 72 ----------------------------------------------------------------------------*/ 73 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 86 /* 87 ------------------------------------------------------------------------------ 88 FUNCTION NAME: calc_unfilt_energies 89 ------------------------------------------------------------------------------ 90 INPUT AND OUTPUT DEFINITIONS 91 92 Inputs: 93 res = LP residual, buffer type Word16 94 exc = LTP excitation (unfiltered), buffer type Word16 95 code = CB innovation (unfiltered), buffer type Word16 96 gain_pit = pitch gain, type Word16 97 L_subfr = Subframe length, type Word16 98 frac_en = energy coefficients (4), fraction part, buffer type Word16 99 exp_en = energy coefficients (4), exponent part, buffer type Word16 100 ltpg = LTP coding gain (log2()), pointer to type Word16 101 pOverflow= pointer to value indicating existence of overflow (Flag) 102 103 Outputs: 104 frac_en buffer containing new fractional parts of energy coefficients 105 exp_en buffer containing new exponential parts of energy coefficients 106 ltpg points to new LTP coding gain 107 pOverflow = 1 if there is an overflow else it is zero. 108 109 Returns: 110 None. 111 112 Global Variables Used: 113 None 114 115 Local Variables Needed: 116 None 117 118 ------------------------------------------------------------------------------ 119 FUNCTION DESCRIPTION 120 121 This function calculates several energy coefficients for unfiltered 122 excitation signals and the LTP coding gain 123 124 frac_en[0]*2^exp_en[0] = <res res> LP residual energy 125 frac_en[1]*2^exp_en[1] = <exc exc> LTP residual energy 126 frac_en[2]*2^exp_en[2] = <exc code> LTP/CB innovation dot product 127 frac_en[3]*2^exp_en[3] = <lres lres> LTP residual energy 128 (lres = res - gain_pit*exc) 129 ltpg = log2(LP_res_en / LTP_res_en) 130 131 ------------------------------------------------------------------------------ 132 REQUIREMENTS 133 134 None. 135 136 ------------------------------------------------------------------------------ 137 REFERENCES 138 139 calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 140 141 ------------------------------------------------------------------------------ 142 PSEUDO-CODE 143 144 void 145 calc_unfilt_energies( 146 Word16 res[], // i : LP residual, Q0 147 Word16 exc[], // i : LTP excitation (unfiltered), Q0 148 Word16 code[], // i : CB innovation (unfiltered), Q13 149 Word16 gain_pit, // i : pitch gain, Q14 150 Word16 L_subfr, // i : Subframe length 151 152 Word16 frac_en[], // o : energy coefficients (4), fraction part, Q15 153 Word16 exp_en[], // o : energy coefficients (4), exponent part, Q0 154 Word16 *ltpg // o : LTP coding gain (log2()), Q13 155 ) 156 { 157 Word32 s, L_temp; 158 Word16 i, exp, tmp; 159 Word16 ltp_res_en, pred_gain; 160 Word16 ltpg_exp, ltpg_frac; 161 162 // Compute residual energy 163 s = L_mac((Word32) 0, res[0], res[0]); 164 for (i = 1; i < L_subfr; i++) 165 s = L_mac(s, res[i], res[i]); 166 167 // ResEn := 0 if ResEn < 200.0 (= 400 Q1) 168 if (L_sub (s, 400L) < 0) 169 { 170 frac_en[0] = 0; 171 exp_en[0] = -15; 172 } 173 else 174 { 175 exp = norm_l(s); 176 frac_en[0] = extract_h(L_shl(s, exp)); 177 exp_en[0] = sub(15, exp); 178 } 179 180 // Compute ltp excitation energy 181 s = L_mac((Word32) 0, exc[0], exc[0]); 182 for (i = 1; i < L_subfr; i++) 183 s = L_mac(s, exc[i], exc[i]); 184 185 exp = norm_l(s); 186 frac_en[1] = extract_h(L_shl(s, exp)); 187 exp_en[1] = sub(15, exp); 188 189 // Compute scalar product <exc[],code[]> 190 s = L_mac((Word32) 0, exc[0], code[0]); 191 for (i = 1; i < L_subfr; i++) 192 s = L_mac(s, exc[i], code[i]); 193 194 exp = norm_l(s); 195 frac_en[2] = extract_h(L_shl(s, exp)); 196 exp_en[2] = sub(16-14, exp); 197 198 // Compute energy of LTP residual 199 s = 0L; 200 for (i = 0; i < L_subfr; i++) 201 { 202 L_temp = L_mult(exc[i], gain_pit); 203 L_temp = L_shl(L_temp, 1); 204 tmp = sub(res[i], pv_round(L_temp)); // LTP residual, Q0 205 s = L_mac (s, tmp, tmp); 206 } 207 208 exp = norm_l(s); 209 ltp_res_en = extract_h (L_shl (s, exp)); 210 exp = sub (15, exp); 211 212 frac_en[3] = ltp_res_en; 213 exp_en[3] = exp; 214 215 // calculate LTP coding gain, i.e. energy reduction LP res -> LTP res 216 if (ltp_res_en > 0 && frac_en[0] != 0) 217 { 218 // gain = ResEn / LTPResEn 219 pred_gain = div_s (shr (frac_en[0], 1), ltp_res_en); 220 exp = sub (exp, exp_en[0]); 221 222 // L_temp = ltpGain * 2^(30 + exp) 223 L_temp = L_deposit_h (pred_gain); 224 // L_temp = ltpGain * 2^27 225 L_temp = L_shr (L_temp, add (exp, 3)); 226 227 // Log2 = log2() + 27 228 Log2(L_temp, <pg_exp, <pg_frac); 229 230 // ltpg = log2(LtpGain) * 2^13 --> range: +- 4 = +- 12 dB 231 L_temp = L_Comp (sub (ltpg_exp, 27), ltpg_frac); 232 *ltpg = pv_round (L_shl (L_temp, 13)); // Q13 233 } 234 else 235 { 236 *ltpg = 0; 237 } 238 } 239 240 241 ------------------------------------------------------------------------------ 242 RESOURCES USED [optional] 243 244 When the code is written for a specific target processor the 245 the resources used should be documented below. 246 247 HEAP MEMORY USED: x bytes 248 249 STACK MEMORY USED: x bytes 250 251 CLOCK CYCLES: (cycle count equation for this function) + (variable 252 used to represent cycle count for each subroutine 253 called) 254 where: (cycle count variable) = cycle count for [subroutine 255 name] 256 257 ------------------------------------------------------------------------------ 258 CAUTION [optional] 259 [State any special notes, constraints or cautions for users of this function] 260 261 ------------------------------------------------------------------------------ 262 */ 263 264 void calc_unfilt_energies( 265 Word16 res[], /* i : LP residual, Q0 */ 266 Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ 267 Word16 code[], /* i : CB innovation (unfiltered), Q13 */ 268 Word16 gain_pit, /* i : pitch gain, Q14 */ 269 Word16 L_subfr, /* i : Subframe length */ 270 271 Word16 frac_en[], /* o : energy coefficients (4), fraction part, Q15 */ 272 Word16 exp_en[], /* o : energy coefficients (4), exponent part, Q0 */ 273 Word16 *ltpg, /* o : LTP coding gain (log2()), Q13 */ 274 Flag *pOverflow 275 ) 276 { 277 Word32 s1; /* Intermediate energy accumulator */ 278 Word32 s2; /* Intermediate energy accumulator */ 279 Word32 s3; /* Intermediate energy accumulator */ 280 Word32 s4; /* Intermediate energy accumulator */ 281 Word32 L_temp; /* temporal 32 bits storage */ 282 283 Word16 i; /* index used in all loops */ 284 Word16 exp; /* nunmber of '0's or '1's before MSB != 0 */ 285 Word16 tmp1; /* temporal storage */ 286 Word16 tmp2; /* temporal storage */ 287 Word16 ltp_res_en; 288 Word16 pred_gain; /* predictor gain */ 289 Word16 ltpg_exp; /* LTP gain (exponent) */ 290 Word16 ltpg_frac; /* LTP gain (mantissa or fractional part) */ 291 292 s1 = 0; 293 s2 = 0; 294 s3 = 0; 295 s4 = 0; 296 297 /*---------------------------------------------------------------------------- 298 NOTE: Overflow is expected as a result of multiply and accumulated without 299 scale down the inputs. This modification is not made at this point 300 to have bit exact results with the pre-optimization code. (JT 6/20/00) 301 302 ----------------------------------------------------------------------------*/ 303 304 for (i = 0; i < L_subfr; i++) 305 { 306 tmp1 = res[i]; /* avoid multiple accesses to memory */ 307 tmp2 = exc[i]; 308 309 s1 = amrnb_fxp_mac_16_by_16bb((Word32) tmp1, (Word32) tmp1, s1); /* Compute residual energy */ 310 s2 = amrnb_fxp_mac_16_by_16bb((Word32) tmp2, (Word32) tmp2, s2); /* Compute ltp excitation energy */ 311 s3 = amrnb_fxp_mac_16_by_16bb((Word32) tmp2, (Word32) code[i], s3);/* Compute scalar product */ 312 /* <exc[],code[]> */ 313 314 L_temp = L_mult(tmp2, gain_pit, pOverflow); 315 L_temp = L_shl(L_temp, 1, pOverflow); 316 tmp2 = sub(tmp1, pv_round(L_temp, pOverflow), pOverflow); 317 /* LTP residual, Q0 */ 318 s4 = L_mac(s4, tmp2, tmp2, pOverflow); 319 /* Compute energy of LTP residual */ 320 } 321 s1 = s1 << 1; 322 s2 = s2 << 1; 323 s3 = s3 << 1; 324 325 if (s1 & MIN_32) 326 { 327 s1 = MAX_32; 328 *pOverflow = 1; 329 } 330 331 /* ResEn := 0 if ResEn < 200.0 (= 400 Q1) */ 332 if (s1 < 400L) 333 { 334 frac_en[0] = 0; 335 exp_en[0] = -15; 336 } 337 else 338 { 339 exp = norm_l(s1); 340 frac_en[0] = (Word16)(L_shl(s1, exp, pOverflow) >> 16); 341 exp_en[0] = (15 - exp); 342 } 343 344 if (s2 & MIN_32) 345 { 346 s2 = MAX_32; 347 *pOverflow = 1; 348 } 349 350 exp = norm_l(s2); 351 frac_en[1] = (Word16)(L_shl(s2, exp, pOverflow) >> 16); 352 exp_en[1] = sub(15, exp, pOverflow); 353 354 /* s3 is not always sum of squares */ 355 exp = norm_l(s3); 356 frac_en[2] = (Word16)(L_shl(s3, exp, pOverflow) >> 16); 357 exp_en[2] = 2 - exp; 358 359 exp = norm_l(s4); 360 ltp_res_en = (Word16)(L_shl(s4, exp, pOverflow) >> 16); 361 exp = sub(15, exp, pOverflow); 362 363 frac_en[3] = ltp_res_en; 364 exp_en[3] = exp; 365 366 /* calculate LTP coding gain, i.e. energy reduction LP res -> LTP res */ 367 368 if (ltp_res_en > 0 && frac_en[0] != 0) 369 { 370 /* gain = ResEn / LTPResEn */ 371 pred_gain = div_s(shr(frac_en[0], 1, pOverflow), ltp_res_en); 372 exp = sub(exp, exp_en[0], pOverflow); 373 374 /* L_temp = ltpGain * 2^(30 + exp) */ 375 L_temp = (Word32) pred_gain << 16; 376 /* L_temp = ltpGain * 2^27 */ 377 L_temp = L_shr(L_temp, (Word16)(exp + 3), pOverflow); 378 379 /* Log2 = log2() + 27 */ 380 Log2(L_temp, <pg_exp, <pg_frac, pOverflow); 381 382 /* ltpg = log2(LtpGain) * 2^13 --> range: +- 4 = +- 12 dB */ 383 L_temp = L_Comp(sub(ltpg_exp, 27, pOverflow), ltpg_frac, pOverflow); 384 *ltpg = pv_round(L_shl(L_temp, 13, pOverflow), pOverflow); /* Q13 */ 385 } 386 else 387 { 388 *ltpg = 0; 389 } 390 391 return; 392 } 393 394 /****************************************************************************/ 395 396 397 /* 398 ------------------------------------------------------------------------------ 399 FUNCTION NAME: calc_filt_energies 400 ------------------------------------------------------------------------------ 401 INPUT AND OUTPUT DEFINITIONS 402 403 Inputs: 404 mode = coder mode, type Mode 405 xn = LTP target vector, buffer type Word16 406 xn2 = CB target vector, buffer type Word16 407 y1 = Adaptive codebook, buffer type Word16 408 Y2 = Filtered innovative vector, buffer type Word16 409 g_coeff = Correlations <xn y1> <y1 y1> 410 computed in G_pitch() buffer type Word16 411 frac_coeff = energy coefficients (5), fraction part, buffer type Word16 412 exp_coeff = energy coefficients (5), exponent part, buffer type Word16 413 cod_gain_frac = optimum codebook gain (fraction part), pointer type Word16 414 cod_gain_exp = optimum codebook gain (exponent part), pointer type Word16 415 pOverflow = pointer to overflow indicator (Flag) 416 417 Outputs: 418 frac_coeff contains new fraction part energy coefficients 419 exp_coeff contains new exponent part energy coefficients 420 cod_gain_frac points to the new optimum codebook gain (fraction part) 421 cod_gain_exp points to the new optimum codebook gain (exponent part) 422 pOverflow = 1 if there is an overflow else it is zero. 423 424 Returns: 425 None. 426 427 Global Variables Used: 428 None 429 430 Local Variables Needed: 431 None 432 433 ------------------------------------------------------------------------------ 434 FUNCTION DESCRIPTION 435 436 This function calculates several energy coefficients for filtered 437 excitation signals 438 439 Compute coefficients need for the quantization and the optimum 440 codebook gain gcu (for MR475 only). 441 442 coeff[0] = y1 y1 443 coeff[1] = -2 xn y1 444 coeff[2] = y2 y2 445 coeff[3] = -2 xn y2 446 coeff[4] = 2 y1 y2 447 448 gcu = <xn2, y2> / <y2, y2> (0 if <xn2, y2> <= 0) 449 450 Product <y1 y1> and <xn y1> have been computed in G_pitch() and 451 are in vector g_coeff[]. 452 453 ------------------------------------------------------------------------------ 454 REQUIREMENTS 455 456 None. 457 458 ------------------------------------------------------------------------------ 459 REFERENCES 460 461 calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 462 463 ------------------------------------------------------------------------------ 464 PSEUDO-CODE 465 466 void 467 calc_filt_energies( 468 enum Mode mode, // i : coder mode 469 Word16 xn[], // i : LTP target vector, Q0 470 Word16 xn2[], // i : CB target vector, Q0 471 Word16 y1[], // i : Adaptive codebook, Q0 472 Word16 Y2[], // i : Filtered innovative vector, Q12 473 Word16 g_coeff[], // i : Correlations <xn y1> <y1 y1> 474 // computed in G_pitch() 475 476 Word16 frac_coeff[],// o : energy coefficients (5), fraction part, Q15 477 Word16 exp_coeff[], // o : energy coefficients (5), exponent part, Q0 478 Word16 *cod_gain_frac,// o: optimum codebook gain (fraction part), Q15 479 Word16 *cod_gain_exp // o: optimum codebook gain (exponent part), Q0 480 ) 481 { 482 Word32 s, ener_init; 483 Word16 i, exp, frac; 484 Word16 y2[L_SUBFR]; 485 486 if (sub(mode, MR795) == 0 || sub(mode, MR475) == 0) 487 { 488 ener_init = 0L; 489 } 490 else 491 { 492 ener_init = 1L; 493 } 494 495 for (i = 0; i < L_SUBFR; i++) { 496 y2[i] = shr(Y2[i], 3); 497 } 498 499 frac_coeff[0] = g_coeff[0]; 500 exp_coeff[0] = g_coeff[1]; 501 frac_coeff[1] = negate(g_coeff[2]); // coeff[1] = -2 xn y1 502 exp_coeff[1] = add(g_coeff[3], 1); 503 504 505 // Compute scalar product <y2[],y2[]> 506 507 s = L_mac(ener_init, y2[0], y2[0]); 508 for (i = 1; i < L_SUBFR; i++) 509 s = L_mac(s, y2[i], y2[i]); 510 511 exp = norm_l(s); 512 frac_coeff[2] = extract_h(L_shl(s, exp)); 513 exp_coeff[2] = sub(15 - 18, exp); 514 515 // Compute scalar product -2*<xn[],y2[]> 516 517 s = L_mac(ener_init, xn[0], y2[0]); 518 for (i = 1; i < L_SUBFR; i++) 519 s = L_mac(s, xn[i], y2[i]); 520 521 exp = norm_l(s); 522 frac_coeff[3] = negate(extract_h(L_shl(s, exp))); 523 exp_coeff[3] = sub(15 - 9 + 1, exp); 524 525 526 // Compute scalar product 2*<y1[],y2[]> 527 528 s = L_mac(ener_init, y1[0], y2[0]); 529 for (i = 1; i < L_SUBFR; i++) 530 s = L_mac(s, y1[i], y2[i]); 531 532 exp = norm_l(s); 533 frac_coeff[4] = extract_h(L_shl(s, exp)); 534 exp_coeff[4] = sub(15 - 9 + 1, exp); 535 536 if (sub(mode, MR475) == 0 || sub(mode, MR795) == 0) 537 { 538 // Compute scalar product <xn2[],y2[]> 539 540 s = L_mac(ener_init, xn2[0], y2[0]); 541 for (i = 1; i < L_SUBFR; i++) 542 s = L_mac(s, xn2[i], y2[i]); 543 544 exp = norm_l(s); 545 frac = extract_h(L_shl(s, exp)); 546 exp = sub(15 - 9, exp); 547 548 549 if (frac <= 0) 550 { 551 *cod_gain_frac = 0; 552 *cod_gain_exp = 0; 553 } 554 else 555 { 556 // 557 gcu = <xn2, y2> / c[2] 558 = (frac>>1)/frac[2] * 2^(exp+1-exp[2]) 559 = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2]) 560 = div_s * 2^(exp-exp[2]-14) 561 562 *cod_gain_frac = div_s (shr (frac,1), frac_coeff[2]); 563 *cod_gain_exp = sub (sub (exp, exp_coeff[2]), 14); 564 565 } 566 } 567 } 568 569 ------------------------------------------------------------------------------ 570 RESOURCES USED [optional] 571 572 When the code is written for a specific target processor the 573 the resources used should be documented below. 574 575 HEAP MEMORY USED: x bytes 576 577 STACK MEMORY USED: x bytes 578 579 CLOCK CYCLES: (cycle count equation for this function) + (variable 580 used to represent cycle count for each subroutine 581 called) 582 where: (cycle count variable) = cycle count for [subroutine 583 name] 584 585 ------------------------------------------------------------------------------ 586 CAUTION [optional] 587 [State any special notes, constraints or cautions for users of this function] 588 589 ------------------------------------------------------------------------------ 590 */ 591 592 void calc_filt_energies( 593 enum Mode mode, /* i : coder mode */ 594 Word16 xn[], /* i : LTP target vector, Q0 */ 595 Word16 xn2[], /* i : CB target vector, Q0 */ 596 Word16 y1[], /* i : Adaptive codebook, Q0 */ 597 Word16 Y2[], /* i : Filtered innovative vector, Q12 */ 598 Word16 g_coeff[], /* i : Correlations <xn y1> <y1 y1> */ 599 /* computed in G_pitch() */ 600 Word16 frac_coeff[], /* o : energy coefficients (5), fraction part, Q15 */ 601 Word16 exp_coeff[], /* o : energy coefficients (5), exponent part, Q0 */ 602 Word16 *cod_gain_frac, /* o : optimum codebook gain (fraction part),Q15 */ 603 Word16 *cod_gain_exp, /* o : optimum codebook gain (exponent part), Q0 */ 604 Flag *pOverflow 605 ) 606 { 607 Word32 s1; /* Intermediate energy accumulator */ 608 Word32 s2; /* Intermediate energy accumulator */ 609 Word32 s3; /* Intermediate energy accumulator */ 610 611 Word16 i; /* index used in all loops */ 612 Word16 exp; /* number of '0's or '1's before MSB != 0 */ 613 Word16 frac; /* fractional part */ 614 Word16 tmp; /* temporal storage */ 615 Word16 scaled_y2[L_SUBFR]; 616 617 618 frac_coeff[0] = g_coeff[0]; 619 exp_coeff[0] = g_coeff[1]; 620 frac_coeff[1] = negate(g_coeff[2]); /* coeff[1] = -2 xn y1 */ 621 exp_coeff[1] = add(g_coeff[3], 1, pOverflow); 622 623 if ((mode == MR795) || (mode == MR475)) 624 { 625 s1 = 0L; 626 s2 = 0L; 627 s3 = 0L; 628 } 629 else 630 { 631 s1 = 1L; 632 s2 = 1L; 633 s3 = 1L; 634 } 635 636 for (i = 0; i < L_SUBFR; i++) 637 { 638 /* avoid multiple accesses to memory */ 639 tmp = (Y2[i] >> 3); 640 scaled_y2[i] = tmp; 641 642 /* Compute scalar product <scaled_y2[],scaled_y2[]> */ 643 s1 = L_mac(s1, tmp, tmp, pOverflow); 644 645 /* Compute scalar product -2*<xn[],scaled_y2[]> */ 646 s2 = L_mac(s2, xn[i], tmp, pOverflow); 647 648 /* Compute scalar product 2*<y1[],scaled_y2[]> */ 649 s3 = L_mac(s3, y1[i], tmp, pOverflow); 650 } 651 652 exp = norm_l(s1); 653 frac_coeff[2] = (Word16)(L_shl(s1, exp, pOverflow) >> 16); 654 exp_coeff[2] = (-3 - exp); 655 656 exp = norm_l(s2); 657 frac_coeff[3] = negate((Word16)(L_shl(s2, exp, pOverflow) >> 16)); 658 exp_coeff[3] = (7 - exp); 659 660 exp = norm_l(s3); 661 frac_coeff[4] = (Word16)(L_shl(s3, exp, pOverflow) >> 16); 662 exp_coeff[4] = sub(7, exp, pOverflow); 663 664 665 if ((mode == MR795) || (mode == MR475)) 666 { 667 /* Compute scalar product <xn2[],scaled_y2[]> */ 668 s1 = 0L; 669 670 for (i = 0; i < L_SUBFR; i++) 671 { 672 s1 = amrnb_fxp_mac_16_by_16bb((Word32) xn2[i], (Word32)scaled_y2[i], s1); 673 } 674 675 s1 = s1 << 1; 676 677 exp = norm_l(s1); 678 frac = (Word16)(L_shl(s1, exp, pOverflow) >> 16); 679 exp = (6 - exp); 680 681 if (frac <= 0) 682 { 683 *cod_gain_frac = 0; 684 *cod_gain_exp = 0; 685 } 686 else 687 { 688 /* 689 gcu = <xn2, scaled_y2> / c[2] 690 = (frac>>1)/frac[2] * 2^(exp+1-exp[2]) 691 = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2]) 692 = div_s * 2^(exp-exp[2]-14) 693 */ 694 *cod_gain_frac = div_s(shr(frac, 1, pOverflow), frac_coeff[2]); 695 *cod_gain_exp = ((exp - exp_coeff[2]) - 14); 696 } 697 } 698 699 return; 700 } 701 702 /****************************************************************************/ 703 704 /* 705 ------------------------------------------------------------------------------ 706 FUNCTION NAME: calc_target_energy 707 ------------------------------------------------------------------------------ 708 INPUT AND OUTPUT DEFINITIONS 709 710 Inputs: 711 xn = LTP target vector, buffer to type Word16 Q0 712 en_exp = optimum codebook gain (exponent part) pointer to type Word16 713 en_frac = optimum codebook gain (fraction part) pointer to type Word16 714 pOverflow = pointer to overflow indicator (Flag) 715 716 Outputs: 717 en_exp points to new optimum codebook gain (exponent part) 718 en_frac points to new optimum codebook gain (fraction part) 719 pOverflow = 1 if there is an overflow else it is zero. 720 721 Returns: 722 None. 723 724 Global Variables Used: 725 None 726 727 Local Variables Needed: 728 None 729 730 ------------------------------------------------------------------------------ 731 FUNCTION DESCRIPTION 732 733 This function calculates the target energy using the formula, 734 en = <xn, xn> 735 736 ------------------------------------------------------------------------------ 737 REQUIREMENTS 738 739 None. 740 741 ------------------------------------------------------------------------------ 742 REFERENCES 743 744 calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 745 746 ------------------------------------------------------------------------------ 747 PSEUDO-CODE 748 749 void 750 calc_target_energy( 751 Word16 xn[], // i: LTP target vector, Q0 752 Word16 *en_exp, // o: optimum codebook gain (exponent part), Q0 753 Word16 *en_frac // o: optimum codebook gain (fraction part), Q15 754 ) 755 { 756 Word32 s; 757 Word16 i, exp; 758 759 // Compute scalar product <xn[], xn[]> 760 s = L_mac(0L, xn[0], xn[0]); 761 for (i = 1; i < L_SUBFR; i++) 762 s = L_mac(s, xn[i], xn[i]); 763 764 // s = SUM 2*xn(i) * xn(i) = <xn xn> * 2 765 exp = norm_l(s); 766 *en_frac = extract_h(L_shl(s, exp)); 767 *en_exp = sub(16, exp); 768 } 769 770 ------------------------------------------------------------------------------ 771 RESOURCES USED [optional] 772 773 When the code is written for a specific target processor the 774 the resources used should be documented below. 775 776 HEAP MEMORY USED: x bytes 777 778 STACK MEMORY USED: x bytes 779 780 CLOCK CYCLES: (cycle count equation for this function) + (variable 781 used to represent cycle count for each subroutine 782 called) 783 where: (cycle count variable) = cycle count for [subroutine 784 name] 785 786 ------------------------------------------------------------------------------ 787 CAUTION [optional] 788 [State any special notes, constraints or cautions for users of this function] 789 790 ------------------------------------------------------------------------------ 791 */ 792 793 void calc_target_energy( 794 Word16 xn[], /* i: LTP target vector, Q0 */ 795 Word16 *en_exp, /* o: optimum codebook gain (exponent part), Q0 */ 796 Word16 *en_frac, /* o: optimum codebook gain (fraction part), Q15 */ 797 Flag *pOverflow 798 ) 799 { 800 Word32 s; /* Intermediate energy accumulator */ 801 Word16 i; /* index used in all loops */ 802 Word16 exp; 803 804 /* Compute scalar product <xn[], xn[]> */ 805 s = 0; 806 for (i = 0; i < L_SUBFR; i++) 807 { 808 s = amrnb_fxp_mac_16_by_16bb((Word32) xn[i], (Word32) xn[i], s); 809 } 810 811 if (s < 0) 812 { 813 *pOverflow = 1; 814 s = MAX_32; 815 } 816 817 /* s = SUM 2*xn(i) * xn(i) = <xn xn> * 2 */ 818 exp = norm_l(s); 819 *en_frac = (Word16)(L_shl(s, exp, pOverflow) >> 16); 820 *en_exp = (16 - exp); 821 822 return; 823 } 824 825 826