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/c_g_aver.c 35 Functions: 36 Cb_gain_average_reset 37 Cb_gain_average 38 39 Date: 03/28/2000 40 41 ------------------------------------------------------------------------------ 42 REVISION HISTORY 43 44 Description: Made some changes to the comments to match the comments from 45 other modules. 46 47 Description: Made changes based on comments from the review meeting. 48 49 Description: Synchronized file with UMTS version 3.2.0. Updated coding 50 template. 51 52 Description: Made the following changes per comments from Phase 2/3 review: 53 1. Defined one local variable per line. 54 55 Description: Removed the functions Cb_gain_average_init and 56 Cb_gain_average_exit. The Cb_gain_average related structure is no longer 57 dynamically allocated. 58 59 Description: Passing in pOverflow to comply with changes needed for EPOC 60 Updated the include files for the module. 61 62 Description: Changed round function name to pv_round to avoid conflict with 63 round function in C standard library. 64 65 66 Description: Replaced OSCL mem type functions and eliminated include 67 files that now are chosen by OSCL definitions 68 69 Description: 70 ------------------------------------------------------------------------------ 71 MODULE DESCRIPTION 72 73 This file contains functions that reset and perform 74 codebook gain calculations. 75 76 ------------------------------------------------------------------------------ 77 */ 78 79 80 /*---------------------------------------------------------------------------- 81 ; INCLUDES 82 ----------------------------------------------------------------------------*/ 83 #include <string.h> 84 85 #include "c_g_aver.h" 86 #include "typedef.h" 87 #include "mode.h" 88 #include "cnst.h" 89 90 #include "basic_op.h" 91 92 /*---------------------------------------------------------------------------- 93 ; MACROS 94 ; Define module specific macros here 95 ----------------------------------------------------------------------------*/ 96 97 98 /*---------------------------------------------------------------------------- 99 ; DEFINES 100 ; Include all pre-processor statements here. Include conditional 101 ; compile variables also. 102 ----------------------------------------------------------------------------*/ 103 104 /*---------------------------------------------------------------------------- 105 ; LOCAL FUNCTION DEFINITIONS 106 ; Function Prototype declaration 107 ----------------------------------------------------------------------------*/ 108 109 /*---------------------------------------------------------------------------- 110 ; LOCAL VARIABLE DEFINITIONS 111 ; Variable declaration - defined here and used outside this module 112 ----------------------------------------------------------------------------*/ 113 114 /* 115 ------------------------------------------------------------------------------ 116 FUNCTION NAME: Cb_gain_average_reset 117 ------------------------------------------------------------------------------ 118 INPUT AND OUTPUT DEFINITIONS 119 120 Inputs: 121 state = pointer to a structure of type Cb_gain_averageState 122 123 Outputs: 124 Structure pointed to by state is initialized to zeros 125 126 Returns: 127 Returns 0 if memory was successfully initialized, 128 otherwise returns -1. 129 130 Global Variables Used: 131 None. 132 133 Local Variables Needed: 134 None. 135 136 ------------------------------------------------------------------------------ 137 FUNCTION DESCRIPTION 138 139 Resets state memory 140 141 ------------------------------------------------------------------------------ 142 REQUIREMENTS 143 144 None. 145 146 ------------------------------------------------------------------------------ 147 REFERENCES 148 149 c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 150 151 ------------------------------------------------------------------------------ 152 PSEUDO-CODE 153 154 Word16 Cb_gain_average_reset (Cb_gain_averageState *state) 155 { 156 if (state == (Cb_gain_averageState *) NULL){ 157 fprintf(stderr, "Cb_gain_average_reset: invalid parameter\n"); 158 return -1; 159 } 160 161 // Static vectors to zero 162 Set_zero (state->cbGainHistory, L_CBGAINHIST); 163 164 // Initialize hangover handling 165 state->hangVar = 0; 166 state->hangCount= 0; 167 168 return 0; 169 } 170 171 ------------------------------------------------------------------------------ 172 RESOURCES USED [optional] 173 174 When the code is written for a specific target processor the 175 the resources used should be documented below. 176 177 HEAP MEMORY USED: x bytes 178 179 STACK MEMORY USED: x bytes 180 181 CLOCK CYCLES: (cycle count equation for this function) + (variable 182 used to represent cycle count for each subroutine 183 called) 184 where: (cycle count variable) = cycle count for [subroutine 185 name] 186 187 ------------------------------------------------------------------------------ 188 CAUTION [optional] 189 [State any special notes, constraints or cautions for users of this function] 190 191 ------------------------------------------------------------------------------ 192 */ 193 194 Word16 Cb_gain_average_reset(Cb_gain_averageState *state) 195 { 196 if (state == (Cb_gain_averageState *) NULL) 197 { 198 /* fprint(stderr, "Cb_gain_average_reset: invalid parameter\n"); */ 199 return(-1); 200 } 201 202 /* Static vectors to zero */ 203 memset(state->cbGainHistory, 0, L_CBGAINHIST*sizeof(Word16)); 204 205 /* Initialize hangover handling */ 206 state->hangVar = 0; 207 state->hangCount = 0; 208 209 return(0); 210 } 211 212 /****************************************************************************/ 213 214 /* 215 ------------------------------------------------------------------------------ 216 FUNCTION NAME: Cb_gain_average 217 ------------------------------------------------------------------------------ 218 INPUT AND OUTPUT DEFINITIONS 219 220 Inputs: 221 st = pointer to structure of type Cb_gain_averageState 222 mode = AMR mode (enum Mode) 223 gain_code = CB gain (Word16) 224 lsp = the LSP for the current frame (Word16) 225 lspAver = the average of LSP for 8 frames (Word16) 226 bfi = bad frame indication flag (Word16) 227 prev_bf = previous bad frame indication flag (Word16) 228 pdfi = potential degraded bad frame ind flag (Word16) 229 prev_pdf = prev pot. degraded bad frame ind flag (Word16) 230 inBackgroundNoise = background noise decision (Word16) 231 voicedHangover = # of frames after last voiced frame (Word16) 232 pOverflow = address of overflow (Flag) 233 234 Returns: 235 cbGainMix = codebook gain (Word16) 236 237 Outputs: 238 None. 239 240 Global Variables Used: 241 None. 242 243 Local Variables Needed: 244 None. 245 246 ------------------------------------------------------------------------------ 247 FUNCTION DESCRIPTION 248 249 The mix cb gains for MR475, MR515, MR59, MR67, MR102; gain_code other modes 250 251 ------------------------------------------------------------------------------ 252 REQUIREMENTS 253 254 None. 255 256 ------------------------------------------------------------------------------ 257 REFERENCES 258 259 c_g_aver.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 260 261 ------------------------------------------------------------------------------ 262 PSEUDO-CODE 263 264 Word16 Cb_gain_average ( 265 Cb_gain_averageState *st, // i/o : State variables for CB gain avergeing 266 enum Mode mode, // i : AMR mode 267 Word16 gain_code, // i : CB gain Q1 268 Word16 lsp[], // i : The LSP for the current frame Q15 269 Word16 lspAver[], // i : The average of LSP for 8 frames Q15 270 Word16 bfi, // i : bad frame indication flag 271 Word16 prev_bf, // i : previous bad frame indication flag 272 Word16 pdfi, // i : potential degraded bad frame ind flag 273 Word16 prev_pdf, // i : prev pot. degraded bad frame ind flag 274 Word16 inBackgroundNoise, // i : background noise decision 275 Word16 voicedHangover // i : # of frames after last voiced frame 276 ) 277 { 278 //---------------------------------------------------------* 279 * Compute mixed cb gain, used to make cb gain more * 280 * smooth in background noise for modes 5.15, 5.9 and 6.7 * 281 * states that needs to be updated by all * 282 *--------------------------------------------------------- 283 Word16 i; 284 Word16 cbGainMix, diff, tmp_diff, bgMix, cbGainMean; 285 Word32 L_sum; 286 Word16 tmp[M], tmp1, tmp2, shift1, shift2, shift; 287 288 // set correct cbGainMix for MR74, MR795, MR122 289 cbGainMix = gain_code; 290 291 *-------------------------------------------------------* 292 * Store list of CB gain needed in the CB gain * 293 * averaging * 294 *-------------------------------------------------------* 295 for (i = 0; i < (L_CBGAINHIST-1); i++) 296 { 297 st->cbGainHistory[i] = st->cbGainHistory[i+1]; 298 } 299 st->cbGainHistory[L_CBGAINHIST-1] = gain_code; 300 301 // compute lsp difference 302 for (i = 0; i < M; i++) { 303 tmp1 = abs_s(sub(lspAver[i], lsp[i])); // Q15 304 shift1 = sub(norm_s(tmp1), 1); // Qn 305 tmp1 = shl(tmp1, shift1); // Q15+Qn 306 shift2 = norm_s(lspAver[i]); // Qm 307 tmp2 = shl(lspAver[i], shift2); // Q15+Qm 308 tmp[i] = div_s(tmp1, tmp2); // Q15+(Q15+Qn)-(Q15+Qm) 309 shift = sub(add(2, shift1), shift2); 310 if (shift >= 0) 311 { 312 tmp[i] = shr(tmp[i], shift); // Q15+Qn-Qm-Qx=Q13 313 } 314 else 315 { 316 tmp[i] = shl(tmp[i], negate(shift)); // Q15+Qn-Qm-Qx=Q13 317 } 318 } 319 320 diff = tmp[0]; 321 for (i = 1; i < M; i++) { 322 diff = add(diff, tmp[i]); // Q13 323 } 324 325 // Compute hangover 326 if (sub(diff, 5325) > 0) // 0.65 in Q11 327 { 328 st->hangVar = add(st->hangVar, 1); 329 } 330 else 331 { 332 st->hangVar = 0; 333 } 334 335 if (sub(st->hangVar, 10) > 0) 336 { 337 st->hangCount = 0; // Speech period, reset hangover variable 338 } 339 340 // Compute mix constant (bgMix) 341 bgMix = 8192; // 1 in Q13 342 if ((sub(mode, MR67) <= 0) || (sub(mode, MR102) == 0)) 343 // MR475, MR515, MR59, MR67, MR102 344 { 345 // if errors and presumed noise make smoothing probability stronger 346 if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) || (prev_bf != 0)) && 347 (sub(voicedHangover, 1) > 0) && (inBackgroundNoise != 0) && 348 ((sub(mode, MR475) == 0) || 349 (sub(mode, MR515) == 0) || 350 (sub(mode, MR59) == 0)) )) 351 { 352 // bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; 353 tmp_diff = sub(diff, 4506); // 0.55 in Q13 354 355 // max(0.0, diff-0.55) 356 if (tmp_diff > 0) 357 { 358 tmp1 = tmp_diff; 359 } 360 else 361 { 362 tmp1 = 0; 363 } 364 365 // min(0.25, tmp1) 366 if (sub(2048, tmp1) < 0) 367 { 368 bgMix = 8192; 369 } 370 else 371 { 372 bgMix = shl(tmp1, 2); 373 } 374 } 375 else 376 { 377 // bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; 378 tmp_diff = sub(diff, 3277); // 0.4 in Q13 379 380 // max(0.0, diff-0.40) 381 if (tmp_diff > 0) 382 { 383 tmp1 = tmp_diff; 384 } 385 else 386 { 387 tmp1 = 0; 388 } 389 390 // min(0.25, tmp1) 391 if (sub(2048, tmp1) < 0) 392 { 393 bgMix = 8192; 394 } 395 else 396 { 397 bgMix = shl(tmp1, 2); 398 } 399 } 400 401 if ((sub(st->hangCount, 40) < 0) || (sub(diff, 5325) > 0)) // 0.65 in Q13 402 { 403 bgMix = 8192; // disable mix if too short time since 404 } 405 406 // Smoothen the cb gain trajectory 407 // smoothing depends on mix constant bgMix 408 L_sum = L_mult(6554, st->cbGainHistory[2]); // 0.2 in Q15; L_sum in Q17 409 for (i = 3; i < L_CBGAINHIST; i++) 410 { 411 L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i]); 412 } 413 cbGainMean = pv_round(L_sum); // Q1 414 415 // more smoothing in error and bg noise (NB no DFI used here) 416 if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0) && 417 ((sub(mode, MR475) == 0) || 418 (sub(mode, MR515) == 0) || 419 (sub(mode, MR59) == 0)) ) 420 { 421 L_sum = L_mult(4681, st->cbGainHistory[0]); // 0.143 in Q15; L_sum in Q17 422 for (i = 1; i < L_CBGAINHIST; i++) 423 { 424 L_sum = L_mac(L_sum, 4681, st->cbGainHistory[i]); 425 } 426 cbGainMean = pv_round(L_sum); // Q1 427 } 428 429 // cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; 430 L_sum = L_mult(bgMix, cbGainMix); // L_sum in Q15 431 L_sum = L_mac(L_sum, 8192, cbGainMean); 432 L_sum = L_msu(L_sum, bgMix, cbGainMean); 433 cbGainMix = pv_round(L_shl(L_sum, 2)); // Q1 434 } 435 436 st->hangCount = add(st->hangCount, 1); 437 return cbGainMix; 438 } 439 440 ------------------------------------------------------------------------------ 441 RESOURCES USED [optional] 442 443 When the code is written for a specific target processor the 444 the resources used should be documented below. 445 446 HEAP MEMORY USED: x bytes 447 448 STACK MEMORY USED: x bytes 449 450 CLOCK CYCLES: (cycle count equation for this function) + (variable 451 used to represent cycle count for each subroutine 452 called) 453 where: (cycle count variable) = cycle count for [subroutine 454 name] 455 456 ------------------------------------------------------------------------------ 457 CAUTION [optional] 458 [State any special notes, constraints or cautions for users of this function] 459 460 ------------------------------------------------------------------------------ 461 */ 462 463 Word16 Cb_gain_average( 464 Cb_gain_averageState *st, /* i/o : State variables for CB gain averaging */ 465 enum Mode mode, /* i : AMR mode */ 466 Word16 gain_code, /* i : CB gain Q1 */ 467 Word16 lsp[], /* i : The LSP for the current frame Q15 */ 468 Word16 lspAver[], /* i : The average of LSP for 8 frames Q15 */ 469 Word16 bfi, /* i : bad frame indication flag */ 470 Word16 prev_bf, /* i : previous bad frame indication flag */ 471 Word16 pdfi, /* i : potential degraded bad frame ind flag */ 472 Word16 prev_pdf, /* i : prev pot. degraded bad frame ind flag */ 473 Word16 inBackgroundNoise, /* i : background noise decision */ 474 Word16 voicedHangover, /* i : # of frames after last voiced frame */ 475 Flag *pOverflow 476 ) 477 { 478 Word16 i; 479 Word16 cbGainMix; 480 Word16 diff; 481 Word16 tmp_diff; 482 Word16 bgMix; 483 Word16 cbGainMean; 484 Word32 L_sum; 485 Word16 tmp[M]; 486 Word16 tmp1; 487 Word16 tmp2; 488 Word16 shift1; 489 Word16 shift2; 490 Word16 shift; 491 492 /*---------------------------------------------------------* 493 * Compute mixed cb gain, used to make cb gain more * 494 * smooth in background noise for modes 5.15, 5.9 and 6.7 * 495 * states that needs to be updated by all * 496 *---------------------------------------------------------*/ 497 498 /* set correct cbGainMix for MR74, MR795, MR122 */ 499 cbGainMix = gain_code; 500 501 /*-------------------------------------------------------* 502 * Store list of CB gain needed in the CB gain * 503 * averaging * 504 *-------------------------------------------------------*/ 505 for (i = 0; i < (L_CBGAINHIST - 1); i++) 506 { 507 st->cbGainHistory[i] = st->cbGainHistory[i+1]; 508 } 509 st->cbGainHistory[L_CBGAINHIST-1] = gain_code; 510 511 diff = 0; 512 513 /* compute lsp difference */ 514 for (i = 0; i < M; i++) 515 { 516 tmp1 = abs_s(sub(*(lspAver + i), *(lsp + i), pOverflow)); 517 /* Q15 */ 518 shift1 = sub(norm_s(tmp1), 1, pOverflow); /* Qn */ 519 tmp1 = shl(tmp1, shift1, pOverflow); /* Q15+Qn */ 520 shift2 = norm_s(*(lspAver + i)); /* Qm */ 521 tmp2 = shl(*(lspAver + i), shift2, pOverflow); /* Q15+Qm */ 522 tmp[i] = div_s(tmp1, tmp2); /* Q15+(Q15+Qn)-(Q15+Qm) */ 523 524 shift = 2 + shift1 - shift2; 525 526 if (shift >= 0) 527 { 528 *(tmp + i) = shr(*(tmp + i), shift, pOverflow); 529 /* Q15+Qn-Qm-Qx=Q13 */ 530 } 531 else 532 { 533 *(tmp + i) = shl(*(tmp + i), negate(shift), pOverflow); 534 /* Q15+Qn-Qm-Qx=Q13 */ 535 } 536 537 diff = add(diff, *(tmp + i), pOverflow); /* Q13 */ 538 } 539 540 /* Compute hangover */ 541 542 if (diff > 5325) /* 0.65 in Q11 */ 543 { 544 st->hangVar += 1; 545 } 546 else 547 { 548 st->hangVar = 0; 549 } 550 551 552 if (st->hangVar > 10) 553 { 554 /* Speech period, reset hangover variable */ 555 st->hangCount = 0; 556 } 557 558 /* Compute mix constant (bgMix) */ 559 bgMix = 8192; /* 1 in Q13 */ 560 561 if ((mode <= MR67) || (mode == MR102)) 562 /* MR475, MR515, MR59, MR67, MR102 */ 563 { 564 /* if errors and presumed noise make smoothing probability stronger */ 565 566 if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) || 567 (prev_bf != 0)) 568 && (voicedHangover > 1) 569 && (inBackgroundNoise != 0) 570 && ((mode == MR475) || (mode == MR515) || 571 (mode == MR59)))) 572 { 573 /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */ 574 tmp_diff = sub(diff, 4506, pOverflow); /* 0.55 in Q13 */ 575 } 576 else 577 { 578 /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */ 579 tmp_diff = sub(diff, 3277, pOverflow); /* 0.4 in Q13 */ 580 } 581 582 /* max(0.0, diff-0.55) or */ 583 /* max(0.0, diff-0.40) */ 584 if (tmp_diff > 0) 585 { 586 tmp1 = tmp_diff; 587 } 588 else 589 { 590 tmp1 = 0; 591 } 592 593 /* min(0.25, tmp1) */ 594 if (2048 < tmp1) 595 { 596 bgMix = 8192; 597 } 598 else 599 { 600 bgMix = shl(tmp1, 2, pOverflow); 601 } 602 603 if ((st->hangCount < 40) || (diff > 5325)) /* 0.65 in Q13 */ 604 { 605 /* disable mix if too short time since */ 606 bgMix = 8192; 607 } 608 609 /* Smoothen the cb gain trajectory */ 610 /* smoothing depends on mix constant bgMix */ 611 L_sum = L_mult(6554, st->cbGainHistory[2], pOverflow); 612 /* 0.2 in Q15; L_sum in Q17 */ 613 614 for (i = 3; i < L_CBGAINHIST; i++) 615 { 616 L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i], pOverflow); 617 } 618 cbGainMean = pv_round(L_sum, pOverflow); /* Q1 */ 619 620 /* more smoothing in error and bg noise (NB no DFI used here) */ 621 622 if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0) 623 && ((mode == MR475) || (mode == MR515) 624 || (mode == MR59))) 625 { 626 /* 0.143 in Q15; L_sum in Q17 */ 627 L_sum = L_mult(4681, st->cbGainHistory[0], pOverflow); 628 for (i = 1; i < L_CBGAINHIST; i++) 629 { 630 L_sum = 631 L_mac(L_sum, 4681, st->cbGainHistory[i], pOverflow); 632 } 633 cbGainMean = pv_round(L_sum, pOverflow); /* Q1 */ 634 } 635 636 /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */ 637 /* L_sum in Q15 */ 638 L_sum = L_mult(bgMix, cbGainMix, pOverflow); 639 L_sum = L_mac(L_sum, 8192, cbGainMean, pOverflow); 640 L_sum = L_msu(L_sum, bgMix, cbGainMean, pOverflow); 641 cbGainMix = pv_round(L_shl(L_sum, 2, pOverflow), pOverflow); /* Q1 */ 642 } 643 644 st->hangCount += 1; 645 646 return (cbGainMix); 647 } 648 649