1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2013 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 < -1) 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 { 766 /* Create data for signal rendering according to the selected concealment method and decoder operating mode. */ 767 768 769 if ( !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD 770 ) 771 ) 772 { 773 switch (hConcealmentInfo->pConcealParams->method) 774 { 775 default: 776 case ConcealMethodMute: 777 if (!frameOk) { 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 } 784 break; 785 786 case ConcealMethodNoise: 787 /* Noise substitution error concealment technique */ 788 appliedProcessing = 789 CConcealment_ApplyNoise (hConcealmentInfo, 790 pAacDecoderChannelInfo, 791 pAacDecoderStaticChannelInfo, 792 pSamplingRateInfo, 793 samplesPerFrame, 794 flags); 795 break; 796 797 case ConcealMethodInter: 798 /* Energy interpolation concealment based on 3GPP */ 799 appliedProcessing = 800 CConcealment_ApplyInter (hConcealmentInfo, 801 pAacDecoderChannelInfo, 802 pSamplingRateInfo, 803 samplesPerFrame, 804 0, /* don't use tonal improvement */ 805 frameOk); 806 break; 807 808 } 809 } 810 } 811 /* update history */ 812 hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1]; 813 hConcealmentInfo->prevFrameOk[1] = frameOk; 814 815 return appliedProcessing; 816 } 817 818 /*! 819 \brief Apply concealment noise substitution 820 821 In case of frame lost this function produces a noisy frame with respect to the 822 energies values of past frame. 823 824 \return none 825 */ 826 static int 827 CConcealment_ApplyNoise (CConcealmentInfo *pConcealmentInfo, 828 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 829 CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, 830 const SamplingRateInfo *pSamplingRateInfo, 831 const int samplesPerFrame, 832 const UINT flags) 833 { 834 CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; 835 836 FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); 837 SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; 838 CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; 839 840 int appliedProcessing = 0; 841 842 FDK_ASSERT((samplesPerFrame>=480) && (samplesPerFrame<=1024)); 843 FDK_ASSERT((samplesPerFrame&0x1F) == 0); 844 845 switch (pConcealmentInfo->concealState) 846 { 847 case ConcealState_Ok: 848 /* Nothing to do here! */ 849 break; 850 851 case ConcealState_Single: 852 case ConcealState_FadeOut: 853 { 854 /* restore frequency coefficients from buffer with a specific muting */ 855 FIXP_SGL fac; 856 int win, numWindows = 1; 857 int windowLen = samplesPerFrame; 858 int tFadeFrames, lastWindow = 0; 859 int win_idx_stride = 1; 860 861 FDK_ASSERT(pConcealmentInfo != NULL); 862 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 863 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 864 FDK_ASSERT(pConcealmentInfo->cntFadeFrames <= pConcealCommonData->numFadeOutFrames); 865 866 /* get attenuation factor */ 867 tFadeFrames = pConcealmentInfo->cntFadeFrames; 868 fac = pConcealCommonData->fadeOutFactor[tFadeFrames]; 869 870 /* set old window parameters */ 871 { 872 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; 873 pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; 874 875 if (pConcealmentInfo->windowSequence == 2) { 876 /* short block handling */ 877 numWindows = 8; 878 windowLen = samplesPerFrame >> 3; 879 lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen; 880 } 881 } 882 883 for (win = 0; win < numWindows; win++) { 884 FIXP_CNCL *pCncl = pConcealmentInfo->spectralCoefficient + (lastWindow * windowLen); 885 FIXP_DBL *pOut = pSpectralCoefficient + (win * windowLen); 886 int i; 887 888 FDK_ASSERT((lastWindow * windowLen + windowLen) <= samplesPerFrame); 889 890 /* restore frequency coefficients from buffer with a specific attenuation */ 891 for (i = 0; i < windowLen; i++) { 892 pOut[i] = fMult(pCncl[i], fac); 893 } 894 895 /* apply random change of sign for spectral coefficients */ 896 CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, 897 pOut, 898 windowLen ); 899 900 /* Increment random phase index to avoid repetition artifacts. */ 901 pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); 902 903 /* set old scale factors */ 904 pSpecScale[win*win_idx_stride] = pConcealmentInfo->specScale[win_idx_stride*lastWindow++]; 905 906 if ( (lastWindow >= numWindows) 907 && (numWindows > 1) ) 908 { 909 /* end of sequence -> rewind */ 910 lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen; 911 /* update the attenuation factor to get a faster fade-out */ 912 tFadeFrames += 1; 913 if (tFadeFrames < pConcealCommonData->numFadeOutFrames) { 914 fac = pConcealCommonData->fadeOutFactor[tFadeFrames]; 915 } else { 916 fac = (FIXP_SGL)0; 917 } 918 } 919 } 920 921 /* store temp vars */ 922 pConcealmentInfo->cntFadeFrames = tFadeFrames; 923 appliedProcessing = 1; 924 } 925 break; 926 927 case ConcealState_Mute: 928 { 929 /* set dummy window parameters */ 930 pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ 931 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape (required for F/T transform) */ 932 pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); 933 pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */ 934 935 /* mute spectral data */ 936 FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); 937 938 if ( !(flags & (AC_USAC|AC_RSVD50)) 939 && pConcealCommonData->comfortNoiseLevel >= 0 940 && pConcealCommonData->comfortNoiseLevel <= 61 /* -90dB */) 941 { 942 /* insert comfort noise using PNS */ 943 CConcealment_fakePnsData ( 944 &pAacDecoderChannelInfo->data.aac.PnsData, 945 pIcsInfo, 946 pSamplingRateInfo, 947 pAacDecoderChannelInfo->pDynData->aSfbScale, 948 pAacDecoderChannelInfo->pDynData->aScaleFactor, 949 pConcealCommonData->comfortNoiseLevel 950 ); 951 952 CPns_Apply ( 953 &pAacDecoderChannelInfo->data.aac.PnsData, 954 pIcsInfo, 955 pAacDecoderChannelInfo->pSpectralCoefficient, 956 pAacDecoderChannelInfo->specScale, 957 pAacDecoderChannelInfo->pDynData->aScaleFactor, 958 pSamplingRateInfo, 959 pAacDecoderChannelInfo->granuleLength, 960 0 /* always apply to first channel */ 961 ); 962 } 963 appliedProcessing = 1; 964 } 965 break; 966 967 case ConcealState_FadeIn: 968 { 969 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 970 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 971 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames); 972 973 /* attenuate signal to get a smooth fade-in */ 974 FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; 975 FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames]; 976 int i; 977 978 for (i = samplesPerFrame; i != 0; i--) { 979 *pOut = fMult(*pOut, fac); 980 pOut--; 981 } 982 appliedProcessing = 1; 983 } 984 break; 985 986 default: 987 /* we shouldn't come here anyway */ 988 FDK_ASSERT(0); 989 break; 990 } 991 992 return appliedProcessing; 993 } 994 995 996 /*! 997 \brief Apply concealment interpolation 998 999 The function swaps the data from the current and the previous frame. If an 1000 error has occured, frame interpolation is performed to restore the missing 1001 frame. In case of multiple faulty frames, fade-in and fade-out is applied. 1002 1003 \return none 1004 */ 1005 static int 1006 CConcealment_ApplyInter ( 1007 CConcealmentInfo *pConcealmentInfo, 1008 CAacDecoderChannelInfo *pAacDecoderChannelInfo, 1009 const SamplingRateInfo *pSamplingRateInfo, 1010 const int samplesPerFrame, 1011 const int improveTonal, 1012 const int frameOk ) 1013 { 1014 CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; 1015 1016 FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); 1017 CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; 1018 SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; 1019 1020 1021 int sfbEnergyPrev[64]; 1022 int sfbEnergyAct [64]; 1023 1024 int i, appliedProcessing = 0; 1025 1026 /* clear/init */ 1027 FDKmemclear(sfbEnergyPrev, 64 * sizeof(int)); 1028 FDKmemclear(sfbEnergyAct, 64 * sizeof(int)); 1029 1030 1031 if (!frameOk) 1032 { 1033 /* Restore last frame from concealment buffer */ 1034 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; 1035 pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; 1036 1037 /* Restore spectral data */ 1038 for (i = 0; i < samplesPerFrame; i++) { 1039 pSpectralCoefficient[i] = FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]); 1040 } 1041 1042 /* Restore scale factors */ 1043 FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8*sizeof(SHORT)); 1044 } 1045 1046 /* if previous frame was not ok */ 1047 if (!pConcealmentInfo->prevFrameOk[1]) { 1048 1049 /* if current frame (f_n) is ok and the last but one frame (f_(n-2)) 1050 was ok, too, then interpolate both frames in order to generate 1051 the current output frame (f_(n-1)). Otherwise, use the last stored 1052 frame (f_(n-2) or f_(n-3) or ...). */ 1053 if (frameOk && pConcealmentInfo->prevFrameOk[0]) 1054 { 1055 appliedProcessing = 1; 1056 1057 1058 /* Interpolate both frames in order to generate the current output frame (f_(n-1)). */ 1059 if (pIcsInfo->WindowSequence == EightShortSequence) { 1060 /* f_(n-2) == EightShortSequence */ 1061 /* short--??????--short, short--??????--long interpolation */ 1062 /* short--short---short, short---long---long interpolation */ 1063 1064 int wnd; 1065 1066 if (pConcealmentInfo->windowSequence == EightShortSequence) { /* f_n == EightShortSequence */ 1067 /* short--short---short interpolation */ 1068 1069 int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short; 1070 const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; 1071 pIcsInfo->WindowShape = 1; 1072 pIcsInfo->WindowSequence = EightShortSequence; 1073 1074 for (wnd = 0; wnd < 8; wnd++) 1075 { 1076 CConcealment_CalcBandEnergy( 1077 &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-2) */ 1078 pSamplingRateInfo, 1079 EightShortSequence, 1080 CConcealment_NoExpand, 1081 sfbEnergyPrev); 1082 1083 CConcealment_CalcBandEnergy( 1084 &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_n */ 1085 pSamplingRateInfo, 1086 EightShortSequence, 1087 CConcealment_NoExpand, 1088 sfbEnergyAct); 1089 1090 CConcealment_InterpolateBuffer( 1091 &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-1) */ 1092 &pSpecScale[wnd], 1093 &pConcealmentInfo->specScale[wnd], 1094 &pSpecScale[wnd], 1095 sfbEnergyPrev, 1096 sfbEnergyAct, 1097 scaleFactorBandsTotal, 1098 pSfbOffset); 1099 1100 } 1101 } else { /* f_n != EightShortSequence */ 1102 /* short---long---long interpolation */ 1103 1104 int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1105 const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1106 SHORT specScaleOut; 1107 1108 CConcealment_CalcBandEnergy(&pSpectralCoefficient[samplesPerFrame - (samplesPerFrame / 8)], /* [wnd] spec_(n-2) */ 1109 pSamplingRateInfo, 1110 EightShortSequence, 1111 CConcealment_Expand, 1112 sfbEnergyAct); 1113 1114 CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ 1115 pSamplingRateInfo, 1116 OnlyLongSequence, 1117 CConcealment_NoExpand, 1118 sfbEnergyPrev); 1119 1120 pIcsInfo->WindowShape = 0; 1121 pIcsInfo->WindowSequence = LongStopSequence; 1122 1123 for (i = 0; i < samplesPerFrame ; i++) { 1124 pSpectralCoefficient[i] = pConcealmentInfo->spectralCoefficient[i]; /* spec_n */ 1125 } 1126 1127 for (i = 0; i < 8; i++) { /* search for max(specScale) */ 1128 if (pSpecScale[i] > pSpecScale[0]) { 1129 pSpecScale[0] = pSpecScale[i]; 1130 } 1131 } 1132 1133 CConcealment_InterpolateBuffer( 1134 pSpectralCoefficient, /* spec_(n-1) */ 1135 &pConcealmentInfo->specScale[0], 1136 &pSpecScale[0], 1137 &specScaleOut, 1138 sfbEnergyPrev, 1139 sfbEnergyAct, 1140 scaleFactorBandsTotal, 1141 pSfbOffset); 1142 1143 pSpecScale[0] = specScaleOut; 1144 } 1145 } else { 1146 /* long--??????--short, long--??????--long interpolation */ 1147 /* long---long---short, long---long---long interpolation */ 1148 1149 int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1150 const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1151 SHORT specScaleAct = pConcealmentInfo->specScale[0]; 1152 1153 CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */ 1154 pSamplingRateInfo, 1155 OnlyLongSequence, 1156 CConcealment_NoExpand, 1157 sfbEnergyPrev); 1158 1159 if (pConcealmentInfo->windowSequence == EightShortSequence) { /* f_n == EightShortSequence */ 1160 /* long---long---short interpolation */ 1161 1162 pIcsInfo->WindowShape = 1; 1163 pIcsInfo->WindowSequence = LongStartSequence; 1164 1165 for (i = 1; i < 8; i++) { /* search for max(specScale) */ 1166 if (pConcealmentInfo->specScale[i] > specScaleAct) { 1167 specScaleAct = pConcealmentInfo->specScale[i]; 1168 } 1169 } 1170 1171 /* Expand first short spectrum */ 1172 CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ 1173 pSamplingRateInfo, 1174 EightShortSequence, 1175 CConcealment_Expand, /* !!! */ 1176 sfbEnergyAct); 1177 } else { 1178 /* long---long---long interpolation */ 1179 1180 pIcsInfo->WindowShape = 0; 1181 pIcsInfo->WindowSequence = OnlyLongSequence; 1182 1183 CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ 1184 pSamplingRateInfo, 1185 OnlyLongSequence, 1186 CConcealment_NoExpand, 1187 sfbEnergyAct); 1188 } 1189 1190 CConcealment_InterpolateBuffer( 1191 pSpectralCoefficient, /* spec_(n-1) */ 1192 &pSpecScale[0], 1193 &specScaleAct, 1194 &pSpecScale[0], 1195 sfbEnergyPrev, 1196 sfbEnergyAct, 1197 scaleFactorBandsTotal, 1198 pSfbOffset); 1199 1200 } 1201 } 1202 1203 /* Noise substitution of sign of the output spectral coefficients */ 1204 CConcealment_ApplyRandomSign (pConcealmentInfo->iRandomPhase, 1205 pSpectralCoefficient, 1206 samplesPerFrame); 1207 /* Increment random phase index to avoid repetition artifacts. */ 1208 pConcealmentInfo->iRandomPhase = (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); 1209 } 1210 1211 /* scale spectrum according to concealment state */ 1212 switch (pConcealmentInfo->concealState) 1213 { 1214 case ConcealState_Single: 1215 appliedProcessing = 1; 1216 break; 1217 1218 case ConcealState_FadeOut: 1219 { 1220 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 1221 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 1222 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeOutFrames); 1223 1224 /* restore frequency coefficients from buffer with a specific muting */ 1225 FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; 1226 FIXP_SGL fac = pConcealCommonData->fadeOutFactor[pConcealmentInfo->cntFadeFrames]; 1227 1228 for (i = samplesPerFrame; i != 0; i--) { 1229 *pOut = fMult(*pOut, fac); 1230 pOut--; 1231 } 1232 appliedProcessing = 1; 1233 } 1234 break; 1235 1236 case ConcealState_FadeIn: 1237 { 1238 FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); 1239 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); 1240 FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames); 1241 1242 /* attenuate signal to get a smooth fade-in */ 1243 FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; 1244 FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames]; 1245 1246 for (i = samplesPerFrame; i != 0; i--) { 1247 *pOut = fMult(*pOut, fac); 1248 pOut--; 1249 } 1250 appliedProcessing = 1; 1251 } 1252 break; 1253 1254 case ConcealState_Mute: 1255 { 1256 int fac = pConcealCommonData->comfortNoiseLevel; 1257 1258 /* set dummy window parameters */ 1259 pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */ 1260 pIcsInfo->WindowShape = pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape (required for F/T transform) */ 1261 pIcsInfo->WindowSequence = CConcealment_GetWinSeq(pConcealmentInfo->windowSequence); 1262 pConcealmentInfo->windowSequence = pIcsInfo->WindowSequence; /* Store for next frame (spectrum in concealment buffer can't be used at all) */ 1263 1264 /* mute spectral data */ 1265 FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); 1266 1267 if (fac >= 0 && fac <= 61) { 1268 /* insert comfort noise using PNS */ 1269 CConcealment_fakePnsData ( 1270 &pAacDecoderChannelInfo->data.aac.PnsData, 1271 pIcsInfo, 1272 pSamplingRateInfo, 1273 pAacDecoderChannelInfo->specScale, 1274 pAacDecoderChannelInfo->pDynData->aScaleFactor, 1275 fac 1276 ); 1277 1278 CPns_Apply ( 1279 &pAacDecoderChannelInfo->data.aac.PnsData, 1280 pIcsInfo, 1281 pAacDecoderChannelInfo->pSpectralCoefficient, 1282 pAacDecoderChannelInfo->specScale, 1283 pAacDecoderChannelInfo->pDynData->aScaleFactor, 1284 pSamplingRateInfo, 1285 pAacDecoderChannelInfo->granuleLength, 1286 0 /* always apply to first channel */ 1287 ); 1288 } 1289 appliedProcessing = 1; 1290 } 1291 break; 1292 1293 default: 1294 /* nothing to do here */ 1295 break; 1296 } 1297 1298 return appliedProcessing; 1299 } 1300 1301 1302 /*! 1303 \brief Calculate the spectral energy 1304 1305 The function calculates band-wise the spectral energy. This is used for 1306 frame interpolation. 1307 1308 \return none 1309 */ 1310 static void 1311 CConcealment_CalcBandEnergy ( 1312 FIXP_DBL *spectrum, 1313 const SamplingRateInfo *pSamplingRateInfo, 1314 const int blockType, 1315 CConcealmentExpandType expandType, 1316 int *sfbEnergy ) 1317 { 1318 const SHORT *pSfbOffset; 1319 int line, sfb, scaleFactorBandsTotal = 0; 1320 1321 /* In the following calculations, enAccu is initialized with LSB-value in order to avoid zero energy-level */ 1322 1323 line = 0; 1324 1325 switch(blockType) { 1326 1327 case OnlyLongSequence: 1328 case LongStartSequence: 1329 case LongStopSequence: 1330 1331 if (expandType == CConcealment_NoExpand) { 1332 /* standard long calculation */ 1333 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1334 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1335 1336 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1337 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1338 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1339 /* scaling depends on sfb width. */ 1340 for ( ; line < pSfbOffset[sfb+1]; line++) { 1341 enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; 1342 } 1343 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1344 } 1345 } 1346 else { 1347 /* compress long to short */ 1348 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short; 1349 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; 1350 1351 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1352 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1353 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1354 /* scaling depends on sfb width. */ 1355 for (; line < pSfbOffset[sfb+1] << 3; line++) { 1356 enAccu += (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3; 1357 } 1358 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1359 } 1360 } 1361 break; 1362 1363 case EightShortSequence: 1364 1365 if (expandType == CConcealment_NoExpand) { 1366 /* standard short calculation */ 1367 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short; 1368 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; 1369 1370 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1371 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1372 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1373 /* scaling depends on sfb width. */ 1374 for ( ; line < pSfbOffset[sfb+1]; line++) { 1375 enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale; 1376 } 1377 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1378 } 1379 } 1380 else { 1381 /* expand short to long spectrum */ 1382 scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; 1383 pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; 1384 1385 for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) { 1386 FIXP_DBL enAccu = (FIXP_DBL)(LONG)1; 1387 int sfbScale = (sizeof(LONG)<<3) - CntLeadingZeros(pSfbOffset[sfb+1] - pSfbOffset[sfb]) - 1; 1388 /* scaling depends on sfb width. */ 1389 for ( ; line < pSfbOffset[sfb+1]; line++) { 1390 enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale; 1391 } 1392 *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; 1393 } 1394 } 1395 break; 1396 } 1397 } 1398 1399 1400 /*! 1401 \brief Interpolate buffer 1402 1403 The function creates the interpolated spectral data according to the 1404 energy of the last good frame and the current (good) frame. 1405 1406 \return none 1407 */ 1408 static void 1409 CConcealment_InterpolateBuffer ( 1410 FIXP_DBL *spectrum, 1411 SHORT *pSpecScalePrv, 1412 SHORT *pSpecScaleAct, 1413 SHORT *pSpecScaleOut, 1414 int *enPrv, 1415 int *enAct, 1416 int sfbCnt, 1417 const SHORT *pSfbOffset ) 1418 { 1419 int sfb, line = 0; 1420 int fac_shift; 1421 int fac_mod; 1422 FIXP_DBL accu; 1423 1424 for (sfb = 0; sfb < sfbCnt; sfb++) { 1425 1426 fac_shift = enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1); 1427 fac_mod = fac_shift & 3; 1428 fac_shift = (fac_shift >> 2) + 1; 1429 fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct); 1430 1431 for (; line < pSfbOffset[sfb+1]; line++) { 1432 accu = fMult(*(spectrum+line), facMod4Table[fac_mod]); 1433 if (fac_shift < 0) { 1434 accu >>= -fac_shift; 1435 } else { 1436 accu <<= fac_shift; 1437 } 1438 *(spectrum+line) = accu; 1439 } 1440 } 1441 *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct); 1442 } 1443 1444 1445 1446 1447 static INT findEquiFadeFrame ( 1448 CConcealParams *pConcealCommonData, 1449 INT actFadeIndex, 1450 int direction ) 1451 { 1452 FIXP_SGL *pFactor; 1453 FIXP_SGL referenceVal; 1454 FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL; 1455 1456 INT numFrames = 0; 1457 INT nextFadeIndex = 0; 1458 1459 int i; 1460 1461 /* init depending on direction */ 1462 if (direction == 0) { /* FADE-OUT => FADE-IN */ 1463 numFrames = pConcealCommonData->numFadeInFrames; 1464 referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1; 1465 pFactor = pConcealCommonData->fadeInFactor; 1466 } 1467 else { /* FADE-IN => FADE-OUT */ 1468 numFrames = pConcealCommonData->numFadeOutFrames; 1469 referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1; 1470 pFactor = pConcealCommonData->fadeOutFactor; 1471 } 1472 1473 /* search for minimum difference */ 1474 for (i = 0; i < numFrames; i++) { 1475 FIXP_SGL diff = fixp_abs((pFactor[i]>>1) - referenceVal); 1476 if (diff < minDiff) { 1477 minDiff = diff; 1478 nextFadeIndex = i; 1479 } 1480 } 1481 1482 /* check and adjust depending on direction */ 1483 if (direction == 0) { /* FADE-OUT => FADE-IN */ 1484 if (((pFactor[nextFadeIndex]>>1) <= referenceVal) && (nextFadeIndex > 0)) { 1485 nextFadeIndex -= 1; 1486 } 1487 } 1488 else { /* FADE-IN => FADE-OUT */ 1489 if (((pFactor[nextFadeIndex]>>1) >= referenceVal) && (nextFadeIndex < numFrames-1)) { 1490 nextFadeIndex += 1; 1491 } 1492 } 1493 1494 return (nextFadeIndex); 1495 } 1496 1497 1498 /*! 1499 \brief Update the concealment state 1500 1501 The function updates the state of the concealment state-machine. The 1502 states are: mute, fade-in, fade-out, interpolate and frame-ok. 1503 1504 \return none 1505 */ 1506 static void 1507 CConcealment_UpdateState ( 1508 CConcealmentInfo *pConcealmentInfo, 1509 int frameOk ) 1510 { 1511 CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; 1512 1513 switch (pConcealCommonData->method) 1514 { 1515 case ConcealMethodNoise: 1516 { 1517 if (pConcealmentInfo->concealState != ConcealState_Ok) { 1518 /* count the valid frames during concealment process */ 1519 if (frameOk) { 1520 pConcealmentInfo->cntValidFrames += 1; 1521 } else { 1522 pConcealmentInfo->cntValidFrames = 0; 1523 } 1524 } 1525 1526 /* -- STATE MACHINE for Noise Substitution -- */ 1527 switch (pConcealmentInfo->concealState) 1528 { 1529 case ConcealState_Ok: 1530 if (!frameOk) { 1531 if (pConcealCommonData->numFadeOutFrames > 0) { 1532 /* change to state SINGLE-FRAME-LOSS */ 1533 pConcealmentInfo->concealState = ConcealState_Single; 1534 } else { 1535 /* change to state MUTE */ 1536 pConcealmentInfo->concealState = ConcealState_Mute; 1537 } 1538 pConcealmentInfo->cntFadeFrames = 0; 1539 pConcealmentInfo->cntValidFrames = 0; 1540 } 1541 break; 1542 1543 case ConcealState_Single: /* Just a pre-stage before fade-out begins. Stay here only one frame! */ 1544 pConcealmentInfo->cntFadeFrames += 1; 1545 if (frameOk) { 1546 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1547 /* change to state FADE-IN */ 1548 pConcealmentInfo->concealState = ConcealState_FadeIn; 1549 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1550 pConcealmentInfo->cntFadeFrames-1, 1551 0 /* FadeOut -> FadeIn */); 1552 } else { 1553 /* change to state OK */ 1554 pConcealmentInfo->concealState = ConcealState_Ok; 1555 } 1556 } else { 1557 if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { 1558 /* change to state MUTE */ 1559 pConcealmentInfo->concealState = ConcealState_Mute; 1560 } else { 1561 /* change to state FADE-OUT */ 1562 pConcealmentInfo->concealState = ConcealState_FadeOut; 1563 } 1564 } 1565 break; 1566 1567 case ConcealState_FadeOut: 1568 pConcealmentInfo->cntFadeFrames += 1; /* used to address the fade-out factors */ 1569 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1570 if (pConcealCommonData->numFadeInFrames > 0) { 1571 /* change to state FADE-IN */ 1572 pConcealmentInfo->concealState = ConcealState_FadeIn; 1573 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1574 pConcealmentInfo->cntFadeFrames-1, 1575 0 /* FadeOut -> FadeIn */); 1576 } else { 1577 /* change to state OK */ 1578 pConcealmentInfo->concealState = ConcealState_Ok; 1579 } 1580 } else { 1581 if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { 1582 /* change to state MUTE */ 1583 pConcealmentInfo->concealState = ConcealState_Mute; 1584 } 1585 } 1586 break; 1587 1588 case ConcealState_Mute: 1589 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1590 if (pConcealCommonData->numFadeInFrames > 0) { 1591 /* change to state FADE-IN */ 1592 pConcealmentInfo->concealState = ConcealState_FadeIn; 1593 pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1; 1594 } else { 1595 /* change to state OK */ 1596 pConcealmentInfo->concealState = ConcealState_Ok; 1597 } 1598 } 1599 break; 1600 1601 case ConcealState_FadeIn: 1602 pConcealmentInfo->cntFadeFrames -= 1; /* used to address the fade-in factors */ 1603 if (frameOk) { 1604 if (pConcealmentInfo->cntFadeFrames < 0) { 1605 /* change to state OK */ 1606 pConcealmentInfo->concealState = ConcealState_Ok; 1607 } 1608 } else { 1609 if (pConcealCommonData->numFadeOutFrames > 0) { 1610 /* change to state FADE-OUT */ 1611 pConcealmentInfo->concealState = ConcealState_FadeOut; 1612 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1613 pConcealmentInfo->cntFadeFrames+1, 1614 1 /* FadeIn -> FadeOut */); 1615 } else { 1616 /* change to state MUTE */ 1617 pConcealmentInfo->concealState = ConcealState_Mute; 1618 } 1619 } 1620 break; 1621 1622 default: 1623 FDK_ASSERT(0); 1624 break; 1625 } 1626 } 1627 break; 1628 1629 case ConcealMethodInter: 1630 case ConcealMethodTonal: 1631 { 1632 if (pConcealmentInfo->concealState != ConcealState_Ok) { 1633 /* count the valid frames during concealment process */ 1634 if ( pConcealmentInfo->prevFrameOk[1] || 1635 (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk) ) { 1636 /* The frame is OK even if it can be estimated by the energy interpolation algorithm */ 1637 pConcealmentInfo->cntValidFrames += 1; 1638 } else { 1639 pConcealmentInfo->cntValidFrames = 0; 1640 } 1641 } 1642 1643 /* -- STATE MACHINE for energy interpolation -- */ 1644 switch (pConcealmentInfo->concealState) 1645 { 1646 case ConcealState_Ok: 1647 if (!(pConcealmentInfo->prevFrameOk[1] || 1648 (pConcealmentInfo->prevFrameOk[0] && !pConcealmentInfo->prevFrameOk[1] && frameOk))) { 1649 if (pConcealCommonData->numFadeOutFrames > 0) { 1650 /* Fade out only if the energy interpolation algorithm can not be applied! */ 1651 pConcealmentInfo->concealState = ConcealState_FadeOut; 1652 } else { 1653 /* change to state MUTE */ 1654 pConcealmentInfo->concealState = ConcealState_Mute; 1655 } 1656 pConcealmentInfo->cntFadeFrames = 0; 1657 pConcealmentInfo->cntValidFrames = 0; 1658 } 1659 break; 1660 1661 case ConcealState_Single: 1662 pConcealmentInfo->concealState = ConcealState_Ok; 1663 break; 1664 1665 case ConcealState_FadeOut: 1666 pConcealmentInfo->cntFadeFrames += 1; 1667 1668 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1669 if (pConcealCommonData->numFadeInFrames > 0) { 1670 /* change to state FADE-IN */ 1671 pConcealmentInfo->concealState = ConcealState_FadeIn; 1672 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1673 pConcealmentInfo->cntFadeFrames-1, 1674 0 /* FadeOut -> FadeIn */); 1675 } else { 1676 /* change to state OK */ 1677 pConcealmentInfo->concealState = ConcealState_Ok; 1678 } 1679 } else { 1680 if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { 1681 /* change to state MUTE */ 1682 pConcealmentInfo->concealState = ConcealState_Mute; 1683 } 1684 } 1685 break; 1686 1687 case ConcealState_Mute: 1688 if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { 1689 if (pConcealCommonData->numFadeInFrames > 0) { 1690 /* change to state FADE-IN */ 1691 pConcealmentInfo->concealState = ConcealState_FadeIn; 1692 pConcealmentInfo->cntFadeFrames = pConcealCommonData->numFadeInFrames - 1; 1693 } else { 1694 /* change to state OK */ 1695 pConcealmentInfo->concealState = ConcealState_Ok; 1696 } 1697 } 1698 break; 1699 1700 case ConcealState_FadeIn: 1701 pConcealmentInfo->cntFadeFrames -= 1; /* used to address the fade-in factors */ 1702 1703 if (frameOk || pConcealmentInfo->prevFrameOk[1]) { 1704 if (pConcealmentInfo->cntFadeFrames < 0) { 1705 /* change to state OK */ 1706 pConcealmentInfo->concealState = ConcealState_Ok; 1707 } 1708 } else { 1709 if (pConcealCommonData->numFadeOutFrames > 0) { 1710 /* change to state FADE-OUT */ 1711 pConcealmentInfo->concealState = ConcealState_FadeOut; 1712 pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, 1713 pConcealmentInfo->cntFadeFrames+1, 1714 1 /* FadeIn -> FadeOut */); 1715 } else { 1716 /* change to state MUTE */ 1717 pConcealmentInfo->concealState = ConcealState_Mute; 1718 } 1719 } 1720 break; 1721 } /* End switch(pConcealmentInfo->concealState) */ 1722 } 1723 break; 1724 1725 default: 1726 /* Don't need a state machine for other concealment methods. */ 1727 break; 1728 } 1729 1730 } 1731 1732 1733 /*! 1734 \brief Randomizes the sign of the spectral data 1735 1736 The function toggles the sign of the spectral data randomly. This is 1737 useful to ensure the quality of the concealed frames. 1738 1739 \return none 1740 */ 1741 static 1742 void CConcealment_ApplyRandomSign (int randomPhase, 1743 FIXP_DBL *spec, 1744 int samplesPerFrame 1745 ) 1746 { 1747 int i; 1748 USHORT packedSign=0; 1749 1750 /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit */ 1751 1752 /* read current packed sign word */ 1753 packedSign = randomSign[randomPhase>>4]; 1754 packedSign >>= (randomPhase&0xf); 1755 1756 for (i = 0; i < samplesPerFrame ; i++) { 1757 if ((randomPhase & 0xf) == 0) { 1758 packedSign = randomSign[randomPhase>>4]; 1759 } 1760 1761 if (packedSign & 0x1) { 1762 spec[i] = -spec[i]; 1763 } 1764 packedSign >>= 1; 1765 1766 randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1); 1767 } 1768 } 1769 1770 1771 /*! 1772 \brief Get fadeing factor for current concealment state. 1773 1774 The function returns the factor used for fading that belongs to the current internal state. 1775 1776 \return Fade factor 1777 */ 1778 FIXP_DBL 1779 CConcealment_GetFadeFactor ( 1780 CConcealmentInfo *hConcealmentInfo, 1781 const int fPreviousFactor 1782 ) 1783 { 1784 FIXP_DBL fac = (FIXP_DBL)0; 1785 1786 CConcealParams *pConcealCommonData = hConcealmentInfo->pConcealParams; 1787 1788 if (hConcealmentInfo->pConcealParams->method > ConcealMethodMute) { 1789 switch (hConcealmentInfo->concealState) { 1790 default: 1791 case ConcealState_Mute: 1792 /* Nothing to do here */ 1793 break; 1794 case ConcealState_Ok: 1795 fac = (FIXP_DBL)MAXVAL_DBL; 1796 break; 1797 case ConcealState_Single: 1798 case ConcealState_FadeOut: 1799 { 1800 int idx = hConcealmentInfo->cntFadeFrames - ((fPreviousFactor != 0) ? 1 : 0); 1801 fac = (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(pConcealCommonData->fadeOutFactor[idx]); 1802 } 1803 break; 1804 case ConcealState_FadeIn: 1805 { 1806 int idx = hConcealmentInfo->cntFadeFrames + ((fPreviousFactor != 0) ? 1 : 0); 1807 fac = (idx >= hConcealmentInfo->pConcealParams->numFadeInFrames) ? (FIXP_DBL)0 : FX_SGL2FX_DBL(pConcealCommonData->fadeInFactor[idx]); 1808 } 1809 break; 1810 } 1811 } 1812 1813 return (fac); 1814 } 1815 1816 1817 /*! 1818 \brief Get fadeing factor for current concealment state. 1819 1820 The function returns the state (ok or not) of the previous frame. 1821 If called before the function CConcealment_Apply() set the fBeforeApply 1822 flag to get the correct value. 1823 1824 \return Frame OK flag of previous frame. 1825 */ 1826 int 1827 CConcealment_GetLastFrameOk ( 1828 CConcealmentInfo *hConcealmentInfo, 1829 const int fBeforeApply 1830 ) 1831 { 1832 int prevFrameOk = 1; 1833 1834 if (hConcealmentInfo != NULL) { 1835 prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1]; 1836 } 1837 1838 return prevFrameOk; 1839 } 1840 1841 /*! 1842 \brief Get the number of delay frames introduced by concealment technique. 1843 1844 \return Number of delay frames. 1845 */ 1846 UINT 1847 CConcealment_GetDelay ( 1848 CConcealParams *pConcealCommonData 1849 ) 1850 { 1851 UINT frameDelay = 0; 1852 1853 if (pConcealCommonData != NULL) { 1854 switch (pConcealCommonData->method) { 1855 case ConcealMethodTonal: 1856 case ConcealMethodInter: 1857 frameDelay = 1; 1858 break; 1859 default: 1860 break; 1861 } 1862 } 1863 1864 return frameDelay; 1865 } 1866 1867