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