/* -----------------------------------------------------------------------------
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(). */

      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;
}
