/* -----------------------------------------------------------------------------
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: long/short-block decoding

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

#include "block.h"

#include "aac_rom.h"
#include "FDK_bitstream.h"
#include "scale.h"
#include "FDK_tools_rom.h"

#include "usacdec_fac.h"
#include "usacdec_lpd.h"
#include "usacdec_lpc.h"
#include "FDK_trigFcts.h"

#include "ac_arith_coder.h"

#include "aacdec_hcr.h"
#include "rvlc.h"

#if defined(__arm__)
#include "arm/block_arm.cpp"
#endif

/*!
  \brief Read escape sequence of codeword

  The function reads the escape sequence from the bitstream,
  if the absolute value of the quantized coefficient has the
  value 16.
  A limitation is implemented to maximal 31 bits to prevent endless loops.
  If it strikes, MAX_QUANTIZED_VALUE + 1 is returned, independent of the sign of
  parameter q.

  \return  quantized coefficient
*/
LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
                      const LONG q)            /*!< quantized coefficient */
{
  if (fAbs(q) != 16) return (q);

  LONG i, off;
  for (i = 4; i < 32; i++) {
    if (FDKreadBit(bs) == 0) break;
  }

  if (i == 32) return (MAX_QUANTIZED_VALUE + 1);

  off = FDKreadBits(bs, i);
  i = off + (1 << i);

  if (q < 0) i = -i;

  return i;
}

AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
    CAacDecoderChannelInfo *pAacDecoderChannelInfo, HANDLE_FDK_BITSTREAM bs,
    UINT flags) {
  int temp;
  int band;
  int group;
  int position = 0; /* accu for intensity delta coding */
  int factor = pAacDecoderChannelInfo->pDynData->RawDataInfo
                   .GlobalGain; /* accu for scale factor delta coding */
  UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
  SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
  const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];

  const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;

  int ScaleFactorBandsTransmitted =
      GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
  for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
       group++) {
    for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
      switch (pCodeBook[band]) {
        case ZERO_HCB: /* zero book */
          pScaleFactor[band] = 0;
          break;

        default: /* decode scale factor */
          if (!((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) && band == 0 &&
                group == 0)) {
            temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
            factor += temp - 60; /* MIDFAC 1.5 dB */
          }
          pScaleFactor[band] = factor - 100;
          break;

        case INTENSITY_HCB: /* intensity steering */
        case INTENSITY_HCB2:
          temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
          position += temp - 60;
          pScaleFactor[band] = position - 100;
          break;

        case NOISE_HCB: /* PNS */
          if (flags & (AC_MPEGD_RES | AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
            return AAC_DEC_PARSE_ERROR;
          }
          CPns_Read(&pAacDecoderChannelInfo->data.aac.PnsData, bs, hcb,
                    pAacDecoderChannelInfo->pDynData->aScaleFactor,
                    pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain,
                    band, group);
          break;
      }
    }
    pCodeBook += 16;
    pScaleFactor += 16;
  }

  return AAC_DEC_OK;
}

void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
                              UCHAR maxSfbs,
                              SamplingRateInfo *pSamplingRateInfo) {
  int band;
  int window;
  const SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
  SHORT *RESTRICT pSpecScale = pAacDecoderChannelInfo->specScale;
  int groupwin, group;
  const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
      &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
  SPECTRAL_PTR RESTRICT pSpectralCoefficient =
      pAacDecoderChannelInfo->pSpectralCoefficient;

  FDKmemclear(pSpecScale, 8 * sizeof(SHORT));

  for (window = 0, group = 0;
       group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
    for (groupwin = 0; groupwin < GetWindowGroupLength(
                                      &pAacDecoderChannelInfo->icsInfo, group);
         groupwin++, window++) {
      int SpecScale_window = pSpecScale[window];
      FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window,
                                 pAacDecoderChannelInfo->granuleLength);

      /* find scaling for current window */
      for (band = 0; band < maxSfbs; band++) {
        SpecScale_window =
            fMax(SpecScale_window, (int)pSfbScale[window * 16 + band]);
      }

      if (pAacDecoderChannelInfo->pDynData->TnsData.Active &&
          pAacDecoderChannelInfo->pDynData->TnsData.NumberOfFilters[window] >
              0) {
        int filter_index, SpecScale_window_tns;
        int tns_start, tns_stop;

        /* Find max scale of TNS bands */
        SpecScale_window_tns = 0;
        tns_start = GetMaximumTnsBands(&pAacDecoderChannelInfo->icsInfo,
                                       pSamplingRateInfo->samplingRateIndex);
        tns_stop = 0;
        for (filter_index = 0;
             filter_index < (int)pAacDecoderChannelInfo->pDynData->TnsData
                                .NumberOfFilters[window];
             filter_index++) {
          for (band = pAacDecoderChannelInfo->pDynData->TnsData
                          .Filter[window][filter_index]
                          .StartBand;
               band < pAacDecoderChannelInfo->pDynData->TnsData
                          .Filter[window][filter_index]
                          .StopBand;
               band++) {
            SpecScale_window_tns =
                fMax(SpecScale_window_tns, (int)pSfbScale[window * 16 + band]);
          }
          /* Find TNS line boundaries for all TNS filters */
          tns_start =
              fMin(tns_start, (int)pAacDecoderChannelInfo->pDynData->TnsData
                                  .Filter[window][filter_index]
                                  .StartBand);
          tns_stop =
              fMax(tns_stop, (int)pAacDecoderChannelInfo->pDynData->TnsData
                                 .Filter[window][filter_index]
                                 .StopBand);
        }
        SpecScale_window_tns = SpecScale_window_tns +
                               pAacDecoderChannelInfo->pDynData->TnsData.GainLd;
        FDK_ASSERT(tns_stop >= tns_start);
        /* Consider existing headroom of all MDCT lines inside the TNS bands. */
        SpecScale_window_tns -=
            getScalefactor(pSpectrum + BandOffsets[tns_start],
                           BandOffsets[tns_stop] - BandOffsets[tns_start]);
        if (SpecScale_window <= 17) {
          SpecScale_window_tns++;
        }
        /* Add enough mantissa head room such that the spectrum is still
           representable after applying TNS. */
        SpecScale_window = fMax(SpecScale_window, SpecScale_window_tns);
      }

      /* store scaling of current window */
      pSpecScale[window] = SpecScale_window;

#ifdef FUNCTION_CBlock_ScaleSpectralData_func1

      CBlock_ScaleSpectralData_func1(pSpectrum, maxSfbs, BandOffsets,
                                     SpecScale_window, pSfbScale, window);

#else  /* FUNCTION_CBlock_ScaleSpectralData_func1 */
      for (band = 0; band < maxSfbs; band++) {
        int scale = fMin(DFRACT_BITS - 1,
                         SpecScale_window - pSfbScale[window * 16 + band]);
        if (scale) {
          FDK_ASSERT(scale > 0);

          /* following relation can be used for optimizations:
           * (BandOffsets[i]%4) == 0 for all i */
          int max_index = BandOffsets[band + 1];
          DWORD_ALIGNED(pSpectrum);
          for (int index = BandOffsets[band]; index < max_index; index++) {
            pSpectrum[index] >>= scale;
          }
        }
      }
#endif /* FUNCTION_CBlock_ScaleSpectralData_func1 */
    }
  }
}

AAC_DECODER_ERROR CBlock_ReadSectionData(
    HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
  int top, band;
  int sect_len, sect_len_incr;
  int group;
  UCHAR sect_cb;
  UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
  /* HCR input (long) */
  SHORT *pNumLinesInSec =
      pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
  int numLinesInSecIdx = 0;
  UCHAR *pHcrCodeBook =
      pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
  const SHORT *BandOffsets = GetScaleFactorBandOffsets(
      &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
  pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection = 0;
  AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;

  FDKmemclear(pCodeBook, sizeof(UCHAR) * (8 * 16));

  const int nbits =
      (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;

  int sect_esc_val = (1 << nbits) - 1;

  UCHAR ScaleFactorBandsTransmitted =
      GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
  for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
       group++) {
    for (band = 0; band < ScaleFactorBandsTransmitted;) {
      sect_len = 0;
      if (flags & AC_ER_VCB11) {
        sect_cb = (UCHAR)FDKreadBits(bs, 5);
      } else
        sect_cb = (UCHAR)FDKreadBits(bs, 4);

      if (((flags & AC_ER_VCB11) == 0) || (sect_cb < 11) ||
          ((sect_cb > 11) && (sect_cb < 16))) {
        sect_len_incr = FDKreadBits(bs, nbits);
        while (sect_len_incr == sect_esc_val) {
          sect_len += sect_esc_val;
          sect_len_incr = FDKreadBits(bs, nbits);
        }
      } else {
        sect_len_incr = 1;
      }

      sect_len += sect_len_incr;

      top = band + sect_len;

      if (flags & AC_ER_HCR) {
        /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
        if (numLinesInSecIdx >= MAX_SFB_HCR) {
          return AAC_DEC_PARSE_ERROR;
        }
        if (top > (int)GetNumberOfScaleFactorBands(
                      &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo)) {
          return AAC_DEC_PARSE_ERROR;
        }
        pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
        numLinesInSecIdx++;
        if (sect_cb == BOOKSCL) {
          return AAC_DEC_INVALID_CODE_BOOK;
        } else {
          *pHcrCodeBook++ = sect_cb;
        }
        pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection++;
      }

      /* Check spectral line limits */
      if (IsLongBlock(&(pAacDecoderChannelInfo->icsInfo))) {
        if (top > 64) {
          return AAC_DEC_DECODE_FRAME_ERROR;
        }
      } else { /* short block */
        if (top + group * 16 > (8 * 16)) {
          return AAC_DEC_DECODE_FRAME_ERROR;
        }
      }

      /* Check if decoded codebook index is feasible */
      if ((sect_cb == BOOKSCL) ||
          ((sect_cb == INTENSITY_HCB || sect_cb == INTENSITY_HCB2) &&
           pAacDecoderChannelInfo->pDynData->RawDataInfo.CommonWindow == 0)) {
        return AAC_DEC_INVALID_CODE_BOOK;
      }

      /* Store codebook index */
      for (; band < top; band++) {
        pCodeBook[group * 16 + band] = sect_cb;
      }
    }
  }

  return ErrorStatus;
}

/* mso: provides a faster way to i-quantize a whole band in one go */

/**
 * \brief inverse quantize one sfb. Each value of the sfb is processed according
 * to the formula: spectrum[i] = Sign(spectrum[i]) * Matissa(spectrum[i])^(4/3)
 * * 2^(lsb/4).
 * \param spectrum pointer to first line of the sfb to be inverse quantized.
 * \param noLines number of lines belonging to the sfb.
 * \param lsb last 2 bits of the scale factor of the sfb.
 * \param scale max allowed shift scale for the sfb.
 */
static inline void InverseQuantizeBand(
    FIXP_DBL *RESTRICT spectrum, const FIXP_DBL *RESTRICT InverseQuantTabler,
    const FIXP_DBL *RESTRICT MantissaTabler,
    const SCHAR *RESTRICT ExponentTabler, INT noLines, INT scale) {
  scale = scale + 1; /* +1 to compensate fMultDiv2 shift-right in loop */

  FIXP_DBL *RESTRICT ptr = spectrum;
  FIXP_DBL signedValue;

  for (INT i = noLines; i--;) {
    if ((signedValue = *ptr++) != FL2FXCONST_DBL(0)) {
      FIXP_DBL value = fAbs(signedValue);
      UINT freeBits = CntLeadingZeros(value);
      UINT exponent = 32 - freeBits;

      UINT x = (UINT)(LONG)value << (INT)freeBits;
      x <<= 1; /* shift out sign bit to avoid masking later on */
      UINT tableIndex = x >> 24;
      x = (x >> 20) & 0x0F;

      UINT r0 = (UINT)(LONG)InverseQuantTabler[tableIndex + 0];
      UINT r1 = (UINT)(LONG)InverseQuantTabler[tableIndex + 1];
      UINT temp = (r1 - r0) * x + (r0 << 4);

      value = fMultDiv2((FIXP_DBL)temp, MantissaTabler[exponent]);

      /* + 1 compensates fMultDiv2() */
      scaleValueInPlace(&value, scale + ExponentTabler[exponent]);

      signedValue = (signedValue < (FIXP_DBL)0) ? -value : value;
      ptr[-1] = signedValue;
    }
  }
}

static inline FIXP_DBL maxabs_D(const FIXP_DBL *pSpectralCoefficient,
                                const int noLines) {
  /* Find max spectral line value of the current sfb */
  FIXP_DBL locMax = (FIXP_DBL)0;
  int i;

  DWORD_ALIGNED(pSpectralCoefficient);

  for (i = noLines; i-- > 0;) {
    /* Expensive memory access */
    locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax);
  }

  return locMax;
}

AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    SamplingRateInfo *pSamplingRateInfo, UCHAR *band_is_noise,
    UCHAR active_band_search) {
  int window, group, groupwin, band;
  int ScaleFactorBandsTransmitted =
      GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
  UCHAR *RESTRICT pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
  SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
  SHORT *RESTRICT pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
  const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
      &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
  const SHORT total_bands =
      GetScaleFactorBandsTotal(&pAacDecoderChannelInfo->icsInfo);

  FDKmemclear(pAacDecoderChannelInfo->pDynData->aSfbScale,
              (8 * 16) * sizeof(SHORT));

  for (window = 0, group = 0;
       group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
    for (groupwin = 0; groupwin < GetWindowGroupLength(
                                      &pAacDecoderChannelInfo->icsInfo, group);
         groupwin++, window++) {
      /* inverse quantization */
      for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
        FIXP_DBL *pSpectralCoefficient =
            SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
                 pAacDecoderChannelInfo->granuleLength) +
            BandOffsets[band];
        FIXP_DBL locMax;

        const int noLines = BandOffsets[band + 1] - BandOffsets[band];
        const int bnds = group * 16 + band;

        if ((pCodeBook[bnds] == ZERO_HCB) ||
            (pCodeBook[bnds] == INTENSITY_HCB) ||
            (pCodeBook[bnds] == INTENSITY_HCB2))
          continue;

        if (pCodeBook[bnds] == NOISE_HCB) {
          /* Leave headroom for PNS values. + 1 because ceil(log2(2^(0.25*3))) =
             1, worst case of additional headroom required because of the
             scalefactor. */
          pSfbScale[window * 16 + band] = (pScaleFactor[bnds] >> 2) + 1;
          continue;
        }

        locMax = maxabs_D(pSpectralCoefficient, noLines);

        if (active_band_search) {
          if (locMax != FIXP_DBL(0)) {
            band_is_noise[group * 16 + band] = 0;
          }
        }

        /* Cheap robustness improvement - Do not remove!!! */
        if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
          return AAC_DEC_PARSE_ERROR;
        }

        /* Added by Youliy Ninov:
        The inverse quantization operation is given by (ISO/IEC 14496-3:2009(E))
        by:

        x_invquant=Sign(x_quant). abs(x_quant)^(4/3)

        We apply a gain, derived from the scale factor for the particular sfb,
        according to the following function:

        gain=2^(0.25*ScaleFactor)

        So, after scaling we have:

        x_rescale=gain*x_invquant=Sign(x_quant)*2^(0.25*ScaleFactor)*abs(s_quant)^(4/3)

        We could represent the ScaleFactor as:

        ScaleFactor= (ScaleFactor >> 2)*4 + ScaleFactor %4

        When we substitute it we get:

        x_rescale=Sign(x_quant)*2^(ScaleFactor>>2)* (
        2^(0.25*(ScaleFactor%4))*abs(s_quant)^(4/3))

        When we set: msb=(ScaleFactor>>2) and lsb=(ScaleFactor%4), we obtain:

        x_rescale=Sign(x_quant)*(2^msb)* ( 2^(lsb/4)*abs(s_quant)^(4/3))

        The rescaled output can be represented by:
           mantissa : Sign(x_quant)*( 2^(lsb/4)*abs(s_quant)^(4/3))
           exponent :(2^msb)

        */

        int msb = pScaleFactor[bnds] >> 2;

        /* Inverse quantize band only if it is not empty */
        if (locMax != FIXP_DBL(0)) {
          int lsb = pScaleFactor[bnds] & 0x03;

          int scale = EvaluatePower43(&locMax, lsb);

          scale = CntLeadingZeros(locMax) - scale - 2;

          pSfbScale[window * 16 + band] = msb - scale;
          InverseQuantizeBand(pSpectralCoefficient, InverseQuantTable,
                              MantissaTable[lsb], ExponentTable[lsb], noLines,
                              scale);
        } else {
          pSfbScale[window * 16 + band] = msb;
        }

      } /* for (band=0; band < ScaleFactorBandsTransmitted; band++) */

      /* Make sure the array is cleared to the end */
      SHORT start_clear = BandOffsets[ScaleFactorBandsTransmitted];
      SHORT end_clear = BandOffsets[total_bands];
      int diff_clear = (int)(end_clear - start_clear);
      FIXP_DBL *pSpectralCoefficient =
          SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
               pAacDecoderChannelInfo->granuleLength) +
          start_clear;
      FDKmemclear(pSpectralCoefficient, diff_clear * sizeof(FIXP_DBL));

    } /* for (groupwin=0; groupwin <
         GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group);
         groupwin++, window++) */
  }   /* for (window=0, group=0; group <
         GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)*/

  return AAC_DEC_OK;
}

AAC_DECODER_ERROR CBlock_ReadSpectralData(
    HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
  int index, i;
  const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
      &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);

  SPECTRAL_PTR pSpectralCoefficient =
      pAacDecoderChannelInfo->pSpectralCoefficient;

  FDK_ASSERT(BandOffsets != NULL);

  FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM));

  if ((flags & AC_ER_HCR) == 0) {
    int group;
    int groupoffset;
    UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
    int ScaleFactorBandsTransmitted =
        GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
    int granuleLength = pAacDecoderChannelInfo->granuleLength;

    groupoffset = 0;

    /* plain huffman decoder  short */
    int max_group = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);

    for (group = 0; group < max_group; group++) {
      int max_groupwin =
          GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
      int band;

      int bnds = group * 16;

      int bandOffset1 = BandOffsets[0];
      for (band = 0; band < ScaleFactorBandsTransmitted; band++, bnds++) {
        UCHAR currentCB = pCodeBook[bnds];
        int bandOffset0 = bandOffset1;
        bandOffset1 = BandOffsets[band + 1];

        /* patch to run plain-huffman-decoder with vcb11 input codebooks
         * (LAV-checking might be possible below using the virtual cb and a
         * LAV-table) */
        if ((currentCB >= 16) && (currentCB <= 31)) {
          pCodeBook[bnds] = currentCB = 11;
        }
        if (((currentCB != ZERO_HCB) && (currentCB != NOISE_HCB) &&
             (currentCB != INTENSITY_HCB) && (currentCB != INTENSITY_HCB2))) {
          const CodeBookDescription *hcb =
              &AACcodeBookDescriptionTable[currentCB];
          int step = hcb->Dimension;
          int offset = hcb->Offset;
          int bits = hcb->numBits;
          int mask = (1 << bits) - 1;
          const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
          int groupwin;

          FIXP_DBL *mdctSpectrum =
              &pSpectralCoefficient[groupoffset * granuleLength];

          if (offset == 0) {
            for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
              for (index = bandOffset0; index < bandOffset1; index += step) {
                int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
                for (i = 0; i < step; i++, idx >>= bits) {
                  FIXP_DBL tmp = (FIXP_DBL)((idx & mask) - offset);
                  if (tmp != FIXP_DBL(0)) tmp = (FDKreadBit(bs)) ? -tmp : tmp;
                  mdctSpectrum[index + i] = tmp;
                }

                if (currentCB == ESCBOOK) {
                  for (int j = 0; j < 2; j++)
                    mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
                        bs, (LONG)mdctSpectrum[index + j]);
                }
              }
              mdctSpectrum += granuleLength;
            }
          } else {
            for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
              for (index = bandOffset0; index < bandOffset1; index += step) {
                int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
                for (i = 0; i < step; i++, idx >>= bits) {
                  mdctSpectrum[index + i] = (FIXP_DBL)((idx & mask) - offset);
                }
                if (currentCB == ESCBOOK) {
                  for (int j = 0; j < 2; j++)
                    mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
                        bs, (LONG)mdctSpectrum[index + j]);
                }
              }
              mdctSpectrum += granuleLength;
            }
          }
        }
      }
      groupoffset += max_groupwin;
    }
    /* plain huffman decoding (short) finished */
  }

  /* HCR - Huffman Codeword Reordering  short */
  else /* if ( flags & AC_ER_HCR ) */

  {
    H_HCR_INFO hHcr = &pAacDecoderChannelInfo->pComData->overlay.aac.erHcrInfo;

    int hcrStatus = 0;

    /* advanced Huffman decoding starts here (HCR decoding :) */
    if (pAacDecoderChannelInfo->pDynData->specificTo.aac
            .lenOfReorderedSpectralData != 0) {
      /* HCR initialization short */
      hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);

      if (hcrStatus != 0) {
        return AAC_DEC_DECODE_FRAME_ERROR;
      }

      /* HCR decoding short */
      hcrStatus =
          HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);

      if (hcrStatus != 0) {
#if HCR_ERROR_CONCEALMENT
        HcrMuteErroneousLines(hHcr);
#else
        return AAC_DEC_DECODE_FRAME_ERROR;
#endif /* HCR_ERROR_CONCEALMENT */
      }

      FDKpushFor(bs, pAacDecoderChannelInfo->pDynData->specificTo.aac
                         .lenOfReorderedSpectralData);
    }
  }
  /* HCR - Huffman Codeword Reordering short finished */

  if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) &&
      !(flags & (AC_ELD | AC_SCALABLE))) {
    /* apply pulse data */
    CPulseData_Apply(
        &pAacDecoderChannelInfo->pDynData->specificTo.aac.PulseData,
        GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
                                  pSamplingRateInfo),
        SPEC_LONG(pSpectralCoefficient));
  }

  return AAC_DEC_OK;
}

static const FIXP_SGL noise_level_tab[8] = {
    /* FDKpow(2, (float)(noise_level-14)/3.0f) * 2; (*2 to compensate for
       fMultDiv2) noise_level_tab(noise_level==0) == 0 by definition
    */
    FX_DBL2FXCONST_SGL(0x00000000 /*0x0a145173*/),
    FX_DBL2FXCONST_SGL(0x0cb2ff5e),
    FX_DBL2FXCONST_SGL(0x10000000),
    FX_DBL2FXCONST_SGL(0x1428a2e7),
    FX_DBL2FXCONST_SGL(0x1965febd),
    FX_DBL2FXCONST_SGL(0x20000000),
    FX_DBL2FXCONST_SGL(0x28514606),
    FX_DBL2FXCONST_SGL(0x32cbfd33)};

void CBlock_ApplyNoise(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
                       SamplingRateInfo *pSamplingRateInfo, ULONG *nfRandomSeed,
                       UCHAR *band_is_noise) {
  const SHORT *swb_offset = GetScaleFactorBandOffsets(
      &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
  int g, win, gwin, sfb, noiseFillingStartOffset, nfStartOffset_sfb;

  /* Obtain noise level and scale factor offset. */
  int noise_level = pAacDecoderChannelInfo->pDynData->specificTo.usac
                        .fd_noise_level_and_offset >>
                    5;
  const FIXP_SGL noiseVal_pos = noise_level_tab[noise_level];

  /* noise_offset can change even when noise_level=0. Neccesary for IGF stereo
   * filling */
  const int noise_offset = (pAacDecoderChannelInfo->pDynData->specificTo.usac
                                .fd_noise_level_and_offset &
                            0x1f) -
                           16;

  int max_sfb =
      GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);

  noiseFillingStartOffset =
      (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
          ? 20
          : 160;
  if (pAacDecoderChannelInfo->granuleLength == 96) {
    noiseFillingStartOffset =
        (3 * noiseFillingStartOffset) /
        4; /* scale offset with 3/4 for coreCoderFrameLength == 768 */
  }

  /* determine sfb from where on noise filling is applied */
  for (sfb = 0; swb_offset[sfb] < noiseFillingStartOffset; sfb++)
    ;
  nfStartOffset_sfb = sfb;

  /* if (noise_level!=0) */
  {
    for (g = 0, win = 0; g < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
         g++) {
      int windowGroupLength =
          GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, g);
      for (sfb = nfStartOffset_sfb; sfb < max_sfb; sfb++) {
        int bin_start = swb_offset[sfb];
        int bin_stop = swb_offset[sfb + 1];

        int flagN = band_is_noise[g * 16 + sfb];

        /* if all bins of one sfb in one window group are zero modify the scale
         * factor by noise_offset */
        if (flagN) {
          /* Change scaling factors for empty signal bands */
          pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] +=
              noise_offset;
          /* scale factor "sf" implied gain "g" is g = 2^(sf/4) */
          for (gwin = 0; gwin < windowGroupLength; gwin++) {
            pAacDecoderChannelInfo->pDynData
                ->aSfbScale[(win + gwin) * 16 + sfb] += (noise_offset >> 2);
          }
        }

        ULONG seed = *nfRandomSeed;
        /* + 1 because exponent of MantissaTable[lsb][0] is always 1. */
        int scale =
            (pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] >>
             2) +
            1;
        int lsb =
            pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] & 3;
        FIXP_DBL mantissa = MantissaTable[lsb][0];

        for (gwin = 0; gwin < windowGroupLength; gwin++) {
          FIXP_DBL *pSpec =
              SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, win + gwin,
                   pAacDecoderChannelInfo->granuleLength);

          int scale1 = scale - pAacDecoderChannelInfo->pDynData
                                   ->aSfbScale[(win + gwin) * 16 + sfb];
          FIXP_DBL scaled_noiseVal_pos =
              scaleValue(fMultDiv2(noiseVal_pos, mantissa), scale1);
          FIXP_DBL scaled_noiseVal_neg = -scaled_noiseVal_pos;

          /* If the whole band is zero, just fill without checking */
          if (flagN) {
            for (int bin = bin_start; bin < bin_stop; bin++) {
              seed = (ULONG)(
                  (UINT64)seed * 69069 +
                  5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
              pSpec[bin] =
                  (seed & 0x10000) ? scaled_noiseVal_neg : scaled_noiseVal_pos;
            } /* for (bin...) */
          }
          /*If band is sparsely filled, check for 0 and fill */
          else {
            for (int bin = bin_start; bin < bin_stop; bin++) {
              if (pSpec[bin] == (FIXP_DBL)0) {
                seed = (ULONG)(
                    (UINT64)seed * 69069 +
                    5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
                pSpec[bin] = (seed & 0x10000) ? scaled_noiseVal_neg
                                              : scaled_noiseVal_pos;
              }
            } /* for (bin...) */
          }

        } /* for (gwin...) */
        *nfRandomSeed = seed;
      } /* for (sfb...) */
      win += windowGroupLength;
    } /* for (g...) */

  } /* ... */
}

AAC_DECODER_ERROR CBlock_ReadAcSpectralData(
    HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, const UINT frame_length,
    const UINT flags) {
  AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
  ARITH_CODING_ERROR error = ARITH_CODER_OK;
  int arith_reset_flag, lg, numWin, win, winLen;
  const SHORT *RESTRICT BandOffsets;

  /* number of transmitted spectral coefficients */
  BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
                                          pSamplingRateInfo);
  lg = BandOffsets[GetScaleFactorBandsTransmitted(
      &pAacDecoderChannelInfo->icsInfo)];

  numWin = GetWindowsPerFrame(&pAacDecoderChannelInfo->icsInfo);
  winLen = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo))
               ? (int)frame_length
               : (int)frame_length / numWin;

  if (flags & AC_INDEP) {
    arith_reset_flag = 1;
  } else {
    arith_reset_flag = (USHORT)FDKreadBits(hBs, 1);
  }

  for (win = 0; win < numWin; win++) {
    error =
        CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs,
                              SPEC(pAacDecoderChannelInfo->pSpectralCoefficient,
                                   win, pAacDecoderChannelInfo->granuleLength),
                              lg, winLen, arith_reset_flag && (win == 0));
    if (error != ARITH_CODER_OK) {
      goto bail;
    }
  }

bail:
  if (error == ARITH_CODER_ERROR) {
    errorAAC = AAC_DEC_PARSE_ERROR;
  }

  return errorAAC;
}

void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
                const SamplingRateInfo *pSamplingRateInfo, const UINT flags,
                const UINT elFlags, const int channel,
                const int common_window) {
  if (!(flags & (AC_USAC | AC_RSVD50 | AC_MPEGD_RES | AC_RSV603DA))) {
    CPns_Apply(&pAacDecoderChannelInfo[channel]->data.aac.PnsData,
               &pAacDecoderChannelInfo[channel]->icsInfo,
               pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
               pAacDecoderChannelInfo[channel]->specScale,
               pAacDecoderChannelInfo[channel]->pDynData->aScaleFactor,
               pSamplingRateInfo,
               pAacDecoderChannelInfo[channel]->granuleLength, channel);
  }

  UCHAR nbands =
      GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[channel]->icsInfo);

  CTns_Apply(&pAacDecoderChannelInfo[channel]->pDynData->TnsData,
             &pAacDecoderChannelInfo[channel]->icsInfo,
             pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
             pSamplingRateInfo, pAacDecoderChannelInfo[channel]->granuleLength,
             nbands, (elFlags & AC_EL_ENHANCED_NOISE) ? 1 : 0, flags);
}

static int getWindow2Nr(int length, int shape) {
  int nr = 0;

  if (shape == 2) {
    /* Low Overlap, 3/4 zeroed */
    nr = (length * 3) >> 2;
  }

  return nr;
}

FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) {
  FIXP_DBL corr = (FIXP_DBL)0;
  FIXP_DBL ener = (FIXP_DBL)1;

  int headroom_x = getScalefactor(x, n);
  int headroom_y = getScalefactor(y, n);

  /*Calculate the normalization necessary due to addition*/
  /* Check for power of two /special case */
  INT width_shift = (INT)(fNormz((FIXP_DBL)n));
  /* Get the number of bits necessary minus one, because we need one sign bit
   * only */
  width_shift = 31 - width_shift;

  for (int i = 0; i < n; i++) {
    corr +=
        fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >> width_shift;
    ener += fPow2Div2((y[i] << headroom_y)) >> width_shift;
  }

  int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
  int exp_ener = ((17 - headroom_y) << 1) + width_shift + 1;

  int temp_exp = 0;
  FIXP_DBL output = fDivNormSigned(corr, ener, &temp_exp);

  int output_exp = (exp_corr - exp_ener) + temp_exp;

  INT output_shift = 17 - output_exp;
  output_shift = fMin(output_shift, 31);

  output = scaleValue(output, -output_shift);

  return output;
}

void CBlock_FrequencyToTime(
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
    const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
    UINT elFlags, INT elCh) {
  int fr, fl, tl, nSpec;

#if defined(FDK_ASSERT_ENABLE)
  LONG nSamples;
#endif

  /* Determine left slope length (fl), right slope length (fr) and transform
     length (tl). USAC: The slope length may mismatch with the previous frame in
     case of LPD / FD transitions. The adjustment is handled by the imdct
     implementation.
  */
  tl = frameLen;
  nSpec = 1;

  switch (pAacDecoderChannelInfo->icsInfo.WindowSequence) {
    default:
    case BLOCK_LONG:
      fl = frameLen;
      fr = frameLen -
           getWindow2Nr(frameLen,
                        GetWindowShape(&pAacDecoderChannelInfo->icsInfo));
      /* New startup needs differentiation between sine shape and low overlap
         shape. This is a special case for the LD-AAC transformation windows,
         because the slope length can be different while using the same window
         sequence. */
      if (pAacDecoderStaticChannelInfo->IMdct.prev_tl == 0) {
        fl = fr;
      }
      break;
    case BLOCK_STOP:
      fl = frameLen >> 3;
      fr = frameLen;
      break;
    case BLOCK_START: /* or StopStartSequence */
      fl = frameLen;
      fr = frameLen >> 3;
      break;
    case BLOCK_SHORT:
      fl = fr = frameLen >> 3;
      tl >>= 3;
      nSpec = 8;
      break;
  }

  {
    int last_frame_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;

    if (pAacDecoderStaticChannelInfo->last_core_mode == LPD) {
      INT fac_FB = 1;
      if (elFlags & AC_EL_FULLBANDLPD) {
        fac_FB = 2;
      }

      FIXP_DBL *synth;

      /* Keep some free space at the beginning of the buffer. To be used for
       * past data */
      if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
        synth = pWorkBuffer1 + ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB);
      } else {
        synth = pWorkBuffer1 + PIT_MAX_MAX * fac_FB;
      }

      int fac_length =
          (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT)
              ? (frameLen >> 4)
              : (frameLen >> 3);

      INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
      FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];

      int nbDiv = (elFlags & AC_EL_FULLBANDLPD) ? 2 : 4;
      int lFrame = (elFlags & AC_EL_FULLBANDLPD) ? frameLen / 2 : frameLen;
      int nbSubfr =
          lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
      int LpdSfd = (nbDiv * nbSubfr) >> 1;
      int SynSfd = LpdSfd - BPF_SFD;

      FDKmemclear(
          pitch,
          sizeof(
              pitch));  // added to prevent ferret errors in bass_pf_1sf_delay
      FDKmemclear(pit_gain, sizeof(pit_gain));

      /* FAC case */
      if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0 ||
          pAacDecoderStaticChannelInfo->last_lpd_mode == 4) {
        FIXP_DBL fac_buf[LFAC];
        FIXP_LPC *A = pAacDecoderChannelInfo->data.usac.lp_coeff[0];

        if (!frameOk || last_frame_lost ||
            (pAacDecoderChannelInfo->data.usac.fac_data[0] == NULL)) {
          FDKmemclear(fac_buf,
                      pAacDecoderChannelInfo->granuleLength * sizeof(FIXP_DBL));
          pAacDecoderChannelInfo->data.usac.fac_data[0] = fac_buf;
          pAacDecoderChannelInfo->data.usac.fac_data_e[0] = 0;
        }

        INT A_exp; /* linear prediction coefficients exponent */
        {
          for (int i = 0; i < M_LP_FILTER_ORDER; i++) {
            A[i] = FX_DBL2FX_LPC(fixp_cos(
                fMult(pAacDecoderStaticChannelInfo->lpc4_lsf[i],
                      FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
                LSF_SCALE - LSPARG_SCALE));
          }

          E_LPC_f_lsp_a_conversion(A, A, &A_exp);
        }

#if defined(FDK_ASSERT_ENABLE)
        nSamples =
#endif
            CLpd_FAC_Acelp2Mdct(
                &pAacDecoderStaticChannelInfo->IMdct, synth,
                SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
                pAacDecoderChannelInfo->specScale, nSpec,
                pAacDecoderChannelInfo->data.usac.fac_data[0],
                pAacDecoderChannelInfo->data.usac.fac_data_e[0], fac_length,
                frameLen, tl,
                FDKgetWindowSlope(
                    fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
                fr, A, A_exp, &pAacDecoderStaticChannelInfo->acelp,
                (FIXP_DBL)0, /* FAC gain has already been applied. */
                (last_frame_lost || !frameOk), 1,
                pAacDecoderStaticChannelInfo->last_lpd_mode, 0,
                pAacDecoderChannelInfo->currAliasingSymmetry);

      } else {
#if defined(FDK_ASSERT_ENABLE)
        nSamples =
#endif
            imlt_block(
                &pAacDecoderStaticChannelInfo->IMdct, synth,
                SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
                pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
                FDKgetWindowSlope(
                    fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
                fl,
                FDKgetWindowSlope(
                    fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
                fr, (FIXP_DBL)0,
                pAacDecoderChannelInfo->currAliasingSymmetry
                    ? MLT_FLAG_CURR_ALIAS_SYMMETRY
                    : 0);
      }
      FDK_ASSERT(nSamples == frameLen);

      /* The "if" clause is entered both for fullbandLpd mono and
       * non-fullbandLpd*. The "else"-> just for fullbandLpd stereo*/
      if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
        FDKmemcpy(pitch, pAacDecoderStaticChannelInfo->old_T_pf,
                  SynSfd * sizeof(INT));
        FDKmemcpy(pit_gain, pAacDecoderStaticChannelInfo->old_gain_pf,
                  SynSfd * sizeof(FIXP_DBL));

        for (int i = SynSfd; i < LpdSfd + 3; i++) {
          pitch[i] = L_SUBFR;
          pit_gain[i] = (FIXP_DBL)0;
        }

        if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0) {
          pitch[SynSfd] = pitch[SynSfd - 1];
          pit_gain[SynSfd] = pit_gain[SynSfd - 1];
          if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
            pitch[SynSfd + 1] = pitch[SynSfd];
            pit_gain[SynSfd + 1] = pit_gain[SynSfd];
          }
        }

        /* Copy old data to the beginning of the buffer */
        {
          FDKmemcpy(
              pWorkBuffer1, pAacDecoderStaticChannelInfo->old_synth,
              ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB) * sizeof(FIXP_DBL));
        }

        FIXP_DBL *p2_synth = pWorkBuffer1 + (PIT_MAX_MAX * fac_FB);

        /* recalculate pitch gain to allow postfilering on FAC area */
        for (int i = 0; i < SynSfd + 2; i++) {
          int T = pitch[i];
          FIXP_DBL gain = pit_gain[i];

          if (gain > (FIXP_DBL)0) {
            gain = get_gain(&p2_synth[i * L_SUBFR * fac_FB],
                            &p2_synth[(i * L_SUBFR * fac_FB) - fac_FB * T],
                            L_SUBFR * fac_FB);
            pit_gain[i] = gain;
          }
        }

        bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
                          (LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
                          frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
                          pAacDecoderStaticChannelInfo->mem_bpf);
      }

    } else /* last_core_mode was not LPD */
    {
      FIXP_DBL *tmp =
          pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->mdctOutTemp;
#if defined(FDK_ASSERT_ENABLE)
      nSamples =
#endif
          imlt_block(&pAacDecoderStaticChannelInfo->IMdct, tmp,
                     SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
                     pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
                     FDKgetWindowSlope(
                         fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
                     fl,
                     FDKgetWindowSlope(
                         fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
                     fr, (FIXP_DBL)0,
                     pAacDecoderChannelInfo->currAliasingSymmetry
                         ? MLT_FLAG_CURR_ALIAS_SYMMETRY
                         : 0);

      scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM);
    }
  }

  FDK_ASSERT(nSamples == frameLen);

  pAacDecoderStaticChannelInfo->last_core_mode =
      (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT) ? FD_SHORT
                                                                      : FD_LONG;
  pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
}

#include "ldfiltbank.h"
void CBlock_FrequencyToTimeLowDelay(
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
    const short frameLen) {
  InvMdctTransformLowDelay_fdk(
      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
      pAacDecoderChannelInfo->specScale[0], outSamples,
      pAacDecoderStaticChannelInfo->pOverlapBuffer, frameLen);
}
