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