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