/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:

You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.

You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------- */

/**************************** AAC decoder library ******************************

   Author(s):   Josef Hoepfl

   Description: independent channel concealment

*******************************************************************************/

/*!
  \page concealment AAC core concealment

  This AAC core implementation includes a concealment function, which can be
  enabled using the several defines during compilation.

  There are various tests inside the core, starting with simple CRC tests and
  ending in a variety of plausibility checks. If such a check indicates an
  invalid bitstream, then concealment is applied.

  Concealment is also applied when the calling main program indicates a
  distorted or missing data frame using the frameOK flag. This is used for error
  detection on the transport layer. (See below)

  There are three concealment-modes:

  1) Muting: The spectral data is simply set to zero in case of an detected
  error.

  2) Noise substitution: In case of an detected error, concealment copies the
  last frame and adds attenuates the spectral data. For this mode you have to
  set the #CONCEAL_NOISE define. Noise substitution adds no additional delay.

  3) Interpolation: The interpolation routine swaps the spectral data from the
  previous and the current frame just before the final frequency to time
  conversion. In case a single frame is corrupted, concealmant interpolates
  between the last good and the first good frame to create the spectral data for
  the missing frame. If multiple frames are corrupted, concealment implements
  first a fade out based on slightly modified spectral values from the last good
     frame. As soon as good frames are available, concealmant fades in the new
  spectral data. For this mode you have to set the #CONCEAL_INTER define. Note
  that in this case, you also need to set #SBR_BS_DELAY_ENABLE, which basically
  adds approriate delay in the SBR decoder. Note that the
  Interpolating-Concealment increases the delay of your decoder by one frame and
  that it does require additional resources such as memory and computational
  complexity.

  <h2>How concealment can be used with errors on the transport layer</h2>

  Many errors can or have to be detected on the transport layer. For example in
  IP based systems packet loss can occur. The transport protocol used should
  indicate such packet loss by inserting an empty frame with frameOK=0.
*/

#include "conceal.h"

#include "aac_rom.h"
#include "genericStds.h"

/* PNS (of block) */
#include "aacdec_pns.h"
#include "block.h"

#define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000)

#define CONCEAL_NOT_DEFINED ((UCHAR)-1)

/* default settings */
#define CONCEAL_DFLT_FADEOUT_FRAMES (6)
#define CONCEAL_DFLT_FADEIN_FRAMES (5)
#define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0)

#define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */

/* some often used constants: */
#define FIXP_ZERO FL2FXCONST_DBL(0.0f)
#define FIXP_ONE FL2FXCONST_DBL(1.0f)
#define FIXP_FL_CORRECTION FL2FXCONST_DBL(0.53333333333333333f)

/* For parameter conversion */
#define CONCEAL_PARAMETER_BITS (8)
#define CONCEAL_MAX_QUANT_FACTOR ((1 << CONCEAL_PARAMETER_BITS) - 1)
/*#define CONCEAL_MIN_ATTENUATION_FACTOR_025  ( FL2FXCONST_DBL(0.971627951577106174) )*/ /* -0.25 dB */
#define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD \
  FL2FXCONST_DBL(-0.041524101186092029596853445212299)
/*#define CONCEAL_MIN_ATTENUATION_FACTOR_050  ( FL2FXCONST_DBL(0.944060876285923380) )*/ /* -0.50 dB */
#define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD \
  FL2FXCONST_DBL(-0.083048202372184059253597008145293)

typedef enum {
  CConcealment_NoExpand,
  CConcealment_Expand,
  CConcealment_Compress
} CConcealmentExpandType;

static const FIXP_SGL facMod4Table[4] = {
    FL2FXCONST_SGL(0.500000000f), /* FIXP_SGL(0x4000),  2^-(1-0,00) */
    FL2FXCONST_SGL(0.594603558f), /* FIXP_SGL(0x4c1b),  2^-(1-0,25) */
    FL2FXCONST_SGL(0.707106781f), /* FIXP_SGL(0x5a82),  2^-(1-0,50) */
    FL2FXCONST_SGL(0.840896415f)  /* FIXP_SGL(0x6ba2)   2^-(1-0,75) */
};

static void CConcealment_CalcBandEnergy(
    FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
    const int blockType, CConcealmentExpandType ex, int *sfbEnergy);

static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
                                           SHORT *pSpecScalePrev,
                                           SHORT *pSpecScaleAct,
                                           SHORT *pSpecScaleOut, int *enPrv,
                                           int *enAct, int sfbCnt,
                                           const SHORT *pSfbOffset);

static int CConcealment_ApplyInter(
    CConcealmentInfo *pConcealmentInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
    const int improveTonal, const int frameOk, const int mute_release_active);

static int CConcealment_ApplyNoise(
    CConcealmentInfo *pConcealmentInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
    const UINT flags);

static void CConcealment_UpdateState(
    CConcealmentInfo *pConcealmentInfo, int frameOk,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);

static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
                                         int samplesPerFrame);

/* TimeDomainFading */
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
                                      FIXP_DBL fadeStop, FIXP_PCM *pcmdata);
static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
                                                  int *fadingSteps,
                                                  FIXP_DBL fadeStop,
                                                  FIXP_DBL fadeStart,
                                                  TDfadingType fadingType);
static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps);

/* Streamline the state machine */
static int CConcealment_ApplyFadeOut(
    int mode, CConcealmentInfo *pConcealmentInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);

static int CConcealment_TDNoise_Random(ULONG *seed);
static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
                                       const int len, FIXP_PCM *const pcmdata);

static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
  BLOCK_TYPE newWinSeq = BLOCK_LONG;

  /* Try to have only long blocks */
  if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) {
    newWinSeq = BLOCK_STOP;
  }

  return (newWinSeq);
}

/*!
  \brief Init common concealment information data

  \param pConcealCommonData Pointer to the concealment common data structure.
*/
void CConcealment_InitCommonData(CConcealParams *pConcealCommonData) {
  if (pConcealCommonData != NULL) {
    int i;

    /* Set default error concealment technique */
    pConcealCommonData->method = ConcealMethodInter;

    pConcealCommonData->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES;
    pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES;
    pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES;

    pConcealCommonData->comfortNoiseLevel =
        (FIXP_DBL)CONCEAL_DFLT_COMF_NOISE_LEVEL;

    /* Init fade factors (symetric) */
    pConcealCommonData->fadeOutFactor[0] =
        FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR);
    pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0];

    for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
      pConcealCommonData->fadeOutFactor[i] =
          FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i - 1],
                              FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR)));
      pConcealCommonData->fadeInFactor[i] =
          pConcealCommonData->fadeOutFactor[i];
    }
  }
}

/*!
  \brief Get current concealment method.

  \param pConcealCommonData Pointer to common concealment data (for all
  channels)
*/
CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) {
  CConcealmentMethod method = ConcealMethodNone;

  if (pConcealCommonData != NULL) {
    method = pConcealCommonData->method;
  }

  return (method);
}

/*!
  \brief Init concealment information for each channel

  \param pConcealChannelInfo Pointer to the channel related concealment info
  structure to be initialized. \param pConcealCommonData  Pointer to common
  concealment data (for all channels) \param initRenderMode      Initial render
  mode to be set for the current channel. \param samplesPerFrame     The number
  of samples per frame.
*/
void CConcealment_InitChannelData(CConcealmentInfo *pConcealChannelInfo,
                                  CConcealParams *pConcealCommonData,
                                  AACDEC_RENDER_MODE initRenderMode,
                                  int samplesPerFrame) {
  int i;
  pConcealChannelInfo->TDNoiseSeed = 0;
  FDKmemclear(pConcealChannelInfo->TDNoiseStates,
              sizeof(pConcealChannelInfo->TDNoiseStates));
  pConcealChannelInfo->TDNoiseCoef[0] = FL2FXCONST_SGL(0.05f);
  pConcealChannelInfo->TDNoiseCoef[1] = FL2FXCONST_SGL(0.5f);
  pConcealChannelInfo->TDNoiseCoef[2] = FL2FXCONST_SGL(0.45f);

  pConcealChannelInfo->pConcealParams = pConcealCommonData;

  pConcealChannelInfo->lastRenderMode = initRenderMode;

  pConcealChannelInfo->windowShape = CONCEAL_NOT_DEFINED;
  pConcealChannelInfo->windowSequence = BLOCK_LONG; /* default type */
  pConcealChannelInfo->lastWinGrpLen = 1;

  pConcealChannelInfo->concealState = ConcealState_Ok;

  FDKmemclear(pConcealChannelInfo->spectralCoefficient,
              1024 * sizeof(FIXP_CNCL));

  for (i = 0; i < 8; i++) {
    pConcealChannelInfo->specScale[i] = 0;
  }

  pConcealChannelInfo->iRandomPhase = 0;

  pConcealChannelInfo->prevFrameOk[0] = 1;
  pConcealChannelInfo->prevFrameOk[1] = 1;

  pConcealChannelInfo->cntFadeFrames = 0;
  pConcealChannelInfo->cntValidFrames = 0;
  pConcealChannelInfo->fade_old = (FIXP_DBL)MAXVAL_DBL;
  pConcealChannelInfo->winGrpOffset[0] = 0;
  pConcealChannelInfo->winGrpOffset[1] = 0;
  pConcealChannelInfo->attGrpOffset[0] = 0;
  pConcealChannelInfo->attGrpOffset[1] = 0;
}

/*!
  \brief Set error concealment parameters

  \param concealParams
  \param method
  \param fadeOutSlope
  \param fadeInSlope
  \param muteRelease
  \param comfNoiseLevel
*/
AAC_DECODER_ERROR
CConcealment_SetParams(CConcealParams *concealParams, int method,
                       int fadeOutSlope, int fadeInSlope, int muteRelease,
                       FIXP_DBL comfNoiseLevel) {
  /* set concealment technique */
  if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
    switch ((CConcealmentMethod)method) {
      case ConcealMethodMute:
      case ConcealMethodNoise:
      case ConcealMethodInter:
        /* Be sure to enable delay adjustment of SBR decoder! */
        if (concealParams == NULL) {
          return AAC_DEC_INVALID_HANDLE;
        } else {
          /* set param */
          concealParams->method = (CConcealmentMethod)method;
        }
        break;

      default:
        return AAC_DEC_SET_PARAM_FAIL;
    }
  }

  /* set number of frames for fade-out slope */
  if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
    if ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) {
      if (concealParams == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      } else {
        /* set param */
        concealParams->numFadeOutFrames = fadeOutSlope;
      }
    } else {
      return AAC_DEC_SET_PARAM_FAIL;
    }
  }

  /* set number of frames for fade-in slope */
  if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
    if ((fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeInSlope >= 0)) {
      if (concealParams == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      } else {
        /* set param */
        concealParams->numFadeInFrames = fadeInSlope;
      }
    } else {
      return AAC_DEC_SET_PARAM_FAIL;
    }
  }

  /* set number of error-free frames after which the muting will be released */
  if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
    if ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) &&
        (muteRelease >= 0)) {
      if (concealParams == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      } else {
        /* set param */
        concealParams->numMuteReleaseFrames = muteRelease;
      }
    } else {
      return AAC_DEC_SET_PARAM_FAIL;
    }
  }

  /* set confort noise level which will be inserted while in state 'muting' */
  if (comfNoiseLevel != (FIXP_DBL)AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
    if ((comfNoiseLevel < (FIXP_DBL)0) ||
        (comfNoiseLevel > (FIXP_DBL)MAXVAL_DBL)) {
      return AAC_DEC_SET_PARAM_FAIL;
    }
    if (concealParams == NULL) {
      return AAC_DEC_INVALID_HANDLE;
    } else {
      concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel;
    }
  }

  return (AAC_DEC_OK);
}

/*!
  \brief Set fade-out/in attenuation factor vectors

  \param concealParams
  \param fadeOutAttenuationVector
  \param fadeInAttenuationVector

  \return 0 if OK all other values indicate errors
*/
AAC_DECODER_ERROR
CConcealment_SetAttenuation(CConcealParams *concealParams,
                            const SHORT *fadeOutAttenuationVector,
                            const SHORT *fadeInAttenuationVector) {
  if ((fadeOutAttenuationVector == NULL) && (fadeInAttenuationVector == NULL)) {
    return AAC_DEC_SET_PARAM_FAIL;
  }

  /* Fade-out factors */
  if (fadeOutAttenuationVector != NULL) {
    int i;

    /* check quantized factors first */
    for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
      if ((fadeOutAttenuationVector[i] < 0) ||
          (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
    }
    if (concealParams == NULL) {
      return AAC_DEC_INVALID_HANDLE;
    }

    /* now dequantize factors */
    for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
      concealParams->fadeOutFactor[i] =
          FX_DBL2FX_SGL(fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
                               (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0 / 2.0) >>
                                                (CONCEAL_PARAMETER_BITS - 1)) *
                                          (INT)fadeOutAttenuationVector[i]),
                               CONCEAL_PARAMETER_BITS));
    }
  }

  /* Fade-in factors */
  if (fadeInAttenuationVector != NULL) {
    int i;

    /* check quantized factors first */
    for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
      if ((fadeInAttenuationVector[i] < 0) ||
          (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
    }
    if (concealParams == NULL) {
      return AAC_DEC_INVALID_HANDLE;
    }

    /* now dequantize factors */
    for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
      concealParams->fadeInFactor[i] = FX_DBL2FX_SGL(
          fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
                 (FIXP_DBL)((INT)(FIXP_ONE >> CONCEAL_PARAMETER_BITS) *
                            (INT)fadeInAttenuationVector[i]),
                 CONCEAL_PARAMETER_BITS));
    }
  }

  return (AAC_DEC_OK);
}

/*!
  \brief Get state of concealment module.

  \param pConcealChannelInfo

  \return Concealment state.
*/
CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) {
  CConcealmentState state = ConcealState_Ok;

  if (pConcealChannelInfo != NULL) {
    state = pConcealChannelInfo->concealState;
  }

  return (state);
}

/*!
  \brief Store data for concealment techniques applied later

  Interface function to store data for different concealment strategies
 */
void CConcealment_Store(
    CConcealmentInfo *hConcealmentInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
  UCHAR nbDiv = NB_DIV;

  if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
        pAacDecoderChannelInfo->data.usac.mod[nbDiv - 1] == 0))

  {
    FIXP_DBL *pSpectralCoefficient =
        SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
    SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
    CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;

    SHORT tSpecScale[8];
    UCHAR tWindowShape;
    BLOCK_TYPE tWindowSequence;

    /* store old window infos for swapping */
    tWindowSequence = hConcealmentInfo->windowSequence;
    tWindowShape = hConcealmentInfo->windowShape;

    /* store old scale factors for swapping */
    FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));

    /* store new window infos */
    hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo);
    hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo);
    hConcealmentInfo->lastWinGrpLen =
        *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1);

    /* store new scale factors */
    FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT));

    if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) {
    /* store new spectral bins */
#if (CNCL_FRACT_BITS == DFRACT_BITS)
      FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient,
                1024 * sizeof(FIXP_CNCL));
#else
      FIXP_CNCL *RESTRICT pCncl =
          &hConcealmentInfo->spectralCoefficient[1024 - 1];
      FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
      int i;
      for (i = 1024; i != 0; i--) {
        *pCncl-- = FX_DBL2FX_CNCL(*pSpec--);
      }
#endif
    } else {
    /* swap spectral data */
#if (FIXP_CNCL == FIXP_DBL)
      C_ALLOC_SCRATCH_START(pSpecTmp, FIXP_DBL, 1024);
      FDKmemcpy(pSpecTmp, pSpectralCoefficient, 1024 * sizeof(FIXP_DBL));
      FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
                1024 * sizeof(FIXP_DBL));
      FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpecTmp,
                1024 * sizeof(FIXP_DBL));
      C_ALLOC_SCRATCH_END(pSpecTmp, FIXP_DBL, 1024);
#else
      FIXP_CNCL *RESTRICT pCncl =
          &hConcealmentInfo->spectralCoefficient[1024 - 1];
      FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
      FIXP_DBL tSpec;

      for (int i = 1024; i != 0; i--) {
        tSpec = *pSpec;
        *pSpec-- = FX_CNCL2FX_DBL(*pCncl);
        *pCncl-- = FX_DBL2FX_CNCL(tSpec);
      }
#endif

      /* complete swapping of window infos */
      pIcsInfo->WindowSequence = tWindowSequence;
      pIcsInfo->WindowShape = tWindowShape;

      /* complete swapping of scale factors */
      FDKmemcpy(pSpecScale, tSpecScale, 8 * sizeof(SHORT));
    }
  }

  if (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD) {
    /* Store LSF4 */
    FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
              sizeof(hConcealmentInfo->lsf4));
    /* Store TCX gain */
    hConcealmentInfo->last_tcx_gain =
        pAacDecoderStaticChannelInfo->last_tcx_gain;
    hConcealmentInfo->last_tcx_gain_e =
        pAacDecoderStaticChannelInfo->last_tcx_gain_e;
  }
}

/*!
  \brief Apply concealment

  Interface function to different concealment strategies
 */
int CConcealment_Apply(
    CConcealmentInfo *hConcealmentInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
    const UCHAR lastLpdMode, const int frameOk, const UINT flags) {
  int appliedProcessing = 0;
  const int mute_release_active =
      frameOk && (hConcealmentInfo->concealState >= ConcealState_Mute) &&
      (hConcealmentInfo->cntValidFrames + 1 <=
       hConcealmentInfo->pConcealParams->numMuteReleaseFrames);

  if (hConcealmentInfo->windowShape == CONCEAL_NOT_DEFINED) {
    /* Initialize window_shape with same value as in the current (parsed) frame.
       Because section 4.6.11.3.2 (Windowing and block switching) of ISO/IEC
       14496-3:2009 says: For the first raw_data_block() to be decoded the
       window_shape of the left and right half of the window are identical. */
    hConcealmentInfo->windowShape = pAacDecoderChannelInfo->icsInfo.WindowShape;
  }

  if (frameOk && !mute_release_active) {
    /* Update render mode if frameOk except for ongoing mute release state. */
    hConcealmentInfo->lastRenderMode =
        (SCHAR)pAacDecoderChannelInfo->renderMode;

    /* Rescue current data for concealment in future frames */
    CConcealment_Store(hConcealmentInfo, pAacDecoderChannelInfo,
                       pAacDecoderStaticChannelInfo);
    /* Reset index to random sign vector to make sign calculation frame agnostic
       (only depends on number of subsequently concealed spectral blocks) */
    hConcealmentInfo->iRandomPhase = 0;
  } else {
    if (hConcealmentInfo->lastRenderMode == AACDEC_RENDER_INVALID) {
      hConcealmentInfo->lastRenderMode = AACDEC_RENDER_IMDCT;
    }
    pAacDecoderChannelInfo->renderMode =
        (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode;
  }

  /* hand current frame status to the state machine */
  CConcealment_UpdateState(hConcealmentInfo, frameOk,
                           pAacDecoderStaticChannelInfo, samplesPerFrame,
                           pAacDecoderChannelInfo);

  {
    if (!frameOk && pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_IMDCT) {
      /* LPC extrapolation */
      CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
                   pAacDecoderStaticChannelInfo->lpc4_lsf,
                   pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
                   hConcealmentInfo->lastRenderMode == AACDEC_RENDER_IMDCT);
      FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
                sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
    }

    /* Create data for signal rendering according to the selected concealment
     * method and decoder operating mode. */

    if ((!frameOk || mute_release_active) &&
        (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD)) {
      /* Restore old LSF4 */
      FDKmemcpy(pAacDecoderStaticChannelInfo->lpc4_lsf, hConcealmentInfo->lsf4,
                sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
      /* Restore old TCX gain */
      pAacDecoderStaticChannelInfo->last_tcx_gain =
          hConcealmentInfo->last_tcx_gain;
      pAacDecoderStaticChannelInfo->last_tcx_gain_e =
          hConcealmentInfo->last_tcx_gain_e;
    }

    if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
          pAacDecoderStaticChannelInfo->last_lpd_mode == 0)) {
      switch (hConcealmentInfo->pConcealParams->method) {
        default:
        case ConcealMethodMute:
          if (!frameOk) {
            /* Mute spectral data in case of errors */
            FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
                        samplesPerFrame * sizeof(FIXP_DBL));
            /* Set last window shape */
            pAacDecoderChannelInfo->icsInfo.WindowShape =
                hConcealmentInfo->windowShape;
            appliedProcessing = 1;
          }
          break;

        case ConcealMethodNoise:
          /* Noise substitution error concealment technique */
          appliedProcessing = CConcealment_ApplyNoise(
              hConcealmentInfo, pAacDecoderChannelInfo,
              pAacDecoderStaticChannelInfo, pSamplingRateInfo, samplesPerFrame,
              flags);
          break;

        case ConcealMethodInter:
          /* Energy interpolation concealment based on 3GPP */
          appliedProcessing = CConcealment_ApplyInter(
              hConcealmentInfo, pAacDecoderChannelInfo, pSamplingRateInfo,
              samplesPerFrame, 0, /* don't use tonal improvement */
              frameOk, mute_release_active);
          break;
      }
    } else if (!frameOk || mute_release_active) {
      /* simply restore the buffer */
      FIXP_DBL *pSpectralCoefficient =
          SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
      SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
      CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
#if (CNCL_FRACT_BITS != DFRACT_BITS)
      FIXP_CNCL *RESTRICT pCncl =
          &hConcealmentInfo->spectralCoefficient[1024 - 1];
      FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
      int i;
#endif

      /* restore window infos (gri) do we need that? */
      pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence;
      pIcsInfo->WindowShape = hConcealmentInfo->windowShape;

      if (hConcealmentInfo->concealState != ConcealState_Mute) {
        /* restore scale factors */
        FDKmemcpy(pSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));

        /* restore spectral bins */
#if (CNCL_FRACT_BITS == DFRACT_BITS)
        FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
                  1024 * sizeof(FIXP_DBL));
#else
        for (i = 1024; i != 0; i--) {
          *pSpec-- = FX_CNCL2FX_DBL(*pCncl--);
        }
#endif
      } else {
        /* clear scale factors */
        FDKmemclear(pSpecScale, 8 * sizeof(SHORT));

        /* clear buffer */
        FDKmemclear(pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL));
      }
    }
  }
  /* update history */
  hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1];
  hConcealmentInfo->prevFrameOk[1] = frameOk;

  return mute_release_active ? -1 : appliedProcessing;
}

/*!
\brief Apply concealment noise substitution

  In case of frame lost this function produces a noisy frame with respect to the
  energies values of past frame.
 */
static int CConcealment_ApplyNoise(
    CConcealmentInfo *pConcealmentInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
    const UINT flags) {
  FIXP_DBL *pSpectralCoefficient =
      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
  CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;

  int appliedProcessing = 0;

  FDK_ASSERT(pConcealmentInfo != NULL);
  FDK_ASSERT((samplesPerFrame >= 120) && (samplesPerFrame <= 1024));

  switch (pConcealmentInfo->concealState) {
    case ConcealState_Ok:
      /* Nothing to do here! */
      break;

    case ConcealState_Single:
    case ConcealState_FadeOut:
      appliedProcessing = CConcealment_ApplyFadeOut(
          /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo,
          samplesPerFrame, pAacDecoderChannelInfo);
      break;

    case ConcealState_Mute: {
      /* set dummy window parameters */
      pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
      pIcsInfo->WindowShape =
          pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
                                            (required for F/T transform) */
      pIcsInfo->WindowSequence =
          CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
      pConcealmentInfo->windowSequence =
          pIcsInfo->WindowSequence; /* Store for next frame
                                       (spectrum in concealment
                                       buffer can't be used at
                                       all) */

      /* mute spectral data */
      FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
      FDKmemclear(pConcealmentInfo->spectralCoefficient,
                  samplesPerFrame * sizeof(FIXP_DBL));

      appliedProcessing = 1;
    } break;

    case ConcealState_FadeIn: {
      /* TimeDomainFading:                                        */
      /* Attenuation of signal is done in CConcealment_TDFading() */

      appliedProcessing = 1;
    } break;

    default:
      /* we shouldn't come here anyway */
      FDK_ASSERT(0);
      break;
  }

  return appliedProcessing;
}

/*!
  \brief Apply concealment interpolation

  The function swaps the data from the current and the previous frame. If an
  error has occured, frame interpolation is performed to restore the missing
  frame. In case of multiple faulty frames, fade-in and fade-out is applied.
*/
static int CConcealment_ApplyInter(
    CConcealmentInfo *pConcealmentInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
    const int improveTonal, const int frameOk, const int mute_release_active) {
#if defined(FDK_ASSERT_ENABLE)
  CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
#endif

  FIXP_DBL *pSpectralCoefficient =
      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
  CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
  SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;

  int sfbEnergyPrev[64];
  int sfbEnergyAct[64];

  int i, appliedProcessing = 0;

  /* clear/init */
  FDKmemclear(sfbEnergyPrev, 64 * sizeof(int));
  FDKmemclear(sfbEnergyAct, 64 * sizeof(int));

  if (!frameOk || mute_release_active) {
    /* Restore last frame from concealment buffer */
    pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
    pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;

    /* Restore spectral data */
    for (i = 0; i < samplesPerFrame; i++) {
      pSpectralCoefficient[i] =
          FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]);
    }

    /* Restore scale factors */
    FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT));
  }

  /* if previous frame was not ok */
  if (!pConcealmentInfo->prevFrameOk[1] || mute_release_active) {
    /* if current frame (f_n) is ok and the last but one frame (f_(n-2))
       was ok, too, then interpolate both frames in order to generate
       the current output frame (f_(n-1)). Otherwise, use the last stored
       frame (f_(n-2) or f_(n-3) or ...). */
    if (frameOk && pConcealmentInfo->prevFrameOk[0] && !mute_release_active) {
      appliedProcessing = 1;

      /* Interpolate both frames in order to generate the current output frame
       * (f_(n-1)). */
      if (pIcsInfo->WindowSequence == BLOCK_SHORT) {
        /* f_(n-2) == BLOCK_SHORT */
        /* short--??????--short, short--??????--long interpolation */
        /* short--short---short, short---long---long interpolation */

        int wnd;

        if (pConcealmentInfo->windowSequence ==
            BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
          /* short--short---short interpolation */

          int scaleFactorBandsTotal =
              pSamplingRateInfo->NumberOfScaleFactorBands_Short;
          const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
          pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
          pIcsInfo->WindowSequence = BLOCK_SHORT;

          for (wnd = 0; wnd < 8; wnd++) {
            CConcealment_CalcBandEnergy(
                &pSpectralCoefficient[wnd *
                                      (samplesPerFrame / 8)], /* spec_(n-2) */
                pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
                sfbEnergyPrev);

            CConcealment_CalcBandEnergy(
                &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame /
                                                              8)], /* spec_n */
                pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
                sfbEnergyAct);

            CConcealment_InterpolateBuffer(
                &pSpectralCoefficient[wnd *
                                      (samplesPerFrame / 8)], /* spec_(n-1) */
                &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd],
                &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct,
                scaleFactorBandsTotal, pSfbOffset);
          }
        } else { /* f_n != BLOCK_SHORT */
          /* short---long---long interpolation */

          int scaleFactorBandsTotal =
              pSamplingRateInfo->NumberOfScaleFactorBands_Long;
          const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
          SHORT specScaleOut;

          CConcealment_CalcBandEnergy(
              &pSpectralCoefficient[samplesPerFrame -
                                    (samplesPerFrame /
                                     8)], /* [wnd] spec_(n-2) */
              pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand,
              sfbEnergyAct);

          CConcealment_CalcBandEnergy(
              pConcealmentInfo->spectralCoefficient, /* spec_n */
              pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
              sfbEnergyPrev);

          pIcsInfo->WindowShape = 0;
          pIcsInfo->WindowSequence = BLOCK_STOP;

          for (i = 0; i < samplesPerFrame; i++) {
            pSpectralCoefficient[i] =
                pConcealmentInfo->spectralCoefficient[i]; /* spec_n */
          }

          for (i = 0; i < 8; i++) { /* search for max(specScale) */
            if (pSpecScale[i] > pSpecScale[0]) {
              pSpecScale[0] = pSpecScale[i];
            }
          }

          CConcealment_InterpolateBuffer(
              pSpectralCoefficient, /* spec_(n-1) */
              &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut,
              sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);

          pSpecScale[0] = specScaleOut;
        }
      } else {
        /* long--??????--short, long--??????--long interpolation */
        /* long---long---short, long---long---long interpolation */

        int scaleFactorBandsTotal =
            pSamplingRateInfo->NumberOfScaleFactorBands_Long;
        const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
        SHORT specScaleAct = pConcealmentInfo->specScale[0];

        CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */
                                    pSamplingRateInfo, BLOCK_LONG,
                                    CConcealment_NoExpand, sfbEnergyPrev);

        if (pConcealmentInfo->windowSequence ==
            BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
          /* long---long---short interpolation */

          pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
          pIcsInfo->WindowSequence = BLOCK_START;

          for (i = 1; i < 8; i++) { /* search for max(specScale) */
            if (pConcealmentInfo->specScale[i] > specScaleAct) {
              specScaleAct = pConcealmentInfo->specScale[i];
            }
          }

          /* Expand first short spectrum */
          CConcealment_CalcBandEnergy(
              pConcealmentInfo->spectralCoefficient,               /* spec_n */
              pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */
              sfbEnergyAct);
        } else {
          /* long---long---long interpolation */

          pIcsInfo->WindowShape = 0;
          pIcsInfo->WindowSequence = BLOCK_LONG;

          CConcealment_CalcBandEnergy(
              pConcealmentInfo->spectralCoefficient, /* spec_n */
              pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
              sfbEnergyAct);
        }

        CConcealment_InterpolateBuffer(
            pSpectralCoefficient, /* spec_(n-1) */
            &pSpecScale[0], &specScaleAct, &pSpecScale[0], sfbEnergyPrev,
            sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
      }
    }

    /* Noise substitution of sign of the output spectral coefficients */
    CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase,
                                 pSpectralCoefficient, samplesPerFrame);
    /* Increment random phase index to avoid repetition artifacts. */
    pConcealmentInfo->iRandomPhase =
        (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
  }

  /* scale spectrum according to concealment state */
  switch (pConcealmentInfo->concealState) {
    case ConcealState_Single:
      appliedProcessing = 1;
      break;

    case ConcealState_FadeOut: {
      FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
      FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
                 CONCEAL_MAX_NUM_FADE_FACTORS);
      FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
                 pConcealCommonData->numFadeOutFrames);

      /* TimeDomainFading:                                        */
      /* Attenuation of signal is done in CConcealment_TDFading() */

      appliedProcessing = 1;
    } break;

    case ConcealState_FadeIn: {
      FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
      FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
                 CONCEAL_MAX_NUM_FADE_FACTORS);
      FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
                 pConcealCommonData->numFadeInFrames);

      /* TimeDomainFading:                                        */
      /* Attenuation of signal is done in CConcealment_TDFading() */

      appliedProcessing = 1;
    } break;

    case ConcealState_Mute: {
      /* set dummy window parameters */
      pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
      pIcsInfo->WindowShape =
          pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
                                            (required for F/T transform) */
      pIcsInfo->WindowSequence =
          CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
      pConcealmentInfo->windowSequence =
          pIcsInfo->WindowSequence; /* Store for next frame
                                       (spectrum in concealment
                                       buffer can't be used at
                                       all) */

      /* mute spectral data */
      FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));

      appliedProcessing = 1;
    } break;

    default:
      /* nothing to do here */
      break;
  }

  return appliedProcessing;
}

/*!
  \brief Calculate the spectral energy

  The function calculates band-wise the spectral energy. This is used for
  frame interpolation.
*/
static void CConcealment_CalcBandEnergy(
    FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
    const int blockType, CConcealmentExpandType expandType, int *sfbEnergy) {
  const SHORT *pSfbOffset;
  int line, sfb, scaleFactorBandsTotal = 0;

  /* In the following calculations, enAccu is initialized with LSB-value in
   * order to avoid zero energy-level */

  line = 0;

  switch (blockType) {
    case BLOCK_LONG:
    case BLOCK_START:
    case BLOCK_STOP:

      if (expandType == CConcealment_NoExpand) {
        /* standard long calculation */
        scaleFactorBandsTotal =
            pSamplingRateInfo->NumberOfScaleFactorBands_Long;
        pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;

        for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
          FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
          int sfbScale =
              (sizeof(LONG) << 3) -
              CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
          /* scaling depends on sfb width. */
          for (; line < pSfbOffset[sfb + 1]; line++) {
            enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
          }
          *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
        }
      } else {
        /* compress long to short */
        scaleFactorBandsTotal =
            pSamplingRateInfo->NumberOfScaleFactorBands_Short;
        pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;

        for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
          FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
          int sfbScale =
              (sizeof(LONG) << 3) -
              CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
          /* scaling depends on sfb width. */
          for (; line < pSfbOffset[sfb + 1] << 3; line++) {
            enAccu +=
                (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3;
          }
          *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
        }
      }
      break;

    case BLOCK_SHORT:

      if (expandType == CConcealment_NoExpand) {
        /*   standard short calculation */
        scaleFactorBandsTotal =
            pSamplingRateInfo->NumberOfScaleFactorBands_Short;
        pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;

        for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
          FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
          int sfbScale =
              (sizeof(LONG) << 3) -
              CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
          /* scaling depends on sfb width. */
          for (; line < pSfbOffset[sfb + 1]; line++) {
            enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
          }
          *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
        }
      } else {
        /*  expand short to long spectrum */
        scaleFactorBandsTotal =
            pSamplingRateInfo->NumberOfScaleFactorBands_Long;
        pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;

        for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
          FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
          int sfbScale =
              (sizeof(LONG) << 3) -
              CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
          /* scaling depends on sfb width. */
          for (; line < pSfbOffset[sfb + 1]; line++) {
            enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale;
          }
          *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
        }
      }
      break;
  }
}

/*!
  \brief Interpolate buffer

  The function creates the interpolated spectral data according to the
  energy of the last good frame and the current (good) frame.
*/
static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
                                           SHORT *pSpecScalePrv,
                                           SHORT *pSpecScaleAct,
                                           SHORT *pSpecScaleOut, int *enPrv,
                                           int *enAct, int sfbCnt,
                                           const SHORT *pSfbOffset) {
  int sfb, line = 0;
  int fac_shift;
  int fac_mod;
  FIXP_DBL accu;

  for (sfb = 0; sfb < sfbCnt; sfb++) {
    fac_shift =
        enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1);
    fac_mod = fac_shift & 3;
    fac_shift = (fac_shift >> 2) + 1;
    fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);

    for (; line < pSfbOffset[sfb + 1]; line++) {
      accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
      if (fac_shift < 0) {
        accu >>= -fac_shift;
      } else {
        accu <<= fac_shift;
      }
      *(spectrum + line) = accu;
    }
  }
  *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
}

/*!
  \brief Find next fading frame in case of changing fading direction

  \param pConcealCommonData Pointer to the concealment common data structure.
  \param actFadeIndex Last index used for fading
  \param direction Direction of change: 0 : change from FADE-OUT to FADE-IN,  1
  : change from FADE-IN to FADE-OUT

  This function determines the next fading index to be used for the fading
  direction to be changed to.
*/

static INT findEquiFadeFrame(CConcealParams *pConcealCommonData,
                             INT actFadeIndex, int direction) {
  FIXP_SGL *pFactor;
  FIXP_SGL referenceVal;
  FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL;

  INT nextFadeIndex = 0;

  int i;

  /* init depending on direction */
  if (direction == 0) { /* FADE-OUT => FADE-IN */
    if (actFadeIndex < 0) {
      referenceVal = (FIXP_SGL)MAXVAL_SGL;
    } else {
      referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1;
    }
    pFactor = pConcealCommonData->fadeInFactor;
  } else { /* FADE-IN => FADE-OUT */
    if (actFadeIndex < 0) {
      referenceVal = (FIXP_SGL)MAXVAL_SGL;
    } else {
      referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1;
    }
    pFactor = pConcealCommonData->fadeOutFactor;
  }

  /* search for minimum difference */
  for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
    FIXP_SGL diff = fixp_abs((pFactor[i] >> 1) - referenceVal);
    if (diff < minDiff) {
      minDiff = diff;
      nextFadeIndex = i;
    }
  }

  /* check and adjust depending on direction */
  if (direction == 0) { /* FADE-OUT => FADE-IN */
    if (nextFadeIndex > pConcealCommonData->numFadeInFrames) {
      nextFadeIndex = fMax(pConcealCommonData->numFadeInFrames - 1, 0);
    }
    if (((pFactor[nextFadeIndex] >> 1) <= referenceVal) &&
        (nextFadeIndex > 0)) {
      nextFadeIndex -= 1;
    }
  } else { /* FADE-IN => FADE-OUT */
    if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) &&
        (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) {
      nextFadeIndex += 1;
    }
  }

  return (nextFadeIndex);
}

/*!
  \brief Update the concealment state

  The function updates the state of the concealment state-machine. The
  states are: mute, fade-in, fade-out, interpolate and frame-ok.
*/
static void CConcealment_UpdateState(
    CConcealmentInfo *pConcealmentInfo, int frameOk,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
  CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;

  switch (pConcealCommonData->method) {
    case ConcealMethodNoise: {
      if (pConcealmentInfo->concealState != ConcealState_Ok) {
        /* count the valid frames during concealment process */
        if (frameOk) {
          pConcealmentInfo->cntValidFrames += 1;
        } else {
          pConcealmentInfo->cntValidFrames = 0;
        }
      }

      /* -- STATE MACHINE for Noise Substitution -- */
      switch (pConcealmentInfo->concealState) {
        case ConcealState_Ok:
          if (!frameOk) {
            pConcealmentInfo->cntFadeFrames = 0;
            pConcealmentInfo->cntValidFrames = 0;
            pConcealmentInfo->attGrpOffset[0] = 0;
            pConcealmentInfo->attGrpOffset[1] = 0;
            pConcealmentInfo->winGrpOffset[0] = 0;
            pConcealmentInfo->winGrpOffset[1] = 0;
            if (pConcealCommonData->numFadeOutFrames > 0) {
              /* change to state SINGLE-FRAME-LOSS */
              pConcealmentInfo->concealState = ConcealState_Single;
              /* mode 0 just updates the Fading counter */
              CConcealment_ApplyFadeOut(
                  /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
                  samplesPerFrame, pAacDecoderChannelInfo);

            } else {
              /* change to state MUTE */
              pConcealmentInfo->concealState = ConcealState_Mute;
            }
          }
          break;

        case ConcealState_Single: /* Just a pre-stage before fade-out begins.
                                     Stay here only one frame! */
          if (frameOk) {
            /* change to state OK */
            pConcealmentInfo->concealState = ConcealState_Ok;
          } else {
            if (pConcealmentInfo->cntFadeFrames >=
                pConcealCommonData->numFadeOutFrames) {
              /* change to state MUTE */
              pConcealmentInfo->concealState = ConcealState_Mute;
            } else {
              /* change to state FADE-OUT */
              pConcealmentInfo->concealState = ConcealState_FadeOut;
              /* mode 0 just updates the Fading counter */
              CConcealment_ApplyFadeOut(
                  /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
                  samplesPerFrame, pAacDecoderChannelInfo);
            }
          }
          break;

        case ConcealState_FadeOut:
          if (pConcealmentInfo->cntValidFrames >
              pConcealCommonData->numMuteReleaseFrames) {
            if (pConcealCommonData->numFadeInFrames > 0) {
              /* change to state FADE-IN */
              pConcealmentInfo->concealState = ConcealState_FadeIn;
              pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
                  pConcealCommonData, pConcealmentInfo->cntFadeFrames,
                  0 /* FadeOut -> FadeIn */);
            } else {
              /* change to state OK */
              pConcealmentInfo->concealState = ConcealState_Ok;
            }
          } else {
            if (frameOk) {
              /* we have good frame information but stay fully in concealment -
               * reset winGrpOffset/attGrpOffset */
              pConcealmentInfo->winGrpOffset[0] = 0;
              pConcealmentInfo->winGrpOffset[1] = 0;
              pConcealmentInfo->attGrpOffset[0] = 0;
              pConcealmentInfo->attGrpOffset[1] = 0;
            }
            if (pConcealmentInfo->cntFadeFrames >=
                pConcealCommonData->numFadeOutFrames) {
              /* change to state MUTE */
              pConcealmentInfo->concealState = ConcealState_Mute;
            } else /* Stay in FADE-OUT */
            {
              /* mode 0 just updates the Fading counter */
              CConcealment_ApplyFadeOut(
                  /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
                  samplesPerFrame, pAacDecoderChannelInfo);
            }
          }
          break;

        case ConcealState_Mute:
          if (pConcealmentInfo->cntValidFrames >
              pConcealCommonData->numMuteReleaseFrames) {
            if (pConcealCommonData->numFadeInFrames > 0) {
              /* change to state FADE-IN */
              pConcealmentInfo->concealState = ConcealState_FadeIn;
              pConcealmentInfo->cntFadeFrames =
                  pConcealCommonData->numFadeInFrames - 1;
            } else {
              /* change to state OK */
              pConcealmentInfo->concealState = ConcealState_Ok;
            }
          } else {
            if (frameOk) {
              /* we have good frame information but stay fully in concealment -
               * reset winGrpOffset/attGrpOffset */
              pConcealmentInfo->winGrpOffset[0] = 0;
              pConcealmentInfo->winGrpOffset[1] = 0;
              pConcealmentInfo->attGrpOffset[0] = 0;
              pConcealmentInfo->attGrpOffset[1] = 0;
            }
          }
          break;

        case ConcealState_FadeIn:
          pConcealmentInfo->cntFadeFrames -= 1;
          if (frameOk) {
            if (pConcealmentInfo->cntFadeFrames < 0) {
              /* change to state OK */
              pConcealmentInfo->concealState = ConcealState_Ok;
            }
          } else {
            if (pConcealCommonData->numFadeOutFrames > 0) {
              /* change to state FADE-OUT */
              pConcealmentInfo->concealState = ConcealState_FadeOut;
              pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
                  pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
                  1 /* FadeIn -> FadeOut */);
              pConcealmentInfo->winGrpOffset[0] = 0;
              pConcealmentInfo->winGrpOffset[1] = 0;
              pConcealmentInfo->attGrpOffset[0] = 0;
              pConcealmentInfo->attGrpOffset[1] = 0;

              pConcealmentInfo
                  ->cntFadeFrames--; /* decrease because
                                        CConcealment_ApplyFadeOut() will
                                        increase, accordingly */
              /* mode 0 just updates the Fading counter */
              CConcealment_ApplyFadeOut(
                  /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
                  samplesPerFrame, pAacDecoderChannelInfo);
            } else {
              /* change to state MUTE */
              pConcealmentInfo->concealState = ConcealState_Mute;
            }
          }
          break;

        default:
          FDK_ASSERT(0);
          break;
      }
    } break;

    case ConcealMethodInter:
    case ConcealMethodTonal: {
      if (pConcealmentInfo->concealState != ConcealState_Ok) {
        /* count the valid frames during concealment process */
        if (pConcealmentInfo->prevFrameOk[1] ||
            (pConcealmentInfo->prevFrameOk[0] &&
             !pConcealmentInfo->prevFrameOk[1] && frameOk)) {
          /* The frame is OK even if it can be estimated by the energy
           * interpolation algorithm */
          pConcealmentInfo->cntValidFrames += 1;
        } else {
          pConcealmentInfo->cntValidFrames = 0;
        }
      }

      /* -- STATE MACHINE for energy interpolation -- */
      switch (pConcealmentInfo->concealState) {
        case ConcealState_Ok:
          if (!(pConcealmentInfo->prevFrameOk[1] ||
                (pConcealmentInfo->prevFrameOk[0] &&
                 !pConcealmentInfo->prevFrameOk[1] && frameOk))) {
            if (pConcealCommonData->numFadeOutFrames > 0) {
              /* Fade out only if the energy interpolation algorithm can not be
               * applied! */
              pConcealmentInfo->concealState = ConcealState_FadeOut;
            } else {
              /* change to state MUTE */
              pConcealmentInfo->concealState = ConcealState_Mute;
            }
            pConcealmentInfo->cntFadeFrames = 0;
            pConcealmentInfo->cntValidFrames = 0;
          }
          break;

        case ConcealState_Single:
          pConcealmentInfo->concealState = ConcealState_Ok;
          break;

        case ConcealState_FadeOut:
          pConcealmentInfo->cntFadeFrames += 1;

          if (pConcealmentInfo->cntValidFrames >
              pConcealCommonData->numMuteReleaseFrames) {
            if (pConcealCommonData->numFadeInFrames > 0) {
              /* change to state FADE-IN */
              pConcealmentInfo->concealState = ConcealState_FadeIn;
              pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
                  pConcealCommonData, pConcealmentInfo->cntFadeFrames - 1,
                  0 /* FadeOut -> FadeIn */);
            } else {
              /* change to state OK */
              pConcealmentInfo->concealState = ConcealState_Ok;
            }
          } else {
            if (pConcealmentInfo->cntFadeFrames >=
                pConcealCommonData->numFadeOutFrames) {
              /* change to state MUTE */
              pConcealmentInfo->concealState = ConcealState_Mute;
            }
          }
          break;

        case ConcealState_Mute:
          if (pConcealmentInfo->cntValidFrames >
              pConcealCommonData->numMuteReleaseFrames) {
            if (pConcealCommonData->numFadeInFrames > 0) {
              /* change to state FADE-IN */
              pConcealmentInfo->concealState = ConcealState_FadeIn;
              pConcealmentInfo->cntFadeFrames =
                  pConcealCommonData->numFadeInFrames - 1;
            } else {
              /* change to state OK */
              pConcealmentInfo->concealState = ConcealState_Ok;
            }
          }
          break;

        case ConcealState_FadeIn:
          pConcealmentInfo->cntFadeFrames -=
              1; /* used to address the fade-in factors */

          if (frameOk || pConcealmentInfo->prevFrameOk[1]) {
            if (pConcealmentInfo->cntFadeFrames < 0) {
              /* change to state OK */
              pConcealmentInfo->concealState = ConcealState_Ok;
            }
          } else {
            if (pConcealCommonData->numFadeOutFrames > 0) {
              /* change to state FADE-OUT */
              pConcealmentInfo->concealState = ConcealState_FadeOut;
              pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
                  pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
                  1 /* FadeIn -> FadeOut */);
            } else {
              /* change to state MUTE */
              pConcealmentInfo->concealState = ConcealState_Mute;
            }
          }
          break;
      } /* End switch(pConcealmentInfo->concealState) */
    } break;

    default:
      /* Don't need a state machine for other concealment methods. */
      break;
  }
}

/*!
\brief Randomizes the sign of the spectral data

  The function toggles the sign of the spectral data randomly. This is
  useful to ensure the quality of the concealed frames.
 */
static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
                                         int samplesPerFrame) {
  int i;
  USHORT packedSign = 0;

  /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit
   */

  /* read current packed sign word */
  packedSign = AacDec_randomSign[randomPhase >> 4];
  packedSign >>= (randomPhase & 0xf);

  for (i = 0; i < samplesPerFrame; i++) {
    if ((randomPhase & 0xf) == 0) {
      packedSign = AacDec_randomSign[randomPhase >> 4];
    }

    if (packedSign & 0x1) {
      spec[i] = -spec[i];
    }
    packedSign >>= 1;

    randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
  }
}

/*!
  \brief Get fadeing factor for current concealment state.

  The function returns the state (ok or not) of the previous frame.
  If called before the function CConcealment_Apply() set the fBeforeApply
  flag to get the correct value.

  \return Frame OK flag of previous frame.
 */
int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
                                const int fBeforeApply) {
  int prevFrameOk = 1;

  if (hConcealmentInfo != NULL) {
    prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1];
  }

  return prevFrameOk;
}

/*!
  \brief Get the number of delay frames introduced by concealment technique.

  \return Number of delay frames.
 */
UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) {
  UINT frameDelay = 0;

  if (pConcealCommonData != NULL) {
    switch (pConcealCommonData->method) {
      case ConcealMethodTonal:
      case ConcealMethodInter:
        frameDelay = 1;
        break;
      default:
        break;
    }
  }

  return frameDelay;
}

static int CConcealment_ApplyFadeOut(
    int mode, CConcealmentInfo *pConcealmentInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
  /* mode 1 = apply RandomSign and mute spectral coefficients if necessary,  *
   * mode 0 = Update cntFadeFrames                                            */

  /* restore frequency coefficients from buffer with a specific muting */
  int srcWin, dstWin, numWindows = 1;
  int windowLen = samplesPerFrame;
  int srcGrpStart = 0;
  int winIdxStride = 1;
  int numWinGrpPerFac, attIdx, attIdxStride;
  int i;
  int appliedProcessing = 0;

  CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
  FIXP_DBL *pSpectralCoefficient =
      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
  SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;

  /* set old window parameters */
  if (pConcealmentInfo->lastRenderMode == AACDEC_RENDER_LPD) {
    switch (pAacDecoderStaticChannelInfo->last_lpd_mode) {
      case 1:
        numWindows = 4;
        srcGrpStart = 3;
        windowLen = samplesPerFrame >> 2;
        break;
      case 2:
        numWindows = 2;
        srcGrpStart = 1;
        windowLen = samplesPerFrame >> 1;
        winIdxStride = 2;
        break;
      case 3:
        numWindows = 1;
        srcGrpStart = 0;
        windowLen = samplesPerFrame;
        winIdxStride = 4;
        break;
    }
    pConcealmentInfo->lastWinGrpLen = 1;
  } else {
    pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
    pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;

    if (pConcealmentInfo->windowSequence == BLOCK_SHORT) {
      /* short block handling */
      numWindows = 8;
      windowLen = samplesPerFrame >> 3;
      srcGrpStart = numWindows - pConcealmentInfo->lastWinGrpLen;
    }
  }

  attIdxStride =
      fMax(1, (int)(numWindows / (pConcealmentInfo->lastWinGrpLen + 1)));

  /* load last state */
  attIdx = pConcealmentInfo->cntFadeFrames;
  numWinGrpPerFac = pConcealmentInfo->attGrpOffset[mode];
  srcWin = srcGrpStart + pConcealmentInfo->winGrpOffset[mode];

  FDK_ASSERT((srcGrpStart * windowLen + windowLen) <= samplesPerFrame);
  FDK_ASSERT((srcWin * windowLen + windowLen) <= 1024);

  for (dstWin = 0; dstWin < numWindows; dstWin += 1) {
    FIXP_CNCL *pCncl =
        pConcealmentInfo->spectralCoefficient + (srcWin * windowLen);
    FIXP_DBL *pOut = pSpectralCoefficient + (dstWin * windowLen);

    if (mode == 1) {
      /* mute if attIdx gets large enaugh */
      if (attIdx > pConcealmentInfo->pConcealParams->numFadeOutFrames) {
        FDKmemclear(pCncl, sizeof(FIXP_DBL) * windowLen);
      }

      /* restore frequency coefficients from buffer - attenuation is done later
       */
      for (i = 0; i < windowLen; i++) {
        pOut[i] = pCncl[i];
      }

      /* apply random change of sign for spectral coefficients */
      CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, pOut,
                                   windowLen);

      /* Increment random phase index to avoid repetition artifacts. */
      pConcealmentInfo->iRandomPhase =
          (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);

      /* set old scale factors */
      pSpecScale[dstWin * winIdxStride] =
          pConcealmentInfo->specScale[srcWin * winIdxStride];
    }

    srcWin += 1;

    if (srcWin >= numWindows) {
      /* end of sequence -> rewind to first window of group */
      srcWin = srcGrpStart;
      numWinGrpPerFac += 1;
      if (numWinGrpPerFac >= attIdxStride) {
        numWinGrpPerFac = 0;
        attIdx += 1;
      }
    }
  }

  /* store current state */

  pConcealmentInfo->winGrpOffset[mode] = srcWin - srcGrpStart;
  FDK_ASSERT((pConcealmentInfo->winGrpOffset[mode] >= 0) &&
             (pConcealmentInfo->winGrpOffset[mode] < 8));
  pConcealmentInfo->attGrpOffset[mode] = numWinGrpPerFac;
  FDK_ASSERT((pConcealmentInfo->attGrpOffset[mode] >= 0) &&
             (pConcealmentInfo->attGrpOffset[mode] < attIdxStride));

  if (mode == 0) {
    pConcealmentInfo->cntFadeFrames = attIdx;
  }

  appliedProcessing = 1;

  return appliedProcessing;
}

/*!
  \brief Do Time domain fading (TDFading) in concealment case

  In case of concealment, this function takes care of the fading, after time
domain signal has been rendered by the respective signal rendering functions.
  The fading out in case of ACELP decoding is not done by this function but by
the ACELP decoder for the first concealed frame if CONCEAL_CORE_IGNORANT_FADE is
not set.

  TimeDomain fading never creates jumps in energy / discontinuities, it always
does a continuous fading. To achieve this, fading is always done from a starting
point to a target point, while the starting point is always determined to be the
last target point. By varying the target point of a fading, the fading slope can
be controlled.

  This principle is applied to the fading within a frame and the fading from
frame to frame.

  One frame is divided into 8 subframes to obtain 8 parts of fading slopes
within a frame, each maybe with its own gradient.

  Workflow:
  1.) Determine Fading behavior and end-of-frame target fading level, based on
concealmentState (determined by CConcealment_UpdateState()) and the core mode.
        - By _DEFAULT_,
          The target fading level is determined by fadeOutFactor[cntFadeFrames]
in case of fadeOut, or fadeInFactor[cntFadeFrames] in case of fadeIn.
          --> fading type is FADE_TIMEDOMAIN in this case. Target fading level
is determined by fading index cntFadeFrames.

        - If concealmentState is signalling a _MUTED SIGNAL_,
          TDFading decays to 0 within 1/8th of a frame if numFadeOutFrames == 0.
          --> fading type is FADE_TIMEDOMAIN_TOSPECTRALMUTE in this case.

        - If concealmentState is signalling the _END OF MUTING_,
          TDFading fades to target fading level within 1/8th of a frame if
numFadeInFrames == 0.
          --> fading type is FADE_TIMEDOMAIN_FROMSPECTRALMUTE in this case.
Target fading level is determined by fading index cntFadeFrames.

#ifndef CONCEAL_CORE_IGNORANT_FADE
        - In case of an _ACELP FADEOUT_,
          TDFading leaves fading control to ACELP decoder for 1/2 frame.
          --> fading type is FADE_ACELPDOMAIN in this case.
#endif

  2.) Render fading levels within current frame and do the final fading:
      Map Fading slopes to fading levels and apply to time domain signal.


*/

INT CConcealment_TDFading(
    int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
    FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) {
  /*
  Do the fading in Time domain based on concealment states and core mode
  */
  FIXP_DBL fadeStop, attMute = (FIXP_DBL)0;
  int idx = 0, ii;
  CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
      *ppAacDecoderStaticChannelInfo;
  CConcealmentInfo *pConcealmentInfo =
      &pAacDecoderStaticChannelInfo->concealmentInfo;
  CConcealParams *pConcealParams = pConcealmentInfo->pConcealParams;
  const CConcealmentState concealState = pConcealmentInfo->concealState;
  TDfadingType fadingType;
  FIXP_DBL fadingStations[9] = {0};
  int fadingSteps[8] = {0};
  const FIXP_DBL fadeStart =
      pConcealmentInfo
          ->fade_old; /* start fading at last end-of-frame attenuation */
  FIXP_SGL *fadeFactor = pConcealParams->fadeOutFactor;
  const INT cntFadeFrames = pConcealmentInfo->cntFadeFrames;
  int TDFadeOutStopBeforeMute = 1;
  int TDFadeInStopBeforeFullLevel = 1;

  /*
  determine Fading behaviour (end-of-frame attenuation and fading type) (1.)
  */

  switch (concealState) {
    case ConcealState_Single:
    case ConcealState_Mute:
    case ConcealState_FadeOut:
      idx = (pConcealParams->method == ConcealMethodNoise) ? cntFadeFrames - 1
                                                           : cntFadeFrames;
      fadingType = FADE_TIMEDOMAIN;

      if (concealState == ConcealState_Mute ||
          (cntFadeFrames + TDFadeOutStopBeforeMute) >
              pConcealmentInfo->pConcealParams->numFadeOutFrames) {
        fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
      }

      break;
    case ConcealState_FadeIn:
      idx = cntFadeFrames;
      idx -= TDFadeInStopBeforeFullLevel;
      FDK_FALLTHROUGH;
    case ConcealState_Ok:
      fadeFactor = pConcealParams->fadeInFactor;
      idx = (concealState == ConcealState_Ok) ? -1 : idx;
      fadingType = (pConcealmentInfo->concealState_old == ConcealState_Mute)
                       ? FADE_TIMEDOMAIN_FROMSPECTRALMUTE
                       : FADE_TIMEDOMAIN;
      break;
    default:
      FDK_ASSERT(0);
      fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
      break;
  }

  /* determine Target end-of-frame fading level and fading slope */
  switch (fadingType) {
    case FADE_TIMEDOMAIN_FROMSPECTRALMUTE:
      fadeStop =
          (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
      if (pConcealmentInfo->pConcealParams->numFadeInFrames == 0) {
        /* do step as fast as possible */
        fadingSteps[0] = 1;
        break;
      }
      CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
      break;
    case FADE_TIMEDOMAIN:
      fadeStop =
          (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
      CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
      break;
    case FADE_TIMEDOMAIN_TOSPECTRALMUTE:
      fadeStop = attMute;
      if (pConcealmentInfo->pConcealParams->numFadeOutFrames == 0) {
        /* do step as fast as possible */
        fadingSteps[0] = 1;
        break;
      }
      CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
      break;
  }

  /*
  Render fading levels within current frame and do the final fading (2.)
  */

  len >>= 3;
  CConcealment_TDFadeFillFadingStations(fadingStations, fadingSteps, fadeStop,
                                        fadeStart, fadingType);

  if ((fadingStations[8] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[7] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[6] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[5] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[4] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[3] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[2] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[1] != (FIXP_DBL)MAXVAL_DBL) ||
      (fadingStations[0] !=
       (FIXP_DBL)MAXVAL_DBL)) /* if there's something to fade */
  {
    int start = 0;
    for (ii = 0; ii < 8; ii++) {
      CConcealment_TDFadePcmAtt(start, len, fadingStations[ii],
                                fadingStations[ii + 1], pcmdata);
      start += len;
    }
  }
  CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata);

  /* Save end-of-frame attenuation and fading type */
  pConcealmentInfo->lastFadingType = fadingType;
  pConcealmentInfo->fade_old = fadeStop;
  pConcealmentInfo->concealState_old = concealState;

  return 1;
}

/* attenuate pcmdata in Time Domain Fading process */
static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
                                      FIXP_DBL fadeStop, FIXP_PCM *pcmdata) {
  int i;
  FIXP_DBL dStep;
  FIXP_DBL dGain;
  FIXP_DBL dGain_apply;
  int bitshift = (DFRACT_BITS - SAMPLE_BITS);

  /* set start energy */
  dGain = fadeStart;
  /* determine energy steps from sample to sample */
  dStep = (FIXP_DBL)((int)((fadeStart >> 1) - (fadeStop >> 1)) / len) << 1;

  for (i = start; i < (start + len); i++) {
    dGain -= dStep;
    /* prevent gain from getting negative due to possible fixpoint inaccuracies
     */
    dGain_apply = fMax((FIXP_DBL)0, dGain);
    /* finally, attenuate samples */
    pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift);
  }
}

/*
\brief Fill FadingStations

The fadingstations are the attenuation factors, being applied to its dedicated
portions of pcm data. They are calculated using the fadingsteps. One fadingstep
is the weighted contribution to the fading slope within its dedicated portion of
pcm data.

*Fadingsteps  :      0  0  0  1  0  1  2  0

                  |<-  1 Frame pcm data ->|
      fadeStart-->|__________             |
                  ^  ^  ^  ^ \____        |
 Attenuation  :   |  |  |  |  ^  ^\__     |
                  |  |  |  |  |  |  ^\    |
                  |  |  |  |  |  |  | \___|<-- fadeStop
                  |  |  |  |  |  |  |  ^  ^
                  |  |  |  |  |  |  |  |  |
Fadingstations:  [0][1][2][3][4][5][6][7][8]

(Fadingstations "[0]" is "[8] from previous frame", therefore its not meaningful
to be edited)

*/
static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
                                                  int *fadingSteps,
                                                  FIXP_DBL fadeStop,
                                                  FIXP_DBL fadeStart,
                                                  TDfadingType fadingType) {
  int i;
  INT fadingSteps_sum = 0;
  INT fadeDiff;

  fadingSteps_sum = fadingSteps[0] + fadingSteps[1] + fadingSteps[2] +
                    fadingSteps[3] + fadingSteps[4] + fadingSteps[5] +
                    fadingSteps[6] + fadingSteps[7];
  fadeDiff = ((INT)(fadeStop - fadeStart) / fMax(fadingSteps_sum, (INT)1));
  fadingStations[0] = fadeStart;
  for (i = 1; i < 8; i++) {
    fadingStations[i] =
        fadingStations[i - 1] + (FIXP_DBL)(fadeDiff * fadingSteps[i - 1]);
  }
  fadingStations[8] = fadeStop;
}

static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps) {
  fadingSteps[0] = fadingSteps[1] = fadingSteps[2] = fadingSteps[3] =
      fadingSteps[4] = fadingSteps[5] = fadingSteps[6] = fadingSteps[7] = 1;
}

/* end of TimeDomainFading functions */

/* derived from int UsacRandomSign() */
static int CConcealment_TDNoise_Random(ULONG *seed) {
  *seed = (ULONG)(((UINT64)(*seed) * 69069) + 5);
  return (int)(*seed);
}

static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
                                       const int len, FIXP_PCM *const pcmdata) {
  FIXP_PCM *states = pConcealmentInfo->TDNoiseStates;
  FIXP_PCM noiseVal;
  FIXP_DBL noiseValLong;
  FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
  FIXP_DBL TDNoiseAtt;
  ULONG seed = pConcealmentInfo->TDNoiseSeed =
      (ULONG)CConcealment_TDNoise_Random(&pConcealmentInfo->TDNoiseSeed) + 1;

  TDNoiseAtt = pConcealmentInfo->pConcealParams->comfortNoiseLevel;

  int ii;

  if ((pConcealmentInfo->concealState != ConcealState_Ok ||
       pConcealmentInfo->concealState_old != ConcealState_Ok) &&
      TDNoiseAtt != (FIXP_DBL)0) {
    for (ii = 0; ii < (len << 3); ii++) {
      /* create filtered noise */
      states[2] = states[1];
      states[1] = states[0];
      states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed));
      noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) +
                     fMult(states[2], coef[2]);
      noiseVal = FX_DBL2FX_PCM(fMult(noiseValLong, TDNoiseAtt));

      /* add filtered noise - check for clipping, before */
      if (noiseVal > (FIXP_PCM)0 &&
          pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) {
        noiseVal = noiseVal * (FIXP_PCM)-1;
      } else if (noiseVal < (FIXP_PCM)0 &&
                 pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) {
        noiseVal = noiseVal * (FIXP_PCM)-1;
      }

      pcmdata[ii] += noiseVal;
    }
  }
}
