/* -----------------------------------------------------------------------------
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:

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

#include "channel.h"
#include "aacdecoder.h"
#include "block.h"
#include "aacdec_tns.h"
#include "FDK_bitstream.h"

#include "conceal.h"

#include "rvlc.h"

#include "aacdec_hcr.h"

#include "usacdec_lpd.h"
#include "usacdec_fac.h"

static void MapMidSideMaskToPnsCorrelation(
    CAacDecoderChannelInfo *pAacDecoderChannelInfo[2]) {
  int group;

  for (group = 0; group < pAacDecoderChannelInfo[L]->icsInfo.WindowGroups;
       group++) {
    UCHAR groupMask = 1 << group;

    for (UCHAR band = 0; band < pAacDecoderChannelInfo[L]->icsInfo.MaxSfBands;
         band++) {
      if (pAacDecoderChannelInfo[L]->pComData->jointStereoData.MsUsed[band] &
          groupMask) { /* channels are correlated */
        CPns_SetCorrelation(&pAacDecoderChannelInfo[L]->data.aac.PnsData, group,
                            band, 0);

        if (CPns_IsPnsUsed(&pAacDecoderChannelInfo[L]->data.aac.PnsData, group,
                           band) &&
            CPns_IsPnsUsed(&pAacDecoderChannelInfo[R]->data.aac.PnsData, group,
                           band))
          pAacDecoderChannelInfo[L]->pComData->jointStereoData.MsUsed[band] ^=
              groupMask; /* clear the groupMask-bit */
      }
    }
  }
}

static void Clean_Complex_Prediction_coefficients(
    CJointStereoPersistentData *pJointStereoPersistentData, int windowGroups,
    const int low_limit, const int high_limit) {
  for (int group = 0; group < windowGroups; group++) {
    for (int sfb = low_limit; sfb < high_limit; sfb++) {
      pJointStereoPersistentData->alpha_q_re_prev[group][sfb] = 0;
      pJointStereoPersistentData->alpha_q_im_prev[group][sfb] = 0;
    }
  }
}

/*!
  \brief Decode channel pair element

  The function decodes a channel pair element.

  \return  none
*/
void CChannelElement_Decode(
    CAacDecoderChannelInfo
        *pAacDecoderChannelInfo[2], /*!< pointer to aac decoder channel info */
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
    SamplingRateInfo *pSamplingRateInfo, UINT flags, UINT elFlags,
    int el_channels) {
  int ch = 0;

  int maxSfBandsL = 0, maxSfBandsR = 0;
  int maybe_jstereo = (el_channels > 1);

  if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && el_channels == 2) {
    if (pAacDecoderChannelInfo[L]->data.usac.core_mode ||
        pAacDecoderChannelInfo[R]->data.usac.core_mode) {
      maybe_jstereo = 0;
    }
  }

  if (maybe_jstereo) {
    maxSfBandsL =
        GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo);
    maxSfBandsR =
        GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[R]->icsInfo);

    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
      if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
        if (pAacDecoderChannelInfo[L]->data.aac.PnsData.PnsActive ||
            pAacDecoderChannelInfo[R]->data.aac.PnsData.PnsActive) {
          MapMidSideMaskToPnsCorrelation(pAacDecoderChannelInfo);
        }
      }
      /* if tns_on_lr == 1 run MS */ /* &&
                                        (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active
                                        == 1) */
      if (((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
            1)) ||
          ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) == 0)) {
        int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

        CJointStereo_ApplyMS(
            pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
            pAacDecoderChannelInfo[L]->pSpectralCoefficient,
            pAacDecoderChannelInfo[R]->pSpectralCoefficient,
            pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[L]->specScale,
            pAacDecoderChannelInfo[R]->specScale,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
            maxSfBandsL, maxSfBandsR,
            pAacDecoderChannelInfo[L]
                ->pComData->jointStereoData.store_dmx_re_prev,
            &(pAacDecoderChannelInfo[L]
                  ->pComData->jointStereoData.store_dmx_re_prev_e),
            1);

      } /* if ( ((elFlags & AC_EL_USAC_CP_POSSIBLE).... */
    }   /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow)*/

    /* apply intensity stereo */ /* modifies pAacDecoderChannelInfo[]->aSpecSfb
                                  */
    if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
      if ((pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
           1) &&
          (el_channels == 2)) {
        CJointStereo_ApplyIS(
            pAacDecoderChannelInfo,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo),
            GetScaleFactorBandsTransmitted(
                &pAacDecoderChannelInfo[L]->icsInfo));
      }
    }
  } /* maybe_stereo */

  for (ch = 0; ch < el_channels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
      /* Decode LPD data */
      CLpdChannelStream_Decode(pAacDecoderChannelInfo[ch],
                               pAacDecoderStaticChannelInfo[ch], flags);
    } else {
      UCHAR noSfbs =
          GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[ch]->icsInfo);
      /* For USAC common window: max_sfb of both channels may differ
       * (common_max_sfb == 0). */
      if ((maybe_jstereo == 1) &&
          (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
           1)) {
        noSfbs = fMax(maxSfBandsL, maxSfBandsR);
      }
      int CP_active = 0;
      if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
        CP_active = pAacDecoderChannelInfo[ch]
                        ->pComData->jointStereoData.cplx_pred_flag;
      }

      /* Omit writing of pAacDecoderChannelInfo[ch]->specScale for complex
         stereo prediction since scaling has already been carried out. */
      int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

      if ((!CP_active) || (CP_active && (max_sfb_ste < noSfbs)) ||
          ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
            0))) {
        CBlock_ScaleSpectralData(pAacDecoderChannelInfo[ch], noSfbs,
                                 pSamplingRateInfo);

        /*Active for the case of TNS applied before MS/CP*/
        if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
            (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
             0)) {
          if (IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo)) {
            for (int i = 0; i < noSfbs; i++) {
              pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i] =
                  pAacDecoderChannelInfo[ch]->specScale[0];
            }
          } else {
            for (int i = 0; i < 8; i++) {
              for (int j = 0; j < noSfbs; j++) {
                pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i * 16 + j] =
                    pAacDecoderChannelInfo[ch]->specScale[i];
              }
            }
          }
        }
      }
    }
  } /* End "for (ch = 0; ch < el_channels; ch++)" */

  if (maybe_jstereo) {
    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
    } /* CommonWindow */
    else {
      if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
        FDKmemclear(
            pAacDecoderStaticChannelInfo[L]
                ->pCpeStaticData->jointStereoPersistentData.alpha_q_re_prev,
            JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
        FDKmemclear(
            pAacDecoderStaticChannelInfo[L]
                ->pCpeStaticData->jointStereoPersistentData.alpha_q_im_prev,
            JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
      }
    }

  } /* if (maybe_jstereo) */

  for (ch = 0; ch < el_channels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
    } else {
      if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
        /* Use same seed for coupled channels (CPE) */
        int pnsCh = (ch > 0) ? L : ch;
        CPns_UpdateNoiseState(
            &pAacDecoderChannelInfo[ch]->data.aac.PnsData,
            pAacDecoderChannelInfo[pnsCh]->data.aac.PnsData.currentSeed,
            pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
      }

      if ((!(flags & (AC_USAC))) ||
          ((flags & (AC_USAC)) &&
           (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active ==
            1)) ||
          (maybe_jstereo == 0)) {
        ApplyTools(
            pAacDecoderChannelInfo, pSamplingRateInfo, flags, elFlags, ch,
            pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow);
      }
    } /* End "} else" */
  }   /* End "for (ch = 0; ch < el_channels; ch++)" */

  if (maybe_jstereo) {
    /* apply ms */
    if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
      /* if tns_on_lr == 0 run MS */
      if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
          (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
           0)) {
        int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);

        CJointStereo_ApplyMS(
            pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
            pAacDecoderChannelInfo[L]->pSpectralCoefficient,
            pAacDecoderChannelInfo[R]->pSpectralCoefficient,
            pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
            pAacDecoderChannelInfo[L]->specScale,
            pAacDecoderChannelInfo[R]->specScale,
            GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
                                      pSamplingRateInfo),
            GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
            GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
            maxSfBandsL, maxSfBandsR,
            pAacDecoderChannelInfo[L]
                ->pComData->jointStereoData.store_dmx_re_prev,
            &(pAacDecoderChannelInfo[L]
                  ->pComData->jointStereoData.store_dmx_re_prev_e),
            1);
      }

    } /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) */

  } /* if (maybe_jstereo) */

  for (ch = 0; ch < el_channels; ch++) {
    if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
      pAacDecoderStaticChannelInfo[L]
          ->pCpeStaticData->jointStereoPersistentData.clearSpectralCoeffs = 0;
    }
  }

  CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
                     flags, el_channels);
}

void CChannel_CodebookTableInit(
    CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
  int b, w, maxBands, maxWindows;
  int maxSfb = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
  UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;

  if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
    maxBands = 64;
    maxWindows = 1;
  } else {
    maxBands = 16;
    maxWindows = 8;
  }

  for (w = 0; w < maxWindows; w++) {
    for (b = 0; b < maxSfb; b++) {
      pCodeBook[b] = ESCBOOK;
    }
    for (; b < maxBands; b++) {
      pCodeBook[b] = ZERO_HCB;
    }
    pCodeBook += maxBands;
  }
}

/*
 * Arbitrary order bitstream parser
 */
AAC_DECODER_ERROR CChannelElement_Read(
    HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
    const AUDIO_OBJECT_TYPE aot, SamplingRateInfo *pSamplingRateInfo,
    const UINT flags, const UINT elFlags, const UINT frame_length,
    const UCHAR numberOfChannels, const SCHAR epConfig,
    HANDLE_TRANSPORTDEC pTpDec) {
  AAC_DECODER_ERROR error = AAC_DEC_OK;
  const element_list_t *list;
  int i, ch, decision_bit;
  int crcReg1 = -1, crcReg2 = -1;
  int cplxPred;
  int ind_sw_cce_flag = 0, num_gain_element_lists = 0;

  FDK_ASSERT((numberOfChannels == 1) || (numberOfChannels == 2));

  /* Get channel element sequence table */
  list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, elFlags);
  if (list == NULL) {
    error = AAC_DEC_UNSUPPORTED_FORMAT;
    goto bail;
  }

  CTns_Reset(&pAacDecoderChannelInfo[0]->pDynData->TnsData);
  /* Set common window to 0 by default. If signalized in the bit stream it will
   * be overwritten later explicitely */
  pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
  if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
    pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active = 0;
    pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr = 0;
  }
  if (numberOfChannels == 2) {
    CTns_Reset(&pAacDecoderChannelInfo[1]->pDynData->TnsData);
    pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
  }

  cplxPred = 0;
  if (pAacDecoderStaticChannelInfo != NULL) {
    if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
      pAacDecoderChannelInfo[0]->pComData->jointStereoData.cplx_pred_flag = 0;
      cplxPred = 1;
    }
  }

  if (0 || (flags & (AC_ELD | AC_SCALABLE))) {
    pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 1;
    if (numberOfChannels == 2) {
      pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
          pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
    }
  }

  /* Iterate through sequence table */
  i = 0;
  ch = 0;
  decision_bit = 0;
  do {
    switch (list->id[i]) {
      case element_instance_tag:
        pAacDecoderChannelInfo[0]->ElementInstanceTag = FDKreadBits(hBs, 4);
        if (numberOfChannels == 2) {
          pAacDecoderChannelInfo[1]->ElementInstanceTag =
              pAacDecoderChannelInfo[0]->ElementInstanceTag;
        }
        break;
      case common_window:
        decision_bit =
            pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow =
                FDKreadBits(hBs, 1);
        if (numberOfChannels == 2) {
          pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
              pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
        }
        break;
      case ics_info:
        /* store last window sequence (utilized in complex stereo prediction)
         * before reading new channel-info */
        if (cplxPred) {
          if (pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
            pAacDecoderStaticChannelInfo[0]
                ->pCpeStaticData->jointStereoPersistentData.winSeqPrev =
                pAacDecoderChannelInfo[0]->icsInfo.WindowSequence;
            pAacDecoderStaticChannelInfo[0]
                ->pCpeStaticData->jointStereoPersistentData.winShapePrev =
                pAacDecoderChannelInfo[0]->icsInfo.WindowShape;
          }
        }
        /* Read individual channel info */
        error = IcsRead(hBs, &pAacDecoderChannelInfo[ch]->icsInfo,
                        pSamplingRateInfo, flags);

        if (elFlags & AC_EL_LFE &&
            GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) !=
                BLOCK_LONG) {
          error = AAC_DEC_PARSE_ERROR;
          break;
        }

        if (numberOfChannels == 2 &&
            pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
          pAacDecoderChannelInfo[1]->icsInfo =
              pAacDecoderChannelInfo[0]->icsInfo;
        }
        break;

      case common_max_sfb:
        if (FDKreadBit(hBs) == 0) {
          error = IcsReadMaxSfb(hBs, &pAacDecoderChannelInfo[1]->icsInfo,
                                pSamplingRateInfo);
        }
        break;

      case ltp_data_present:
        if (FDKreadBits(hBs, 1) != 0) {
          error = AAC_DEC_UNSUPPORTED_PREDICTION;
        }
        break;

      case ms:

        INT max_sfb_ste;
        INT max_sfb_ste_clear;

        max_sfb_ste = GetScaleMaxFactorBandsTransmitted(
            &pAacDecoderChannelInfo[0]->icsInfo,
            &pAacDecoderChannelInfo[1]->icsInfo);

        max_sfb_ste_clear = 64;

        pAacDecoderChannelInfo[0]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;
        pAacDecoderChannelInfo[1]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;

        if (flags & (AC_USAC | AC_RSV603DA) &&
            pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow ==
                0) {
          Clean_Complex_Prediction_coefficients(
              &pAacDecoderStaticChannelInfo[0]
                   ->pCpeStaticData->jointStereoPersistentData,
              GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo), 0, 64);
        }

        if (CJointStereo_Read(
                hBs, &pAacDecoderChannelInfo[0]->pComData->jointStereoData,
                GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo),
                max_sfb_ste, max_sfb_ste_clear,
                /* jointStereoPersistentData and cplxPredictionData are only
                   available/allocated if cplxPred is active. */
                ((cplxPred == 0) || (pAacDecoderStaticChannelInfo == NULL))
                    ? NULL
                    : &pAacDecoderStaticChannelInfo[0]
                           ->pCpeStaticData->jointStereoPersistentData,
                ((cplxPred == 0) || (pAacDecoderChannelInfo[0] == NULL))
                    ? NULL
                    : pAacDecoderChannelInfo[0]
                          ->pComStaticData->cplxPredictionData,
                cplxPred,
                GetScaleFactorBandsTotal(&pAacDecoderChannelInfo[0]->icsInfo),
                GetWindowSequence(&pAacDecoderChannelInfo[0]->icsInfo),
                flags)) {
          error = AAC_DEC_PARSE_ERROR;
        }

        break;

      case global_gain:
        pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.GlobalGain =
            (UCHAR)FDKreadBits(hBs, 8);
        break;

      case section_data:
        error = CBlock_ReadSectionData(hBs, pAacDecoderChannelInfo[ch],
                                       pSamplingRateInfo, flags);
        break;

      case scale_factor_data_usac:
        pAacDecoderChannelInfo[ch]->currAliasingSymmetry = 0;
        /* Set active sfb codebook indexes to HCB_ESC to make them "active" */
        CChannel_CodebookTableInit(
            pAacDecoderChannelInfo[ch]); /*  equals ReadSectionData(self,
                                            bs) in float soft. block.c
                                            line: ~599 */
        /* Note: The missing "break" is intentional here, since we need to call
         * CBlock_ReadScaleFactorData(). */
        FDK_FALLTHROUGH;

      case scale_factor_data:
        if (flags & AC_ER_RVLC) {
          /* read RVLC data from bitstream (error sens. cat. 1) */
          CRvlc_Read(pAacDecoderChannelInfo[ch], hBs);
        } else {
          error = CBlock_ReadScaleFactorData(pAacDecoderChannelInfo[ch], hBs,
                                             flags);
        }
        break;

      case pulse:
        if (CPulseData_Read(
                hBs,
                &pAacDecoderChannelInfo[ch]->pDynData->specificTo.aac.PulseData,
                pSamplingRateInfo->ScaleFactorBands_Long, /* pulse data is only
                                                             allowed to be
                                                             present in long
                                                             blocks! */
                (void *)&pAacDecoderChannelInfo[ch]->icsInfo,
                frame_length) != 0) {
          error = AAC_DEC_DECODE_FRAME_ERROR;
        }
        break;
      case tns_data_present:
        CTns_ReadDataPresentFlag(
            hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData);
        if (elFlags & AC_EL_LFE &&
            pAacDecoderChannelInfo[ch]->pDynData->TnsData.DataPresent) {
          error = AAC_DEC_PARSE_ERROR;
        }
        break;
      case tns_data:
        /* tns_data_present is checked inside CTns_Read(). */
        error = CTns_Read(hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData,
                          &pAacDecoderChannelInfo[ch]->icsInfo, flags);

        break;

      case gain_control_data:
        break;

      case gain_control_data_present:
        if (FDKreadBits(hBs, 1)) {
          error = AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA;
        }
        break;

      case tw_data:
        break;
      case common_tw:
        break;
      case tns_data_present_usac:
        if (pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active) {
          CTns_ReadDataPresentUsac(
              hBs, &pAacDecoderChannelInfo[0]->pDynData->TnsData,
              &pAacDecoderChannelInfo[1]->pDynData->TnsData,
              &pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr,
              &pAacDecoderChannelInfo[0]->icsInfo, flags, elFlags,
              pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow);
        } else {
          pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr =
              (UCHAR)1;
        }
        break;
      case core_mode:
        decision_bit = FDKreadBits(hBs, 1);
        pAacDecoderChannelInfo[ch]->data.usac.core_mode = decision_bit;
        if ((ch == 1) && (pAacDecoderChannelInfo[0]->data.usac.core_mode !=
                          pAacDecoderChannelInfo[1]->data.usac.core_mode)) {
          /* StereoCoreToolInfo(core_mode[ch] ) */
          pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
          pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
        }
        break;
      case tns_active:
        pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active =
            FDKreadBit(hBs);
        break;
      case noise:
        if (elFlags & AC_EL_USAC_NOISE) {
          pAacDecoderChannelInfo[ch]
              ->pDynData->specificTo.usac.fd_noise_level_and_offset =
              FDKreadBits(hBs, 3 + 5); /* Noise level */
        }
        break;
      case lpd_channel_stream:

      {
        error = CLpdChannelStream_Read(/* = lpd_channel_stream() */
                                       hBs, pAacDecoderChannelInfo[ch],
                                       pAacDecoderStaticChannelInfo[ch],
                                       pSamplingRateInfo, flags);
      }

        pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_LPD;
        break;
      case fac_data: {
        int fFacDatPresent = FDKreadBit(hBs);

        /* Wee need a valid fac_data[0] even if no FAC data is present (as
         * temporal buffer) */
        pAacDecoderChannelInfo[ch]->data.usac.fac_data[0] =
            pAacDecoderChannelInfo[ch]->data.usac.fac_data0;

        if (fFacDatPresent) {
          if (elFlags & AC_EL_LFE) {
            error = AAC_DEC_PARSE_ERROR;
            break;
          }
          /* FAC data present, this frame is FD, so the last mode had to be
           * ACELP. */
          if (pAacDecoderStaticChannelInfo[ch]->last_core_mode != LPD ||
              pAacDecoderStaticChannelInfo[ch]->last_lpd_mode != 0) {
            pAacDecoderChannelInfo[ch]->data.usac.core_mode_last = LPD;
            pAacDecoderChannelInfo[ch]->data.usac.lpd_mode_last = 0;
            /* We can't change the past! So look to the future and go ahead! */
          }
          CLpd_FAC_Read(hBs, pAacDecoderChannelInfo[ch]->data.usac.fac_data[0],
                        pAacDecoderChannelInfo[ch]->data.usac.fac_data_e,
                        CLpd_FAC_getLength(
                            IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo),
                            pAacDecoderChannelInfo[ch]->granuleLength),
                        1, 0);
        } else {
          if (pAacDecoderStaticChannelInfo[ch]->last_core_mode == LPD &&
              pAacDecoderStaticChannelInfo[ch]->last_lpd_mode == 0) {
            /* ACELP to FD transitons without FAC are possible. That is why we
            zero it out (i.e FAC will not be considered in the subsequent
            calculations */
            FDKmemclear(pAacDecoderChannelInfo[ch]->data.usac.fac_data0,
                        LFAC * sizeof(FIXP_DBL));
          }
        }
      } break;
      case esc2_rvlc:
        if (flags & AC_ER_RVLC) {
          CRvlc_Decode(pAacDecoderChannelInfo[ch],
                       pAacDecoderStaticChannelInfo[ch], hBs);
        }
        break;

      case esc1_hcr:
        if (flags & AC_ER_HCR) {
          CHcr_Read(hBs, pAacDecoderChannelInfo[ch],
                    numberOfChannels == 2 ? ID_CPE : ID_SCE);
        }
        break;

      case spectral_data:
        error = CBlock_ReadSpectralData(hBs, pAacDecoderChannelInfo[ch],
                                        pSamplingRateInfo, flags);
        if (flags & AC_ELD) {
          pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_ELDFB;
        } else {
          if (flags & AC_HDAAC) {
            pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_INTIMDCT;
          } else {
            pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
          }
        }
        break;

      case ac_spectral_data:
        error = CBlock_ReadAcSpectralData(
            hBs, pAacDecoderChannelInfo[ch], pAacDecoderStaticChannelInfo[ch],
            pSamplingRateInfo, frame_length, flags);
        pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
        break;

      case coupled_elements: {
        int num_coupled_elements, c;

        ind_sw_cce_flag = FDKreadBit(hBs);
        num_coupled_elements = FDKreadBits(hBs, 3);

        for (c = 0; c < (num_coupled_elements + 1); c++) {
          int cc_target_is_cpe;

          num_gain_element_lists++;
          cc_target_is_cpe = FDKreadBit(hBs); /* cc_target_is_cpe[c] */
          FDKreadBits(hBs, 4);                /* cc_target_tag_select[c] */

          if (cc_target_is_cpe) {
            int cc_l, cc_r;

            cc_l = FDKreadBit(hBs); /* cc_l[c] */
            cc_r = FDKreadBit(hBs); /* cc_r[c] */

            if (cc_l && cc_r) {
              num_gain_element_lists++;
            }
          }
        }
        FDKreadBit(hBs);     /* cc_domain */
        FDKreadBit(hBs);     /* gain_element_sign  */
        FDKreadBits(hBs, 2); /* gain_element_scale */
      } break;

      case gain_element_lists: {
        const CodeBookDescription *hcb;
        UCHAR *pCodeBook;
        int c;

        hcb = &AACcodeBookDescriptionTable[BOOKSCL];
        pCodeBook = pAacDecoderChannelInfo[ch]->pDynData->aCodeBook;

        for (c = 1; c < num_gain_element_lists; c++) {
          int cge;
          if (ind_sw_cce_flag) {
            cge = 1;
          } else {
            cge = FDKreadBits(hBs, 1); /* common_gain_element_present[c] */
          }
          if (cge) {
            /* Huffman */
            CBlock_DecodeHuffmanWord(
                hBs, hcb); /* hcod_sf[common_gain_element[c]] 1..19 */
          } else {
            int g, sfb;
            for (g = 0;
                 g < GetWindowGroups(&pAacDecoderChannelInfo[ch]->icsInfo);
                 g++) {
              for (sfb = 0; sfb < GetScaleFactorBandsTransmitted(
                                      &pAacDecoderChannelInfo[ch]->icsInfo);
                   sfb++) {
                if (pCodeBook[sfb] != ZERO_HCB) {
                  /* Huffman */
                  CBlock_DecodeHuffmanWord(
                      hBs,
                      hcb); /* hcod_sf[dpcm_gain_element[c][g][sfb]] 1..19 */
                }
              }
            }
          }
        }
      } break;

        /* CRC handling */
      case adtscrc_start_reg1:
        if (pTpDec != NULL) {
          crcReg1 = transportDec_CrcStartReg(pTpDec, 192);
        }
        break;
      case adtscrc_start_reg2:
        if (pTpDec != NULL) {
          crcReg2 = transportDec_CrcStartReg(pTpDec, 128);
        }
        break;
      case adtscrc_end_reg1:
      case drmcrc_end_reg:
        if (pTpDec != NULL) {
          transportDec_CrcEndReg(pTpDec, crcReg1);
          crcReg1 = -1;
        }
        break;
      case adtscrc_end_reg2:
        if (crcReg1 != -1) {
          error = AAC_DEC_DECODE_FRAME_ERROR;
        } else if (pTpDec != NULL) {
          transportDec_CrcEndReg(pTpDec, crcReg2);
          crcReg2 = -1;
        }
        break;
      case drmcrc_start_reg:
        if (pTpDec != NULL) {
          crcReg1 = transportDec_CrcStartReg(pTpDec, 0);
        }
        break;

        /* Non data cases */
      case next_channel:
        ch = (ch + 1) % numberOfChannels;
        break;
      case link_sequence:
        list = list->next[decision_bit];
        i = -1;
        break;

      default:
        error = AAC_DEC_UNSUPPORTED_FORMAT;
        break;
    }

    if (error != AAC_DEC_OK) {
      goto bail;
    }

    i++;

  } while (list->id[i] != end_of_sequence);

  for (ch = 0; ch < numberOfChannels; ch++) {
    if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_IMDCT ||
        pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_ELDFB) {
      /* Shows which bands are empty. */
      UCHAR *band_is_noise =
          pAacDecoderChannelInfo[ch]->pDynData->band_is_noise;
      FDKmemset(band_is_noise, (UCHAR)1, sizeof(UCHAR) * (8 * 16));

      error = CBlock_InverseQuantizeSpectralData(
          pAacDecoderChannelInfo[ch], pSamplingRateInfo, band_is_noise, 1);
      if (error != AAC_DEC_OK) {
        return error;
      }

      if (elFlags & AC_EL_USAC_NOISE) {
        CBlock_ApplyNoise(pAacDecoderChannelInfo[ch], pSamplingRateInfo,
                          &pAacDecoderStaticChannelInfo[ch]->nfRandomSeed,
                          band_is_noise);

      } /* if (elFlags & AC_EL_USAC_NOISE) */
    }
  }

bail:
  if (crcReg1 != -1 || crcReg2 != -1) {
    if (error == AAC_DEC_OK) {
      error = AAC_DEC_DECODE_FRAME_ERROR;
    }
    if (crcReg1 != -1) {
      transportDec_CrcEndReg(pTpDec, crcReg1);
    }
    if (crcReg2 != -1) {
      transportDec_CrcEndReg(pTpDec, crcReg2);
    }
  }
  return error;
}
