1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V. 6 All rights reserved. 7 8 1. INTRODUCTION 9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16 of the MPEG specifications. 17 18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20 individually for the purpose of encoding or decoding bit streams in products that are compliant with 21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23 software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27 applications information and documentation. 28 29 2. COPYRIGHT LICENSE 30 31 Redistribution and use in source and binary forms, with or without modification, are permitted without 32 payment of copyright license fees provided that you satisfy the following conditions: 33 34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35 your modifications thereto in source code form. 36 37 You must retain the complete text of this software license in the documentation and/or other materials 38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40 modifications thereto to recipients of copies in binary form. 41 42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43 prior written permission. 44 45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46 software or your modifications thereto. 47 48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49 and the date of any change. For modified versions of the FDK AAC Codec, the term 50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 52 53 3. NO PATENT LICENSE 54 55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57 respect to this software. 58 59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60 by appropriate patent licenses. 61 62 4. DISCLAIMER 63 64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69 or business interruption, however caused and on any theory of liability, whether in contract, strict 70 liability, or tort (including negligence), arising in any way out of the use of this software, even if 71 advised of the possibility of such damage. 72 73 5. CONTACT INFORMATION 74 75 Fraunhofer Institute for Integrated Circuits IIS 76 Attention: Audio and Multimedia Departments - FDK AAC LL 77 Am Wolfsmantel 33 78 91058 Erlangen, Germany 79 80 www.iis.fraunhofer.de/amm 81 amm-info (at) iis.fraunhofer.de 82 ----------------------------------------------------------------------------------------------------------- */ 83 84 /***************************** MPEG-4 AAC Decoder ************************** 85 86 Author(s): Josef Hoepfl 87 Description: independent channel concealment 88 89 ******************************************************************************/ 90 91 /*! 92 \page concealment AAC core concealment 93 94 This AAC core implementation includes a concealment function, which can be enabled 95 using the several defines during compilation. 96 97 There are various tests inside the core, starting with simple CRC tests and ending in 98 a variety of plausibility checks. If such a check indicates an invalid bitstream, then 99 concealment is applied. 100 101 Concealment is also applied when the calling main program indicates a distorted or missing 102 data frame using the frameOK flag. This is used for error detection on the transport layer. 103 (See below) 104 105 There are three concealment-modes: 106 107 1) Muting: The spectral data is simply set to zero in case of an detected error. 108 109 2) Noise substitution: In case of an detected error, concealment copies the last frame and adds 110 attenuates the spectral data. For this mode you have to set the #CONCEAL_NOISE define. 111 Noise substitution adds no additional delay. 112 113 3) Interpolation: The interpolation routine swaps the spectral data from the previous and the 114 current frame just before the final frequency to time conversion. In case a single frame is 115 corrupted, concealmant interpolates between the last good and the first good frame to create 116 the spectral data for the missing frame. If multiple frames are corrupted, concealment 117 implements first a fade out based on slightly modified spectral values from the last good 118 frame. As soon as good frames are available, concealmant fades in the new spectral data. 119 For this mode you have to set the #CONCEAL_INTER define. Note that in this case, you also 120 need to set #SBR_BS_DELAY_ENABLE, which basically adds approriate delay in the SBR decoder. 121 Note that the Interpolating-Concealment increases the delay of your decoder by one frame 122 and that it does require additional resources such as memory and computational complexity. 123 124 <h2>How concealment can be used with errors on the transport layer</h2> 125 126 Many errors can or have to be detected on the transport layer. For example in IP based systems 127 packet loss can occur. The transport protocol used should indicate such packet loss by inserting 128 an empty frame with frameOK=0. 129 */ 130 131 #include "conceal.h" 132 133 #include "aac_rom.h" 134 #include "genericStds.h" 135 136 137 /* PNS (of block) */ 138 #include "aacdec_pns.h" 139 #include "block.h" 140 141 #include "FDK_tools_rom.h" 142 143 #define CONCEAL_DFLT_COMF_NOISE_LEVEL ( 46 ) /* ~= -70 dB */ 144 145 146 /* default settings */ 147 #define CONCEAL_DFLT_FADEOUT_FRAMES ( 5 ) 148 #define CONCEAL_DFLT_FADEIN_FRAMES ( 5 ) 149 #define CONCEAL_DFLT_MUTE_RELEASE_FRAMES ( 3 ) 150 151 #define CONCEAL_DFLT_FADE_FACTOR ( 0.707106781186548f ) /* 1/sqrt(2) */ 152 153 /* some often used constants: */ 154 #define FIXP_ZERO FL2FXCONST_DBL(0.0f) 155 #define FIXP_ONE FL2FXCONST_DBL(1.0f) 156 #define FIXP_FL_CORRECTION FL2FXCONST_DBL(0.53333333333333333f) 157 158 /* For parameter conversion */ 159 #define CONCEAL_PARAMETER_BITS ( 8 ) 160 #define CONCEAL_MAX_QUANT_FACTOR ( (1<<CONCEAL_PARAMETER_BITS)-1 ) 161 /*#define CONCEAL_MIN_ATTENUATION_FACTOR_025 ( FL2FXCONST_DBL(0.971627951577106174) )*/ /* -0.25 dB */ 162 #define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD FL2FXCONST_DBL(-0.041524101186092029596853445212299) 163 /*#define CONCEAL_MIN_ATTENUATION_FACTOR_050 ( FL2FXCONST_DBL(0.944060876285923380) )*/ /* -0.50 dB */ 164 #define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD FL2FXCONST_DBL(-0.083048202372184059253597008145293) 165 166 typedef enum { 167 CConcealment_NoExpand, 168 CConcealment_Expand, 169 CConcealment_Compress 170 } 171 CConcealmentExpandType; 172 173 static const FIXP_SGL facMod4Table[4] = { 174 FL2FXCONST_SGL(0.500000000f), /* FIXP_SGL(0x4000), 2^-(1-0,00) */ 175 FL2FXCONST_SGL(0.594603558f), /* FIXP_SGL(0x4c1b), 2^-(1-0,25) */ 176 FL2FXCONST_SGL(0.707106781f), /* FIXP_SGL(0x5a82), 2^-(1-0,50) */ 177 FL2FXCONST_SGL(0.840896415f) /* FIXP_SGL(0x6ba2) 2^-(1-0,75) */ 178 }; 179 180 181 182 183 static void 184 CConcealment_CalcBandEnergy ( 185 FIXP_DBL *spectrum, 186 const SamplingRateInfo *pSamplingRateInfo, 187 const int blockType, 188 CConcealmentExpandType ex, 189 int *sfbEnergy 190 ); 191 192 static void 193 CConcealment_InterpolateBuffer ( 194 FIXP_DBL *spectrum, 195 SHORT *pSpecScalePrev, 196 SHORT *pSpecScaleAct, 197 SHORT *pSpecScaleOut, 198 int *enPrv, 199 int *enAct, 200 int sfbCnt, 201 const SHORT *pSfbOffset 202 ); 203 204 static int 205 CConcealment_ApplyInter ( 206 CConcealmentInfo *pConcealmentInfo, 207 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 208 const SamplingRateInfo *pSamplingRateInfo, 209 const int samplesPerFrame, 210 const int improveTonal, 211 const int frameOk 212 ); 213 214 215 216 static int 217 CConcealment_ApplyNoise ( 218 CConcealmentInfo *pConcealmentInfo, 219 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 220 CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, 221 const SamplingRateInfo *pSamplingRateInfo, 222 const int samplesPerFrame, 223 const UINT flags 224 ); 225 226 static void 227 CConcealment_UpdateState ( 228 CConcealmentInfo *pConcealmentInfo, 229 int frameOk 230 ); 231 232 static void 233 CConcealment_ApplyRandomSign ( 234 int iRandomPhase, 235 FIXP_DBL *spec, 236 int samplesPerFrame 237 ); 238 239 240 static int CConcealment_GetWinSeq(int prevWinSeq) 241 { 242 int newWinSeq = OnlyLongSequence; 243 244 /* Try to have only long blocks */ 245 if ( prevWinSeq == LongStartSequence 246 || prevWinSeq == EightShortSequence ) 247 { 248 newWinSeq = LongStopSequence; 249 } 250 251 return (newWinSeq); 252 } 253 254 255 /*! 256 \brief Init common concealment information data 257 258 \pConcealCommonData Pointer to the concealment common data structure. 259 260 \return none 261 */ 262 void 263 CConcealment_InitCommonData (CConcealParams *pConcealCommonData) 264 { 265 if (pConcealCommonData != NULL) 266 { 267 int i; 268 269 /* Set default error concealment technique */ 270 pConcealCommonData->method = ConcealMethodInter; 271 272 pConcealCommonData->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES; 273 pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES; 274 pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES; 275 276 pConcealCommonData->comfortNoiseLevel = CONCEAL_DFLT_COMF_NOISE_LEVEL; 277 278 /* Init fade factors (symetric) */ 279 pConcealCommonData->fadeOutFactor[0] = FL2FXCONST_SGL( CONCEAL_DFLT_FADE_FACTOR ); 280 pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0]; 281 282 for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { 283 pConcealCommonData->fadeOutFactor[i] = FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i-1],FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR))); 284 pConcealCommonData->fadeInFactor[i] = pConcealCommonData->fadeOutFactor[i]; 285 } 286 } 287 } 288 289 290 291 /*! 292 \brief Get current concealment method. 293 294 \pConcealCommonData Pointer to common concealment data (for all channels) 295 296 \return Concealment method. 297 */ 298 CConcealmentMethod 299 CConcealment_GetMethod( CConcealParams *pConcealCommonData ) 300 { 301 CConcealmentMethod method = ConcealMethodNone; 302 303 if (pConcealCommonData != NULL) { 304 method = pConcealCommonData->method; 305 } 306 307 return (method); 308 } 309 310 311 /*! 312 \brief Init concealment information for each channel 313 314 The function initializes the concealment information. Two methods can be chosen: 315 0 = interpolation method (adds delay) 316 1 = noise substitution (no delay, low complexity) 317 318 \return none 319 */ 320 void 321 CConcealment_InitChannelData ( 322 CConcealmentInfo *pConcealChannelInfo, 323 CConcealParams *pConcealCommonData, 324 int samplesPerFrame ) 325 { 326 int i; 327 328 pConcealChannelInfo->pConcealParams = pConcealCommonData; 329 330 FDKmemclear(pConcealChannelInfo->spectralCoefficient, 1024 * sizeof(FIXP_CNCL)); 331 332 for (i = 0; i < 8; i++) { 333 pConcealChannelInfo->specScale[i] = 0; 334 } 335 336 pConcealChannelInfo->iRandomPhase = 0; 337 338 pConcealChannelInfo->windowSequence = 0; 339 pConcealChannelInfo->windowShape = 0; 340 341 pConcealChannelInfo->prevFrameOk[0] = 1; 342 pConcealChannelInfo->prevFrameOk[1] = 1; 343 344 pConcealChannelInfo->cntFadeFrames = 0; 345 pConcealChannelInfo->cntValidFrames = 0; 346 347 pConcealChannelInfo->concealState = ConcealState_Ok; 348 349 } 350 351 352 /*! 353 \brief Set error concealment parameters 354 355 \concealParams 356 \method 357 \fadeOutSlope 358 \fadeInSlope 359 \muteRelease 360 \comfNoiseLevel 361 362 \return none 363 */ 364 AAC_DECODER_ERROR 365 CConcealment_SetParams ( 366 CConcealParams *concealParams, 367 int method, 368 int fadeOutSlope, 369 int fadeInSlope, 370 int muteRelease, 371 int comfNoiseLevel ) 372 { 373 /* set concealment technique */ 374 if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { 375 switch ((CConcealmentMethod)method) 376 { 377 case ConcealMethodMute: 378 case ConcealMethodNoise: 379 case ConcealMethodInter: 380 /* Be sure to enable delay adjustment of SBR decoder! */ 381 if (concealParams == NULL) { 382 return AAC_DEC_INVALID_HANDLE; 383 } else { 384 /* set param */ 385 concealParams->method = (CConcealmentMethod)method; 386 } 387 break; 388 389 default: 390 return AAC_DEC_SET_PARAM_FAIL; 391 } 392 } 393 394 /* set number of frames for fade-out slope */ 395 if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { 396 if ( (fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) 397 && (fadeOutSlope >= 0) ) 398 { 399 if (concealParams == NULL) { 400 return AAC_DEC_INVALID_HANDLE; 401 } else { 402 /* set param */ 403 concealParams->numFadeOutFrames = fadeOutSlope; 404 } 405 } else { 406 return AAC_DEC_SET_PARAM_FAIL; 407 } 408 } 409 410 /* set number of frames for fade-in slope */ 411 if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { 412 if ( (fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) 413 && (fadeInSlope >= 1) ) 414 { 415 if (concealParams == NULL) { 416 return AAC_DEC_INVALID_HANDLE; 417 } else { 418 /* set param */ 419 concealParams->numFadeInFrames = fadeInSlope; 420 } 421 } else { 422 return AAC_DEC_SET_PARAM_FAIL; 423 } 424 } 425 426 /* set number of error-free frames after which the muting will be released */ 427 if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { 428 if ( (muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS<<1)) 429 && (muteRelease >= 0) ) 430 { 431 if (concealParams == NULL) { 432 return AAC_DEC_INVALID_HANDLE; 433 } else { 434 /* set param */ 435 concealParams->numMuteReleaseFrames = muteRelease; 436 } 437 } else { 438 return AAC_DEC_SET_PARAM_FAIL; 439 } 440 } 441 442 /* set confort noise level which will be inserted while in state 'muting' */ 443 if (comfNoiseLevel != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { 444 if ( (comfNoiseLevel < 0) 445 || (comfNoiseLevel > 127) ) { 446 return AAC_DEC_SET_PARAM_FAIL; 447 } 448 if (concealParams == NULL) { 449 return AAC_DEC_INVALID_HANDLE; 450 } else { 451 concealParams->comfortNoiseLevel = comfNoiseLevel; 452 } 453 } 454 455 return (AAC_DEC_OK); 456 } 457 458 459 /*! 460 \brief Set fade-out/in attenuation factor vectors 461 462 \concealParams 463 \fadeOutAttenuationVector 464 \fadeInAttenuationVector 465 466 \return 0 if OK all other values indicate errors 467 */ 468 AAC_DECODER_ERROR 469 CConcealment_SetAttenuation ( 470 CConcealParams *concealParams, 471 SHORT *fadeOutAttenuationVector, 472 SHORT *fadeInAttenuationVector ) 473 { 474 if ( (fadeOutAttenuationVector == NULL) 475 && (fadeInAttenuationVector == NULL) ) { 476 return AAC_DEC_SET_PARAM_FAIL; 477 } 478 479 /* Fade-out factors */ 480 if (fadeOutAttenuationVector != NULL) 481 { 482 int i; 483 484 /* check quantized factors first */ 485 for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { 486 if ((fadeOutAttenuationVector[i] < 0) || (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { 487 return AAC_DEC_SET_PARAM_FAIL; 488 } 489 } 490 if (concealParams == NULL) { 491 return AAC_DEC_INVALID_HANDLE; 492 } 493 494 /* now dequantize factors */ 495 for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) 496 { 497 concealParams->fadeOutFactor[i] = 498 FX_DBL2FX_SGL( fLdPow( CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 499 0, 500 (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0/2.0)>>(CONCEAL_PARAMETER_BITS-1)) * (INT)fadeOutAttenuationVector[i]), 501 CONCEAL_PARAMETER_BITS 502 ) 503 ); 504 } 505 } 506 507 /* Fade-in factors */ 508 if (fadeInAttenuationVector != NULL) 509 { 510 int i; 511 512 /* check quantized factors first */ 513 for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) { 514 if ((fadeInAttenuationVector[i] < 0) || (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { 515 return AAC_DEC_SET_PARAM_FAIL; 516 } 517 } 518 if (concealParams == NULL) { 519 return AAC_DEC_INVALID_HANDLE; 520 } 521 522 /* now dequantize factors */ 523 for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) 524 { 525 concealParams->fadeInFactor[i] = 526 FX_DBL2FX_SGL( fLdPow( CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 527 0, 528 (FIXP_DBL)((INT)(FIXP_ONE>>CONCEAL_PARAMETER_BITS) * (INT)fadeInAttenuationVector[i]), 529 CONCEAL_PARAMETER_BITS 530 ) 531 ); 532 } 533 } 534 535 return (AAC_DEC_OK); 536 } 537 538 539 /*! 540 \brief Get state of concealment module. 541 542 \pConcealChannelInfo 543 544 \return Concealment state. 545 */ 546 CConcealmentState 547 CConcealment_GetState ( 548 CConcealmentInfo *pConcealChannelInfo 549 ) 550 { 551 CConcealmentState state = ConcealState_Ok; 552 553 if (pConcealChannelInfo != NULL) { 554 state = pConcealChannelInfo->concealState; 555 } 556 557 return (state); 558 } 559 560 561 static void CConcealment_fakePnsData ( 562 CPnsData *pPnsData, 563 CIcsInfo *pIcsInfo, 564 const SamplingRateInfo *pSamplingRateInfo, 565 SHORT *pSpecScale, 566 SHORT *pScaleFactor, 567 const int level ) 568 { 569 CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData; 570 571 int pnsBand, band, group, win; 572 //int delta = 0; 573 int windowsPerFrame = GetWindowsPerFrame(pIcsInfo); 574 int refLevel = (windowsPerFrame > 1) ? 82 : 91; 575 576 FDK_ASSERT(level >= 0 && level <= 127); 577 578 for (win = 0; win < windowsPerFrame; win++) { 579 pSpecScale[win] = 31; 580 } 581 582 /* fake ICS info if necessary */ 583 if (!IsValid(pIcsInfo)) { 584 pIcsInfo->WindowGroups = 1; 585 if (IsLongBlock(pIcsInfo)) { 586 pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 587 pIcsInfo->WindowGroupLength[0] = 1; 588 } 589 else { 590 pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Short; 591 pIcsInfo->WindowGroupLength[0] = 8; 592 } 593 pIcsInfo->MaxSfBands = pIcsInfo->TotalSfBands; 594 } 595 596 /* global activate PNS */ 597 pPnsData->PnsActive = 1; 598 /* set energy level */ 599 pPnsData->CurrentEnergy = fixMax( 0, refLevel - level ); 600 601 /* 602 value: | Avg. RMS power | Avg. RMS power | 603 | specScale = 22 | specScale = 31 | 604 -------+----------------+----------------+ 605 5 | | -99.0 dB 606 15 | | -90.0 dB 607 25 | | -89.7 dB 608 35 | | -85.3 dB 609 ... | ... | ... 610 45 | -69.9 dB | -70.0 dB 611 50 | -62.2 dB | 612 55 | -55.6 dB | -54.6 dB 613 60 | -47.0 dB | 614 65 | -39.5 dB | -39.5 dB 615 70 | -31.9 dB | 616 75 | -24.4 dB | -24.4 dB 617 80 | -16.9 dB | 618 85 | -9.4 dB (c) | -9.4 dB 619 90 | -3.9 dB (c) | 620 95 | | -2.1 dB 621 100 | | -1.6 dB 622 105 | | -1.4 dB 623 */ 624 625 for (group=0; group < GetWindowGroups(pIcsInfo); group++) 626 { 627 for (band=0; band < GetScaleFactorBandsTransmitted(pIcsInfo); band++) 628 { 629 pnsBand = group * 16 + band; 630 631 if (pnsBand >= NO_OFBANDS) { 632 return; 633 } 634 //pPnsData->CurrentEnergy += delta ; 635 pScaleFactor[pnsBand] = pPnsData->CurrentEnergy; 636 pInterChannelData->correlated[pnsBand] = 0; 637 pPnsData->pnsUsed[pnsBand] = 1; 638 } 639 } 640 } 641 642 643 /*! 644 \brief Store data for concealment techniques applied later 645 646 Interface function to store data for different concealment strategies 647 648 \return none 649 */ 650 void 651 CConcealment_Store ( 652 CConcealmentInfo *hConcealmentInfo, 653 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 654 CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo ) 655 { 656 if ( !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD 657 ) ) 658 { 659 FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); 660 SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; 661 CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; 662 663 SHORT tSpecScale[8]; 664 UCHAR tWindowShape, tWindowSequence; 665 666 /* store old window infos for swapping */ 667 tWindowSequence = hConcealmentInfo->windowSequence; 668 tWindowShape = hConcealmentInfo->windowShape; 669 670 /* store old scale factors for swapping */ 671 FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8*sizeof(SHORT)); 672 673 /* store new window infos */ 674 hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo); 675 hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo); 676 hConcealmentInfo->lastWinGrpLen = *(GetWindowGroupLengthTable(pIcsInfo)+GetWindowGroups(pIcsInfo)-1); 677 678 /* store new scale factors */ 679 FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8*sizeof(SHORT)); 680 681 if (CConcealment_GetDelay(hConcealmentInfo->pConcealParams) == 0) 682 { 683 /* store new spectral bins */ 684 #if (CNCL_FRACT_BITS == DFRACT_BITS) 685 FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL)); 686 #else 687 FIXP_CNCL *RESTRICT pCncl = &hConcealmentInfo->spectralCoefficient[1024-1]; 688 FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024-1]; 689 int i; 690 691 for (i = 1024; i != 0; i--) { 692 *pCncl-- = FX_DBL2FX_CNCL(*pSpec--); 693 } 694 #endif 695 } 696 else 697 { 698 FIXP_CNCL *RESTRICT pCncl = &hConcealmentInfo->spectralCoefficient[1024-1]; 699 FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024-1]; 700 int i; 701 702 /* swap spectral data */ 703 for (i = 1024; i != 0; i--) { 704 FIXP_DBL tSpec = *pSpec; 705 *pSpec-- = FX_CNCL2FX_DBL(*pCncl); 706 *pCncl-- = FX_DBL2FX_CNCL( tSpec); 707 } 708 709 /* complete swapping of window infos */ 710 pIcsInfo->WindowSequence = tWindowSequence; 711 pIcsInfo->WindowShape = tWindowShape; 712 713 /* complete swapping of scale factors */ 714 FDKmemcpy(pSpecScale, tSpecScale, 8*sizeof(SHORT)); 715 } 716 } 717 718 } 719 720 721 /*! 722 \brief Apply concealment 723 724 Interface function to different concealment strategies 725 726 \return none 727 */ 728 int 729 CConcealment_Apply ( 730 CConcealmentInfo *hConcealmentInfo, 731 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 732 CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, 733 const SamplingRateInfo *pSamplingRateInfo, 734 const int samplesPerFrame, 735 const UCHAR lastLpdMode, 736 const int frameOk, 737 const UINT flags) 738 { 739 int appliedProcessing = 0; 740 741 if ( (frameOk == 0) 742 && (pAacDecoderChannelInfo->renderMode != (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode) ) { 743 /* restore the last render mode to stay in the same domain which allows to do a proper concealment */ 744 pAacDecoderChannelInfo->renderMode = (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode; 745 } else { 746 /* otherwise store the current mode */ 747 hConcealmentInfo->lastRenderMode = (SCHAR)pAacDecoderChannelInfo->renderMode; 748 } 749 750 if ( frameOk ) 751 { 752 /* Rescue current data for concealment in future frames */ 753 CConcealment_Store ( hConcealmentInfo, 754 pAacDecoderChannelInfo, 755 pAacDecoderStaticChannelInfo ); 756 /* Reset index to random sign vector to make sign calculation frame agnostic 757 (only depends on number of subsequently concealed spectral blocks) */ 758 hConcealmentInfo->iRandomPhase = 0; 759 } 760 761 /* hand current frame status to the state machine */ 762 CConcealment_UpdateState( hConcealmentInfo, 763 frameOk ); 764 765 if ( !frameOk ) 766 { 767 /* Create data for signal rendering according to the selected concealment method and decoder operating mode. */ 768 769 770 if ( !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD 771 ) 772 ) 773 { 774 switch (hConcealmentInfo->pConcealParams->method) 775 { 776 default: 777 case ConcealMethodMute: 778 /* Mute spectral data in case of errors */ 779 FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); 780 /* Set last window shape */ 781 pAacDecoderChannelInfo->icsInfo.WindowShape = hConcealmentInfo->windowShape; 782 appliedProcessing = 1; 783 break; 784 785 case ConcealMethodNoise: 786 /* Noise substitution error concealment technique */ 787 appliedProcessing = 788 CConcealment_ApplyNoise (hConcealmentInfo, 789 pAacDecoderChannelInfo, 790 pAacDecoderStaticChannelInfo, 791 pSamplingRateInfo, 792 samplesPerFrame, 793 flags); 794 break; 795 796 case ConcealMethodInter: 797 /* Energy interpolation concealment based on 3GPP */ 798 appliedProcessing = 799 CConcealment_ApplyInter (hConcealmentInfo, 800 pAacDecoderChannelInfo, 801 pSamplingRateInfo, 802 samplesPerFrame, 803 0, /* don't use tonal improvement */ 804 0); 805 break; 806 807 } 808 } 809 } 810 /* update history */ 811 hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1]; 812 hConcealmentInfo->prevFrameOk[1] = frameOk; 813 814 return appliedProcessing; 815 } 816 817 /*! 818 \brief Apply concealment noise substitution 819 820 In case of frame lost this function produces a noisy frame with respect to the 821 energies values of past frame. 822 823 \return none 824 */ 825 static int 826 CConcealment_ApplyNoise (CConcealmentInfo *pConcealmentInfo, 827 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 828 CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, 829 const SamplingRateInfo *pSamplingRateInfo, 830 const int samplesPerFrame, 831 const UINT flags) 832 { 833 CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; 834 835 FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); 836 SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; 837 CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; 838 839 int appliedProcessing = 0; 840 841 FDK_ASSERT((samplesPerFrame>=480) && (samplesPerFrame<=1024)); 842 FDK_ASSERT((samplesPerFrame&0x1F) == 0); 843 844 switch (pConcealmentInfo->concealState) 845 { 846 case ConcealState_Ok: 847 /* Nothing to do here! */ 848 break; 849 850 case ConcealState_Single: 851 case ConcealState_FadeOut: 852 { 853 /* restore frequency coefficients from buffer with a specific muting */ 854 FIXP_SGL fac; 855 int win, numWindows = 1; 856 int windowLen = samplesPerFrame; 857 int tFadeFrames, lastWindow = 0; 858 int win_idx_stride = 1; 859 860 FDK_ASSERT(pConcealmentInfo != NULL); 861 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 862 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 863 FDK_ASSERT(pConcealmentInfo->cntFadeFrames <= pConcealCommonData->numFadeOutFrames); 864 865 /* get attenuation factor */ 866 tFadeFrames = pConcealmentInfo->cntFadeFrames; 867 fac = pConcealCommonData->fadeOutFactor[tFadeFrames]; 868 869 /* set old window parameters */ 870 { 871 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; 872 pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; 873 874 if (pConcealmentInfo->windowSequence == 2) { 875 /* short block handling */ 876 numWindows = 8; 877 windowLen = samplesPerFrame >> 3; 878 lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen; 879 } 880 } 881 882 for (win = 0; win < numWindows; win++) { 883 FIXP_CNCL *pCncl = pConcealmentInfo->spectralCoefficient + (lastWindow * windowLen); 884 FIXP_DBL *pOut = pSpectralCoefficient + (win * windowLen); 885 int i; 886 887 FDK_ASSERT((lastWindow * windowLen + windowLen) <= samplesPerFrame); 888 889 /* restore frequency coefficients from buffer with a specific attenuation */ 890 for (i = 0; i < windowLen; i++) { 891 pOut[i] = fMult(pCncl[i], fac); 892 } 893 894 /* apply random change of sign for spectral coefficients */ 895 CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, 896 pOut, 897 windowLen ); 898 899 /* Increment random phase index to avoid repetition artifacts. */ 900 pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); 901 902 /* set old scale factors */ 903 pSpecScale[win*win_idx_stride] = pConcealmentInfo->specScale[win_idx_stride*lastWindow++]; 904 905 if ( (lastWindow >= numWindows) 906 && (numWindows > 1) ) 907 { 908 /* end of sequence -> rewind */ 909 lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen; 910 /* update the attenuation factor to get a faster fade-out */ 911 tFadeFrames += 1; 912 if (tFadeFrames < pConcealCommonData->numFadeOutFrames) { 913 fac = pConcealCommonData->fadeOutFactor[tFadeFrames]; 914 } else { 915 fac = (FIXP_SGL)0; 916 } 917 } 918 } 919 920 /* store temp vars */ 921 pConcealmentInfo->cntFadeFrames = tFadeFrames; 922 appliedProcessing = 1; 923 } 924 break; 925 926 case ConcealState_Mute: 927 { 928 /* set dummy window parameters */ 929 pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ 930 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape (required for F/T transform) */ 931 pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); 932 pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */ 933 934 /* mute spectral data */ 935 FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); 936 937 if ( !(flags & (AC_USAC|AC_RSVD50)) 938 && pConcealCommonData->comfortNoiseLevel >= 0 939 && pConcealCommonData->comfortNoiseLevel <= 61 /* -90dB */) 940 { 941 /* insert comfort noise using PNS */ 942 CConcealment_fakePnsData ( 943 &pAacDecoderChannelInfo->data.aac.PnsData, 944 pIcsInfo, 945 pSamplingRateInfo, 946 pAacDecoderChannelInfo->pDynData->aSfbScale, 947 pAacDecoderChannelInfo->pDynData->aScaleFactor, 948 pConcealCommonData->comfortNoiseLevel 949 ); 950 951 CPns_Apply ( 952 &pAacDecoderChannelInfo->data.aac.PnsData, 953 pIcsInfo, 954 pAacDecoderChannelInfo->pSpectralCoefficient, 955 pAacDecoderChannelInfo->specScale, 956 pAacDecoderChannelInfo->pDynData->aScaleFactor, 957 pSamplingRateInfo, 958 pAacDecoderChannelInfo->granuleLength, 959 0 /* always apply to first channel */ 960 ); 961 } 962 appliedProcessing = 1; 963 } 964 break; 965 966 case ConcealState_FadeIn: 967 { 968 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 969 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 970 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames); 971 972 /* attenuate signal to get a smooth fade-in */ 973 FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; 974 FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames]; 975 int i; 976 977 for (i = samplesPerFrame; i != 0; i--) { 978 *pOut = fMult(*pOut, fac); 979 pOut--; 980 } 981 appliedProcessing = 1; 982 } 983 break; 984 985 default: 986 /* we shouldn't come here anyway */ 987 FDK_ASSERT(0); 988 break; 989 } 990 991 return appliedProcessing; 992 } 993 994 995 /*! 996 \brief Apply concealment interpolation 997 998 The function swaps the data from the current and the previous frame. If an 999 error has occured, frame interpolation is performed to restore the missing 1000 frame. In case of multiple faulty frames, fade-in and fade-out is applied. 1001 1002 \return none 1003 */ 1004 static int 1005 CConcealment_ApplyInter ( 1006 CConcealmentInfo *pConcealmentInfo, 1007 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 1008 const SamplingRateInfo *pSamplingRateInfo, 1009 const int samplesPerFrame, 1010 const int improveTonal, 1011 const int frameOk ) 1012 { 1013 CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; 1014 1015 FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); 1016 CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; 1017 SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; 1018 1019 1020 int sfbEnergyPrev[64]; 1021 int sfbEnergyAct [64]; 1022 1023 int i, appliedProcessing = 0; 1024 1025 /* clear/init */ 1026 FDKmemclear(sfbEnergyPrev, 64 * sizeof(int)); 1027 FDKmemclear(sfbEnergyAct, 64 * sizeof(int)); 1028 1029 1030 if (!frameOk) 1031 { 1032 /* Restore last frame from concealment buffer */ 1033 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; 1034 pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; 1035 1036 /* Restore spectral data */ 1037 for (i = 0; i < samplesPerFrame; i++) { 1038 pSpectralCoefficient[i] = FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]); 1039 } 1040 1041 /* Restore scale factors */ 1042 FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8*sizeof(SHORT)); 1043 } 1044 1045 /* if previous frame was not ok */ 1046 if (!pConcealmentInfo->prevFrameOk[1]) { 1047 1048 /* if current frame (f_n) is ok and the last but one frame (f_(n-2)) 1049 was ok, too, then interpolate both frames in order to generate 1050 the current output frame (f_(n-1)). Otherwise, use the last stored 1051 frame (f_(n-2) or f_(n-3) or ...). */ 1052 if (frameOk && pConcealmentInfo->prevFrameOk[0]) 1053 { 1054 appliedProcessing = 1; 1055 1056 1057 /* Interpolate both frames in order to generate the current output frame (f_(n-1)). */ 1058 if (pIcsInfo->WindowSequence == EightShortSequence) { 1059 /* f_(n-2) == EightShortSequence */ 1060 /* short--??????--short, short--??????--long interpolation */ 1061 /* short--short---short, short---long---long interpolation */ 1062 1063 int wnd; 1064 1065 if (pConcealmentInfo->windowSequence == EightShortSequence) { /* f_n == EightShortSequence */ 1066 /* short--short---short interpolation */ 1067 1068 int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short; 1069 const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; 1070 pIcsInfo->WindowShape = 1; 1071 pIcsInfo->WindowSequence = EightShortSequence; 1072 1073 for (wnd = 0; wnd < 8; wnd++) 1074 { 1075 CConcealment_CalcBandEnergy( 1076 &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-2) */ 1077 pSamplingRateInfo, 1078 EightShortSequence, 1079 CConcealment_NoExpand, 1080 sfbEnergyPrev); 1081 1082 CConcealment_CalcBandEnergy( 1083 &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_n */ 1084 pSamplingRateInfo, 1085 EightShortSequence, 1086 CConcealment_NoExpand, 1087 sfbEnergyAct); 1088 1089 CConcealment_InterpolateBuffer( 1090 &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-1) */ 1091 &pSpecScale[wnd], 1092 &pConcealmentInfo->specScale[wnd], 1093 &pSpecScale[wnd], 1094 sfbEnergyPrev, 1095 sfbEnergyAct, 1096 scaleFactorBandsTotal, 1097 pSfbOffset); 1098 1099 } 1100 } else { /* f_n != EightShortSequence */ 1101 /* short---long---long interpolation */ 1102 1103 int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1104 const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1105 SHORT specScaleOut; 1106 1107 CConcealment_CalcBandEnergy(&pSpectralCoefficient[samplesPerFrame - (samplesPerFrame / 8)], /* [wnd] spec_(n-2) */ 1108 pSamplingRateInfo, 1109 EightShortSequence, 1110 CConcealment_Expand, 1111 sfbEnergyAct); 1112 1113 CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ 1114 pSamplingRateInfo, 1115 OnlyLongSequence, 1116 CConcealment_NoExpand, 1117 sfbEnergyPrev); 1118 1119 pIcsInfo->WindowShape = 0; 1120 pIcsInfo->WindowSequence = LongStopSequence; 1121 1122 for (i = 0; i < samplesPerFrame ; i++) { 1123 pSpectralCoefficient[i] = pConcealmentInfo->spectralCoefficient[i]; /* spec_n */ 1124 } 1125 1126 for (i = 0; i < 8; i++) { /* search for max(specScale) */ 1127 if (pSpecScale[i] > pSpecScale[0]) { 1128 pSpecScale[0] = pSpecScale[i]; 1129 } 1130 } 1131 1132 CConcealment_InterpolateBuffer( 1133 pSpectralCoefficient, /* spec_(n-1) */ 1134 &pConcealmentInfo->specScale[0], 1135 &pSpecScale[0], 1136 &specScaleOut, 1137 sfbEnergyPrev, 1138 sfbEnergyAct, 1139 scaleFactorBandsTotal, 1140 pSfbOffset); 1141 1142 pSpecScale[0] = specScaleOut; 1143 } 1144 } else { 1145 /* long--??????--short, long--??????--long interpolation */ 1146 /* long---long---short, long---long---long interpolation */ 1147 1148 int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1149 const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1150 SHORT specScaleAct = pConcealmentInfo->specScale[0]; 1151 1152 CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */ 1153 pSamplingRateInfo, 1154 OnlyLongSequence, 1155 CConcealment_NoExpand, 1156 sfbEnergyPrev); 1157 1158 if (pConcealmentInfo->windowSequence == EightShortSequence) { /* f_n == EightShortSequence */ 1159 /* long---long---short interpolation */ 1160 1161 pIcsInfo->WindowShape = 1; 1162 pIcsInfo->WindowSequence = LongStartSequence; 1163 1164 for (i = 1; i < 8; i++) { /* search for max(specScale) */ 1165 if (pConcealmentInfo->specScale[i] > specScaleAct) { 1166 specScaleAct = pConcealmentInfo->specScale[i]; 1167 } 1168 } 1169 1170 /* Expand first short spectrum */ 1171 CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ 1172 pSamplingRateInfo, 1173 EightShortSequence, 1174 CConcealment_Expand, /* !!! */ 1175 sfbEnergyAct); 1176 } else { 1177 /* long---long---long interpolation */ 1178 1179 pIcsInfo->WindowShape = 0; 1180 pIcsInfo->WindowSequence = OnlyLongSequence; 1181 1182 CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ 1183 pSamplingRateInfo, 1184 OnlyLongSequence, 1185 CConcealment_NoExpand, 1186 sfbEnergyAct); 1187 } 1188 1189 CConcealment_InterpolateBuffer( 1190 pSpectralCoefficient, /* spec_(n-1) */ 1191 &pSpecScale[0], 1192 &specScaleAct, 1193 &pSpecScale[0], 1194 sfbEnergyPrev, 1195 sfbEnergyAct, 1196 scaleFactorBandsTotal, 1197 pSfbOffset); 1198 1199 } 1200 } 1201 1202 /* Noise substitution of sign of the output spectral coefficients */ 1203 CConcealment_ApplyRandomSign (pConcealmentInfo->iRandomPhase, 1204 pSpectralCoefficient, 1205 samplesPerFrame); 1206 /* Increment random phase index to avoid repetition artifacts. */ 1207 pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); 1208 } 1209 1210 /* scale spectrum according to concealment state */ 1211 switch (pConcealmentInfo->concealState) 1212 { 1213 case ConcealState_Single: 1214 appliedProcessing = 1; 1215 break; 1216 1217 case ConcealState_FadeOut: 1218 { 1219 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 1220 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 1221 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeOutFrames); 1222 1223 /* restore frequency coefficients from buffer with a specific muting */ 1224 FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; 1225 FIXP_SGL fac = pConcealCommonData->fadeOutFactor[pConcealmentInfo->cntFadeFrames]; 1226 1227 for (i = samplesPerFrame; i != 0; i--) { 1228 *pOut = fMult(*pOut, fac); 1229 pOut--; 1230 } 1231 appliedProcessing = 1; 1232 } 1233 break; 1234 1235 case ConcealState_FadeIn: 1236 { 1237 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 1238 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 1239 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames); 1240 1241 /* attenuate signal to get a smooth fade-in */ 1242 FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; 1243 FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames]; 1244 1245 for (i = samplesPerFrame; i != 0; i--) { 1246 *pOut = fMult(*pOut, fac); 1247 pOut--; 1248 } 1249 appliedProcessing = 1; 1250 } 1251 break; 1252 1253 case ConcealState_Mute: 1254 { 1255 int fac = pConcealCommonData->comfortNoiseLevel; 1256 1257 /* set dummy window parameters */ 1258 pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ 1259 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape (required for F/T transform) */ 1260 pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); 1261 pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */ 1262 1263 /* mute spectral data */ 1264 FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); 1265 1266 if (fac >= 0 && fac <= 61) { 1267 /* insert comfort noise using PNS */ 1268 CConcealment_fakePnsData ( 1269 &pAacDecoderChannelInfo->data.aac.PnsData, 1270 pIcsInfo, 1271 pSamplingRateInfo, 1272 pAacDecoderChannelInfo->specScale, 1273 pAacDecoderChannelInfo->pDynData->aScaleFactor, 1274 fac 1275 ); 1276 1277 CPns_Apply ( 1278 &pAacDecoderChannelInfo->data.aac.PnsData, 1279 pIcsInfo, 1280 pAacDecoderChannelInfo->pSpectralCoefficient, 1281 pAacDecoderChannelInfo->specScale, 1282 pAacDecoderChannelInfo->pDynData->aScaleFactor, 1283 pSamplingRateInfo, 1284 pAacDecoderChannelInfo->granuleLength, 1285 0 /* always apply to first channel */ 1286 ); 1287 } 1288 appliedProcessing = 1; 1289 } 1290 break; 1291 1292 default: 1293 /* nothing to do here */ 1294 break; 1295 } 1296 1297 return appliedProcessing; 1298 } 1299 1300 1301 /*! 1302 \brief Calculate the spectral energy 1303 1304 The function calculates band-wise the spectral energy. This is used for 1305 frame interpolation. 1306 1307 \return none 1308 */ 1309 static void 1310 CConcealment_CalcBandEnergy ( 1311 FIXP_DBL *spectrum, 1312 const SamplingRateInfo *pSamplingRateInfo, 1313 const int blockType, 1314 CConcealmentExpandType expandType, 1315 int *sfbEnergy ) 1316 { 1317 const SHORT *pSfbOffset; 1318 int line, sfb, scaleFactorBandsTotal = 0; 1319 1320 /* In the following calculations, enAccu is initialized with LSB-value in order to avoid zero energy-level */ 1321 1322 line = 0; 1323 1324 switch(blockType) { 1325 1326 case OnlyLongSequence: 1327 case LongStartSequence: 1328 case LongStopSequence: 1329 1330 if (expandType == CConcealment_NoExpand) { 1331 /* standard long calculation */ 1332 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1333 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1334 1335 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1336 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1337 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1338 /* scaling depends on sfb width. */ 1339 for ( ; line < pSfbOffset[sfb+1]; line++) { 1340 enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; 1341 } 1342 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1343 } 1344 } 1345 else { 1346 /* compress long to short */ 1347 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short; 1348 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; 1349 1350 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1351 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1352 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1353 /* scaling depends on sfb width. */ 1354 for (; line < pSfbOffset[sfb+1] << 3; line++) { 1355 enAccu += (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3; 1356 } 1357 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1358 } 1359 } 1360 break; 1361 1362 case EightShortSequence: 1363 1364 if (expandType == CConcealment_NoExpand) { 1365 /* standard short calculation */ 1366 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short; 1367 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; 1368 1369 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1370 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1371 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1372 /* scaling depends on sfb width. */ 1373 for ( ; line < pSfbOffset[sfb+1]; line++) { 1374 enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; 1375 } 1376 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1377 } 1378 } 1379 else { 1380 /* expand short to long spectrum */ 1381 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1382 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1383 1384 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1385 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1386 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1387 /* scaling depends on sfb width. */ 1388 for ( ; line < pSfbOffset[sfb+1]; line++) { 1389 enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale; 1390 } 1391 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1392 } 1393 } 1394 break; 1395 } 1396 } 1397 1398 1399 /*! 1400 \brief Interpolate buffer 1401 1402 The function creates the interpolated spectral data according to the 1403 energy of the last good frame and the current (good) frame. 1404 1405 \return none 1406 */ 1407 static void 1408 CConcealment_InterpolateBuffer ( 1409 FIXP_DBL *spectrum, 1410 SHORT *pSpecScalePrv, 1411 SHORT *pSpecScaleAct, 1412 SHORT *pSpecScaleOut, 1413 int *enPrv, 1414 int *enAct, 1415 int sfbCnt, 1416 const SHORT *pSfbOffset ) 1417 { 1418 int sfb, line = 0; 1419 int fac_shift; 1420 int fac_mod; 1421 FIXP_DBL accu; 1422 1423 for (sfb = 0; sfb < sfbCnt; sfb++) { 1424 1425 fac_shift = enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1); 1426 fac_mod = fac_shift & 3; 1427 fac_shift = (fac_shift >> 2) + 1; 1428 fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct); 1429 1430 for (; line < pSfbOffset[sfb+1]; line++) { 1431 accu = fMult(*(spectrum+line), facMod4Table[fac_mod]); 1432 if (fac_shift < 0) { 1433 accu >>= -fac_shift; 1434 } else { 1435 accu <<= fac_shift; 1436 } 1437 *(spectrum+line) = accu; 1438 } 1439 } 1440 *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct); 1441 } 1442 1443 1444 1445 1446 static INT findEquiFadeFrame ( 1447 CConcealParams *pConcealCommonData, 1448 INT actFadeIndex, 1449 int direction ) 1450 { 1451 FIXP_SGL *pFactor; 1452 FIXP_SGL referenceVal; 1453 FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL; 1454 1455 INT numFrames = 0; 1456 INT nextFadeIndex = 0; 1457 1458 int i; 1459 1460 /* init depending on direction */ 1461 if (direction == 0) { /* FADE-OUT => FADE-IN */ 1462 numFrames = pConcealCommonData->numFadeInFrames; 1463 referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1; 1464 pFactor = pConcealCommonData->fadeInFactor; 1465 } 1466 else { /* FADE-IN => FADE-OUT */ 1467 numFrames = pConcealCommonData->numFadeOutFrames; 1468 referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1; 1469 pFactor = pConcealCommonData->fadeOutFactor; 1470 } 1471 1472 /* search for minimum difference */ 1473 for (i = 0; i < numFrames; i++) { 1474 FIXP_SGL diff = fixp_abs((pFactor[i]>>1) - referenceVal); 1475 if (diff < minDiff) { 1476 minDiff = diff; 1477 nextFadeIndex = i; 1478 } 1479 } 1480 1481 /* check and adjust depending on direction */ 1482 if (direction == 0) { /* FADE-OUT => FADE-IN */ 1483 if (((pFactor[nextFadeIndex]>>1) <= referenceVal) && (nextFadeIndex > 0)) { 1484 nextFadeIndex -= 1; 1485 } 1486 } 1487 else { /* FADE-IN => FADE-OUT */ 1488 if (((pFactor[nextFadeIndex]>>1) >= referenceVal) && (nextFadeIndex < numFrames-1)) { 1489 nextFadeIndex += 1; 1490 } 1491 } 1492 1493 return (nextFadeIndex); 1494 } 1495 1496 1497 /*! 1498 \brief Update the concealment state 1499 1500 The function updates the state of the concealment state-machine. The 1501 states are: mute, fade-in, fade-out, interpolate and frame-ok. 1502 1503 \return none 1504 */ 1505 static void 1506 CConcealment_UpdateState ( 1507 CConcealmentInfo *pConcealmentInfo, 1508 int frameOk ) 1509 { 1510 CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; 1511 1512 switch (pConcealCommonData->method) 1513 { 1514 case ConcealMethodNoise: 1515 { 1516 if (pConcealmentInfo->concealState != ConcealState_Ok) { 1517 /* count the valid frames during concealment process */ 1518 if (frameOk) { 1519 pConcealmentInfo->cntValidFrames += 1; 1520 } else { 1521 pConcealmentInfo->cntValidFrames = 0; 1522 } 1523 } 1524 1525 /* -- STATE MACHINE for Noise Substitution -- */ 1526 switch (pConcealmentInfo->concealState) 1527 { 1528 case ConcealState_Ok: 1529 if (!frameOk) { 1530 /* change to state SINGLE-FRAME-LOSS */ 1531 pConcealmentInfo->concealState = ConcealState_Single; 1532 pConcealmentInfo->cntFadeFrames = 0; 1533 pConcealmentInfo->cntValidFrames = 0; 1534 } 1535 break; 1536 1537 case ConcealState_Single: /* Just a pre-stage before fade-out begins. Stay here only one frame! */ 1538 pConcealmentInfo->cntFadeFrames += 1; 1539 if (frameOk) { 1540 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1541 /* change to state FADE-IN */ 1542 pConcealmentInfo->concealState = ConcealState_FadeIn; 1543 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1544 pConcealmentInfo->cntFadeFrames-1, 1545 0 /* FadeOut -> FadeIn */); 1546 } else { 1547 /* change to state OK */ 1548 pConcealmentInfo->concealState = ConcealState_Ok; 1549 } 1550 } else { 1551 if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { 1552 /* change to state MUTE */ 1553 pConcealmentInfo->concealState = ConcealState_Mute; 1554 } else { 1555 /* change to state FADE-OUT */ 1556 pConcealmentInfo->concealState = ConcealState_FadeOut; 1557 } 1558 } 1559 break; 1560 1561 case ConcealState_FadeOut: 1562 pConcealmentInfo->cntFadeFrames += 1; /* used to address the fade-out factors */ 1563 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1564 /* change to state FADE-IN */ 1565 pConcealmentInfo->concealState = ConcealState_FadeIn; 1566 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1567 pConcealmentInfo->cntFadeFrames-1, 1568 0 /* FadeOut -> FadeIn */); 1569 } else { 1570 if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { 1571 /* change to state MUTE */ 1572 pConcealmentInfo->concealState = ConcealState_Mute; 1573 } 1574 } 1575 break; 1576 1577 case ConcealState_Mute: 1578 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1579 /* change to state FADE-IN */ 1580 pConcealmentInfo->concealState = ConcealState_FadeIn; 1581 pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1; 1582 } 1583 break; 1584 1585 case ConcealState_FadeIn: 1586 pConcealmentInfo->cntFadeFrames -= 1; /* used to address the fade-in factors */ 1587 if (frameOk) { 1588 if (pConcealmentInfo->cntFadeFrames < 0) { 1589 /* change to state OK */ 1590 pConcealmentInfo->concealState = ConcealState_Ok; 1591 } 1592 } else { 1593 /* change to state FADE-OUT */ 1594 pConcealmentInfo->concealState = ConcealState_FadeOut; 1595 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1596 pConcealmentInfo->cntFadeFrames+1, 1597 1 /* FadeIn -> FadeOut */); 1598 } 1599 break; 1600 1601 default: 1602 FDK_ASSERT(0); 1603 break; 1604 } 1605 } 1606 break; 1607 1608 case ConcealMethodInter: 1609 case ConcealMethodTonal: 1610 { 1611 if (pConcealmentInfo->concealState != ConcealState_Ok) { 1612 /* count the valid frames during concealment process */ 1613 if ( pConcealmentInfo->prevFrameOk[1] || 1614 (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk) ) { 1615 /* The frame is OK even if it can be estimated by the energy interpolation algorithm */ 1616 pConcealmentInfo->cntValidFrames += 1; 1617 } else { 1618 pConcealmentInfo->cntValidFrames = 0; 1619 } 1620 } 1621 1622 /* -- STATE MACHINE for energy interpolation -- */ 1623 switch (pConcealmentInfo->concealState) 1624 { 1625 case ConcealState_Ok: 1626 if (!(pConcealmentInfo->prevFrameOk[1] || 1627 (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk))) { 1628 /* Fade out only if the energy interpolation algorithm can not be applied! */ 1629 pConcealmentInfo->concealState = ConcealState_FadeOut; 1630 pConcealmentInfo->cntFadeFrames = 0; 1631 pConcealmentInfo->cntValidFrames = 0; 1632 } 1633 break; 1634 1635 case ConcealState_Single: 1636 pConcealmentInfo->concealState = ConcealState_Ok; 1637 break; 1638 1639 case ConcealState_FadeOut: 1640 pConcealmentInfo->cntFadeFrames += 1; 1641 1642 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1643 /* change to state FADE-IN */ 1644 pConcealmentInfo->concealState = ConcealState_FadeIn; 1645 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1646 pConcealmentInfo->cntFadeFrames-1, 1647 0 /* FadeOut -> FadeIn */); 1648 } else { 1649 if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { 1650 /* change to state MUTE */ 1651 pConcealmentInfo->concealState = ConcealState_Mute; 1652 } 1653 } 1654 break; 1655 1656 case ConcealState_Mute: 1657 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1658 /* change to state FADE-IN */ 1659 pConcealmentInfo->concealState = ConcealState_FadeIn; 1660 pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1; 1661 } 1662 break; 1663 1664 case ConcealState_FadeIn: 1665 pConcealmentInfo->cntFadeFrames -= 1; /* used to address the fade-in factors */ 1666 1667 if (frameOk || pConcealmentInfo->prevFrameOk[1]) { 1668 if (pConcealmentInfo->cntFadeFrames < 0) { 1669 /* change to state OK */ 1670 pConcealmentInfo->concealState = ConcealState_Ok; 1671 } 1672 } else { 1673 /* change to state FADE-OUT */ 1674 pConcealmentInfo->concealState = ConcealState_FadeOut; 1675 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1676 pConcealmentInfo->cntFadeFrames+1, 1677 1 /* FadeIn -> FadeOut */); 1678 } 1679 break; 1680 } /* End switch(pConcealmentInfo->concealState) */ 1681 } 1682 break; 1683 1684 default: 1685 /* Don't need a state machine for other concealment methods. */ 1686 break; 1687 } 1688 1689 } 1690 1691 1692 /*! 1693 \brief Randomizes the sign of the spectral data 1694 1695 The function toggles the sign of the spectral data randomly. This is 1696 useful to ensure the quality of the concealed frames. 1697 1698 \return none 1699 */ 1700 static 1701 void CConcealment_ApplyRandomSign (int randomPhase, 1702 FIXP_DBL *spec, 1703 int samplesPerFrame 1704 ) 1705 { 1706 int i; 1707 USHORT packedSign=0; 1708 1709 /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit */ 1710 1711 /* read current packed sign word */ 1712 packedSign = randomSign[randomPhase>>4]; 1713 packedSign >>= (randomPhase&0xf); 1714 1715 for (i = 0; i < samplesPerFrame ; i++) { 1716 if ((randomPhase & 0xf) == 0) { 1717 packedSign = randomSign[randomPhase>>4]; 1718 } 1719 1720 if (packedSign & 0x1) { 1721 spec[i] = -spec[i]; 1722 } 1723 packedSign >>= 1; 1724 1725 randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); 1726 } 1727 } 1728 1729 1730 /*! 1731 \brief Get fadeing factor for current concealment state. 1732 1733 The function returns the factor used for fading that belongs to the current internal state. 1734 1735 \return Fade factor 1736 */ 1737 FIXP_DBL 1738 CConcealment_GetFadeFactor ( 1739 CConcealmentInfo *hConcealmentInfo, 1740 const int fPreviousFactor 1741 ) 1742 { 1743 FIXP_DBL fac = (FIXP_DBL)0; 1744 1745 CConcealParams *pConcealCommonData = hConcealmentInfo->pConcealParams; 1746 1747 if (hConcealmentInfo->pConcealParams->method > ConcealMethodMute) { 1748 switch (hConcealmentInfo->concealState) { 1749 default: 1750 case ConcealState_Mute: 1751 /* Nothing to do here */ 1752 break; 1753 case ConcealState_Ok: 1754 fac = (FIXP_DBL)MAXVAL_DBL; 1755 break; 1756 case ConcealState_Single: 1757 case ConcealState_FadeOut: 1758 { 1759 int idx = hConcealmentInfo->cntFadeFrames - ((fPreviousFactor != 0) ? 1 : 0); 1760 fac = (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(pConcealCommonData->fadeOutFactor[idx]); 1761 } 1762 break; 1763 case ConcealState_FadeIn: 1764 { 1765 int idx = hConcealmentInfo->cntFadeFrames + ((fPreviousFactor != 0) ? 1 : 0); 1766 fac = (idx >= hConcealmentInfo->pConcealParams->numFadeInFrames) ? (FIXP_DBL)0 : FX_SGL2FX_DBL(pConcealCommonData->fadeInFactor[idx]); 1767 } 1768 break; 1769 } 1770 } 1771 1772 return (fac); 1773 } 1774 1775 1776 /*! 1777 \brief Get fadeing factor for current concealment state. 1778 1779 The function returns the state (ok or not) of the previous frame. 1780 If called before the function CConcealment_Apply() set the fBeforeApply 1781 flag to get the correct value. 1782 1783 \return Frame OK flag of previous frame. 1784 */ 1785 int 1786 CConcealment_GetLastFrameOk ( 1787 CConcealmentInfo *hConcealmentInfo, 1788 const int fBeforeApply 1789 ) 1790 { 1791 int prevFrameOk = 1; 1792 1793 if (hConcealmentInfo != NULL) { 1794 prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1]; 1795 } 1796 1797 return prevFrameOk; 1798 } 1799 1800 /*! 1801 \brief Get the number of delay frames introduced by concealment technique. 1802 1803 \return Number of delay frames. 1804 */ 1805 UINT 1806 CConcealment_GetDelay ( 1807 CConcealParams *pConcealCommonData 1808 ) 1809 { 1810 UINT frameDelay = 0; 1811 1812 if (pConcealCommonData != NULL) { 1813 switch (pConcealCommonData->method) { 1814 case ConcealMethodTonal: 1815 case ConcealMethodInter: 1816 frameDelay = 1; 1817 break; 1818 default: 1819 break; 1820 } 1821 } 1822 1823 return frameDelay; 1824 } 1825 1826