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

/**************************** SBR decoder library ******************************

   Author(s):

   Description:

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

/*!
  \file
  \brief  Envelope extraction
  The functions provided by this module are mostly called by applySBR(). After
  it is determined that there is valid SBR data, sbrGetHeaderData() might be
  called if the current SBR data contains an \ref SBR_HEADER_ELEMENT as opposed
  to a \ref SBR_STANDARD_ELEMENT. This function may return various error codes
  as defined in #SBR_HEADER_STATUS . Most importantly it returns HEADER_RESET
  when decoder settings need to be recalculated according to the SBR
  specifications. In that case applySBR() will initiatite the required
  re-configuration.

  The header data is stored in a #SBR_HEADER_DATA structure.

  The actual SBR data for the current frame is decoded into SBR_FRAME_DATA
  stuctures by sbrGetChannelPairElement() [for stereo streams] and
  sbrGetSingleChannelElement() [for mono streams]. There is no fractional
  arithmetic involved.

  Once the information is extracted, the data needs to be further prepared
  before the actual decoding process. This is done in decodeSbrData().

  \sa Description of buffer management in applySBR(). \ref documentationOverview

  <h1>About the SBR data format:</h1>

  Each frame includes SBR data (side chain information), and can be either the
  \ref SBR_HEADER_ELEMENT or the \ref SBR_STANDARD_ELEMENT. Parts of the data
  can be protected by a CRC checksum.

  \anchor SBR_HEADER_ELEMENT <h2>The SBR_HEADER_ELEMENT</h2>

  The SBR_HEADER_ELEMENT can be transmitted with every frame, however, it
  typically is send every second or so. It contains fundamental information such
  as SBR sampling frequency and frequency range as well as control signals that
  do not require frequent changes. It also includes the \ref
  SBR_STANDARD_ELEMENT.

  Depending on the changes between the information in a current
  SBR_HEADER_ELEMENT and the previous SBR_HEADER_ELEMENT, the SBR decoder might
  need to be reset and reconfigured (e.g. new tables need to be calculated).

  \anchor SBR_STANDARD_ELEMENT <h2>The SBR_STANDARD_ELEMENT</h2>

  This data can be subdivided into "side info" and "raw data", where side info
  is defined as signals needed to decode the raw data and some decoder tuning
  signals. Raw data is referred to as PCM and Huffman coded envelope and noise
  floor estimates. The side info also includes information about the
  time-frequency grid for the current frame.

  \sa \ref documentationOverview
*/

#include "env_extr.h"

#include "sbr_ram.h"
#include "sbr_rom.h"
#include "huff_dec.h"

#include "psbitdec.h"

#define DRM_PARAMETRIC_STEREO 0
#define EXTENSION_ID_PS_CODING 2

static int extractPvcFrameInfo(
    HANDLE_FDK_BITSTREAM hBs,           /*!< bitbuffer handle */
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the
                                           frame-info will be stored */
    HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where
                                                     the previous frame-info
                                                     will be stored */
    UCHAR pvc_mode_last,                          /**< PVC mode of last frame */
    const UINT flags);
static int extractFrameInfo(HANDLE_FDK_BITSTREAM hBs,
                            HANDLE_SBR_HEADER_DATA hHeaderData,
                            HANDLE_SBR_FRAME_DATA h_frame_data,
                            const UINT nrOfChannels, const UINT flags);

static int sbrGetPvcEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
                             HANDLE_SBR_FRAME_DATA h_frame_data,
                             HANDLE_FDK_BITSTREAM hBs, const UINT flags,
                             const UINT pvcMode);
static int sbrGetEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
                          HANDLE_SBR_FRAME_DATA h_frame_data,
                          HANDLE_FDK_BITSTREAM hBs, const UINT flags);

static void sbrGetDirectionControlData(HANDLE_SBR_FRAME_DATA hFrameData,
                                       HANDLE_FDK_BITSTREAM hBs,
                                       const UINT flags, const int bs_pvc_mode);

static void sbrGetNoiseFloorData(HANDLE_SBR_HEADER_DATA hHeaderData,
                                 HANDLE_SBR_FRAME_DATA h_frame_data,
                                 HANDLE_FDK_BITSTREAM hBs);

static int checkFrameInfo(FRAME_INFO *pFrameInfo, int numberOfTimeSlots,
                          int overlap, int timeStep);

/* Mapping to std samplerate table according to 14496-3 (4.6.18.2.6) */
typedef struct SR_MAPPING {
  UINT fsRangeLo; /* If fsRangeLo(n+1)>fs>=fsRangeLo(n), it will be mapped to...
                   */
  UINT fsMapped;  /* fsMapped. */
} SR_MAPPING;

static const SR_MAPPING stdSampleRatesMapping[] = {
    {0, 8000},      {9391, 11025},  {11502, 12000}, {13856, 16000},
    {18783, 22050}, {23004, 24000}, {27713, 32000}, {37566, 44100},
    {46009, 48000}, {55426, 64000}, {75132, 88200}, {92017, 96000}};
static const SR_MAPPING stdSampleRatesMappingUsac[] = {
    {0, 16000},     {18783, 22050}, {23004, 24000}, {27713, 32000},
    {35777, 40000}, {42000, 44100}, {46009, 48000}, {55426, 64000},
    {75132, 88200}, {92017, 96000}};

UINT sbrdec_mapToStdSampleRate(UINT fs,
                               UINT isUsac) /*!< Output sampling frequency */
{
  UINT fsMapped = fs, tableSize = 0;
  const SR_MAPPING *mappingTable;
  int i;

  if (!isUsac) {
    mappingTable = stdSampleRatesMapping;
    tableSize = sizeof(stdSampleRatesMapping) / sizeof(SR_MAPPING);
  } else {
    mappingTable = stdSampleRatesMappingUsac;
    tableSize = sizeof(stdSampleRatesMappingUsac) / sizeof(SR_MAPPING);
  }

  for (i = tableSize - 1; i >= 0; i--) {
    if (fs >= mappingTable[i].fsRangeLo) {
      fsMapped = mappingTable[i].fsMapped;
      break;
    }
  }

  return (fsMapped);
}

SBR_ERROR
initHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, const int sampleRateIn,
               const int sampleRateOut, const INT downscaleFactor,
               const int samplesPerFrame, const UINT flags,
               const int setDefaultHdr) {
  HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
  SBR_ERROR sbrError = SBRDEC_OK;
  int numAnalysisBands;
  int sampleRateProc;

  if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) {
    sampleRateProc =
        sbrdec_mapToStdSampleRate(sampleRateOut * downscaleFactor, 0);
  } else {
    sampleRateProc = sampleRateOut * downscaleFactor;
  }

  if (sampleRateIn == sampleRateOut) {
    hHeaderData->sbrProcSmplRate = sampleRateProc << 1;
    numAnalysisBands = 32;
  } else {
    hHeaderData->sbrProcSmplRate = sampleRateProc;
    if ((sampleRateOut >> 1) == sampleRateIn) {
      /* 1:2 */
      numAnalysisBands = 32;
    } else if ((sampleRateOut >> 2) == sampleRateIn) {
      /* 1:4 */
      numAnalysisBands = 16;
    } else if ((sampleRateOut * 3) >> 3 == (sampleRateIn * 8) >> 3) {
      /* 3:8, 3/4 core frame length */
      numAnalysisBands = 24;
    } else {
      sbrError = SBRDEC_UNSUPPORTED_CONFIG;
      goto bail;
    }
  }
  numAnalysisBands /= downscaleFactor;

  if (setDefaultHdr) {
    /* Fill in default values first */
    hHeaderData->syncState = SBR_NOT_INITIALIZED;
    hHeaderData->status = 0;
    hHeaderData->frameErrorFlag = 0;

    hHeaderData->bs_info.ampResolution = 1;
    hHeaderData->bs_info.xover_band = 0;
    hHeaderData->bs_info.sbr_preprocessing = 0;
    hHeaderData->bs_info.pvc_mode = 0;

    hHeaderData->bs_data.startFreq = 5;
    hHeaderData->bs_data.stopFreq = 0;
    hHeaderData->bs_data.freqScale =
        0; /* previously 2; for ELD reduced delay bitstreams
           /samplerates initializing of the sbr decoder instance fails if
           freqScale is set to 2 because no master table can be generated; in
           ELD reduced delay bitstreams this value is always 0; gets overwritten
           when header is read */
    hHeaderData->bs_data.alterScale = 1;
    hHeaderData->bs_data.noise_bands = 2;
    hHeaderData->bs_data.limiterBands = 2;
    hHeaderData->bs_data.limiterGains = 2;
    hHeaderData->bs_data.interpolFreq = 1;
    hHeaderData->bs_data.smoothingLength = 1;

    /* Patch some entries */
    if (sampleRateOut * downscaleFactor >= 96000) {
      hHeaderData->bs_data.startFreq =
          4; /*   having read these frequency values from bit stream before. */
      hHeaderData->bs_data.stopFreq = 3;
    } else if (sampleRateOut * downscaleFactor >
               24000) { /* Trigger an error if SBR is going to be processed
                           without     */
      hHeaderData->bs_data.startFreq =
          7; /*   having read these frequency values from bit stream before. */
      hHeaderData->bs_data.stopFreq = 3;
    }
  }

  if ((sampleRateOut >> 2) == sampleRateIn) {
    hHeaderData->timeStep = 4;
  } else {
    hHeaderData->timeStep = (flags & SBRDEC_ELD_GRID) ? 1 : 2;
  }

  /* Setup pointers to frequency band tables */
  hFreq->freqBandTable[0] = hFreq->freqBandTableLo;
  hFreq->freqBandTable[1] = hFreq->freqBandTableHi;

  /* One SBR timeslot corresponds to the amount of samples equal to the amount
   * of analysis bands, divided by the timestep. */
  hHeaderData->numberTimeSlots =
      (samplesPerFrame / numAnalysisBands) >> (hHeaderData->timeStep - 1);
  if (hHeaderData->numberTimeSlots > (16)) {
    sbrError = SBRDEC_UNSUPPORTED_CONFIG;
  }

  hHeaderData->numberOfAnalysisBands = numAnalysisBands;
  if ((sampleRateOut >> 2) == sampleRateIn) {
    hHeaderData->numberTimeSlots <<= 1;
  }

bail:
  return sbrError;
}

/*!
  \brief   Initialize the SBR_PREV_FRAME_DATA struct
*/
void initSbrPrevFrameData(
    HANDLE_SBR_PREV_FRAME_DATA
        h_prev_data, /*!< handle to struct SBR_PREV_FRAME_DATA */
    int timeSlots)   /*!< Framelength in SBR-timeslots */
{
  int i;

  /* Set previous energy and noise levels to 0 for the case
     that decoding starts in the middle of a bitstream */
  for (i = 0; i < MAX_FREQ_COEFFS; i++)
    h_prev_data->sfb_nrg_prev[i] = (FIXP_DBL)0;
  for (i = 0; i < MAX_NOISE_COEFFS; i++)
    h_prev_data->prevNoiseLevel[i] = (FIXP_DBL)0;
  for (i = 0; i < MAX_INVF_BANDS; i++) h_prev_data->sbr_invf_mode[i] = INVF_OFF;

  h_prev_data->stopPos = timeSlots;
  h_prev_data->coupling = COUPLING_OFF;
  h_prev_data->ampRes = 0;

  FDKmemclear(&h_prev_data->prevFrameInfo, sizeof(h_prev_data->prevFrameInfo));
}

/*!
  \brief   Read header data from bitstream

  \return  error status - 0 if ok
*/
SBR_HEADER_STATUS
sbrGetHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_FDK_BITSTREAM hBs,
                 const UINT flags, const int fIsSbrData,
                 const UCHAR configMode) {
  SBR_HEADER_DATA_BS *pBsData;
  SBR_HEADER_DATA_BS lastHeader;
  SBR_HEADER_DATA_BS_INFO lastInfo;
  int headerExtra1 = 0, headerExtra2 = 0;

  /* Read and discard new header in config change detection mode */
  if (configMode & AC_CM_DET_CFG_CHANGE) {
    if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
      /* ampResolution */
      FDKreadBits(hBs, 1);
    }
    /* startFreq, stopFreq */
    FDKpushFor(hBs, 8);
    if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
      /* xover_band */
      FDKreadBits(hBs, 3);
      /* reserved bits */
      FDKreadBits(hBs, 2);
    }
    headerExtra1 = FDKreadBit(hBs);
    headerExtra2 = FDKreadBit(hBs);
    FDKpushFor(hBs, 5 * headerExtra1 + 6 * headerExtra2);

    return HEADER_OK;
  }

  /* Copy SBR bit stream header to temporary header */
  lastHeader = hHeaderData->bs_data;
  lastInfo = hHeaderData->bs_info;

  /* Read new header from bitstream */
  if ((flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) && !fIsSbrData) {
    pBsData = &hHeaderData->bs_dflt;
  } else {
    pBsData = &hHeaderData->bs_data;
  }

  if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
    hHeaderData->bs_info.ampResolution = FDKreadBits(hBs, 1);
  }

  pBsData->startFreq = FDKreadBits(hBs, 4);
  pBsData->stopFreq = FDKreadBits(hBs, 4);

  if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
    hHeaderData->bs_info.xover_band = FDKreadBits(hBs, 3);
    FDKreadBits(hBs, 2);
  }

  headerExtra1 = FDKreadBits(hBs, 1);
  headerExtra2 = FDKreadBits(hBs, 1);

  /* Handle extra header information */
  if (headerExtra1) {
    pBsData->freqScale = FDKreadBits(hBs, 2);
    pBsData->alterScale = FDKreadBits(hBs, 1);
    pBsData->noise_bands = FDKreadBits(hBs, 2);
  } else {
    pBsData->freqScale = 2;
    pBsData->alterScale = 1;
    pBsData->noise_bands = 2;
  }

  if (headerExtra2) {
    pBsData->limiterBands = FDKreadBits(hBs, 2);
    pBsData->limiterGains = FDKreadBits(hBs, 2);
    pBsData->interpolFreq = FDKreadBits(hBs, 1);
    pBsData->smoothingLength = FDKreadBits(hBs, 1);
  } else {
    pBsData->limiterBands = 2;
    pBsData->limiterGains = 2;
    pBsData->interpolFreq = 1;
    pBsData->smoothingLength = 1;
  }

  /* Look for new settings. IEC 14496-3, 4.6.18.3.1 */
  if (hHeaderData->syncState < SBR_HEADER ||
      lastHeader.startFreq != pBsData->startFreq ||
      lastHeader.stopFreq != pBsData->stopFreq ||
      lastHeader.freqScale != pBsData->freqScale ||
      lastHeader.alterScale != pBsData->alterScale ||
      lastHeader.noise_bands != pBsData->noise_bands ||
      lastInfo.xover_band != hHeaderData->bs_info.xover_band) {
    return HEADER_RESET; /* New settings */
  }

  return HEADER_OK;
}

/*!
  \brief   Get missing harmonics parameters (only used for AAC+SBR)

  \return  error status - 0 if ok
*/
int sbrGetSyntheticCodedData(HANDLE_SBR_HEADER_DATA hHeaderData,
                             HANDLE_SBR_FRAME_DATA hFrameData,
                             HANDLE_FDK_BITSTREAM hBs, const UINT flags) {
  int i, bitsRead = 0;

  int add_harmonic_flag = FDKreadBits(hBs, 1);
  bitsRead++;

  if (add_harmonic_flag) {
    int nSfb = hHeaderData->freqBandData.nSfb[1];
    for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
      /* read maximum 32 bits and align them to the MSB */
      int readBits = fMin(32, nSfb);
      nSfb -= readBits;
      if (readBits > 0) {
        hFrameData->addHarmonics[i] = FDKreadBits(hBs, readBits)
                                      << (32 - readBits);
      } else {
        hFrameData->addHarmonics[i] = 0;
      }

      bitsRead += readBits;
    }
    /* bs_pvc_mode = 0 for Rsvd50 */
    if (flags & SBRDEC_SYNTAX_USAC) {
      if (hHeaderData->bs_info.pvc_mode) {
        int bs_sinusoidal_position = 31;
        if (FDKreadBit(hBs) /* bs_sinusoidal_position_flag */) {
          bs_sinusoidal_position = FDKreadBits(hBs, 5);
        }
        hFrameData->sinusoidal_position = bs_sinusoidal_position;
      }
    }
  } else {
    for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++)
      hFrameData->addHarmonics[i] = 0;
  }

  return (bitsRead);
}

/*!
  \brief      Reads extension data from the bitstream

  The bitstream format allows up to 4 kinds of extended data element.
  Extended data may contain several elements, each identified by a 2-bit-ID.
  So far, no extended data elements are defined hence the first 2 parameters
  are unused. The data should be skipped in order to update the number
  of read bits for the consistency check in applySBR().
*/
static int extractExtendedData(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< handle to SBR header */
    HANDLE_FDK_BITSTREAM hBs            /*!< Handle to the bit buffer */
    ,
    HANDLE_PS_DEC hParametricStereoDec /*!< Parametric Stereo Decoder */
) {
  INT nBitsLeft;
  int extended_data;
  int i, frameOk = 1;

  extended_data = FDKreadBits(hBs, 1);

  if (extended_data) {
    int cnt;
    int bPsRead = 0;

    cnt = FDKreadBits(hBs, 4);
    if (cnt == (1 << 4) - 1) cnt += FDKreadBits(hBs, 8);

    nBitsLeft = 8 * cnt;

    /* sanity check for cnt */
    if (nBitsLeft > (INT)FDKgetValidBits(hBs)) {
      /* limit nBitsLeft */
      nBitsLeft = (INT)FDKgetValidBits(hBs);
      /* set frame error */
      frameOk = 0;
    }

    while (nBitsLeft > 7) {
      int extension_id = FDKreadBits(hBs, 2);
      nBitsLeft -= 2;

      switch (extension_id) {
        case EXTENSION_ID_PS_CODING:

          /* Read PS data from bitstream */

          if (hParametricStereoDec != NULL) {
            if (bPsRead &&
                !hParametricStereoDec->bsData[hParametricStereoDec->bsReadSlot]
                     .mpeg.bPsHeaderValid) {
              cnt = nBitsLeft >> 3; /* number of remaining bytes */
              for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8);
              nBitsLeft -= cnt * 8;
            } else {
              nBitsLeft -=
                  (INT)ReadPsData(hParametricStereoDec, hBs, nBitsLeft);
              bPsRead = 1;
            }
          }

          /* parametric stereo detected, could set channelMode accordingly here
           */
          /*                                                                     */
          /* "The usage of this parametric stereo extension to HE-AAC is */
          /* signalled implicitly in the bitstream. Hence, if an sbr_extension()
           */
          /* with bs_extension_id==EXTENSION_ID_PS is found in the SBR part of
           */
          /* the bitstream, a decoder supporting the combination of SBR and PS
           */
          /* shall operate the PS tool to generate a stereo output signal." */
          /* source: ISO/IEC 14496-3:2001/FDAM 2:2004(E) */

          break;

        default:
          cnt = nBitsLeft >> 3; /* number of remaining bytes */
          for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8);
          nBitsLeft -= cnt * 8;
          break;
      }
    }

    if (nBitsLeft < 0) {
      frameOk = 0;
      goto bail;
    } else {
      /* Read fill bits for byte alignment */
      FDKreadBits(hBs, nBitsLeft);
    }
  }

bail:
  return (frameOk);
}

/*!
  \brief      Read bitstream elements of a SBR channel element
  \return     SbrFrameOK
*/
int sbrGetChannelElement(HANDLE_SBR_HEADER_DATA hHeaderData,
                         HANDLE_SBR_FRAME_DATA hFrameDataLeft,
                         HANDLE_SBR_FRAME_DATA hFrameDataRight,
                         HANDLE_SBR_PREV_FRAME_DATA hFrameDataLeftPrev,
                         UCHAR pvc_mode_last, HANDLE_FDK_BITSTREAM hBs,
                         HANDLE_PS_DEC hParametricStereoDec, const UINT flags,
                         const int overlap) {
  int i, bs_coupling = COUPLING_OFF;
  const int nCh = (hFrameDataRight == NULL) ? 1 : 2;

  if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) {
    /* Reserved bits */
    if (FDKreadBits(hBs, 1)) { /* bs_data_extra */
      FDKreadBits(hBs, 4);
      if ((flags & SBRDEC_SYNTAX_SCAL) || (nCh == 2)) {
        FDKreadBits(hBs, 4);
      }
    }
  }

  if (nCh == 2) {
    /* Read coupling flag */
    bs_coupling = FDKreadBits(hBs, 1);
    if (bs_coupling) {
      hFrameDataLeft->coupling = COUPLING_LEVEL;
      hFrameDataRight->coupling = COUPLING_BAL;
    } else {
      hFrameDataLeft->coupling = COUPLING_OFF;
      hFrameDataRight->coupling = COUPLING_OFF;
    }
  } else {
    if (flags & SBRDEC_SYNTAX_SCAL) {
      FDKreadBits(hBs, 1); /* bs_coupling */
    }
    hFrameDataLeft->coupling = COUPLING_OFF;
  }

  if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
    if (flags & SBRDEC_USAC_HARMONICSBR) {
      hFrameDataLeft->sbrPatchingMode = FDKreadBit(hBs);
      if (hFrameDataLeft->sbrPatchingMode == 0) {
        hFrameDataLeft->sbrOversamplingFlag = FDKreadBit(hBs);
        if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */
          hFrameDataLeft->sbrPitchInBins = FDKreadBits(hBs, 7);
        } else {
          hFrameDataLeft->sbrPitchInBins = 0;
        }
      } else {
        hFrameDataLeft->sbrOversamplingFlag = 0;
        hFrameDataLeft->sbrPitchInBins = 0;
      }

      if (nCh == 2) {
        if (bs_coupling) {
          hFrameDataRight->sbrPatchingMode = hFrameDataLeft->sbrPatchingMode;
          hFrameDataRight->sbrOversamplingFlag =
              hFrameDataLeft->sbrOversamplingFlag;
          hFrameDataRight->sbrPitchInBins = hFrameDataLeft->sbrPitchInBins;
        } else {
          hFrameDataRight->sbrPatchingMode = FDKreadBit(hBs);
          if (hFrameDataRight->sbrPatchingMode == 0) {
            hFrameDataRight->sbrOversamplingFlag = FDKreadBit(hBs);
            if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */
              hFrameDataRight->sbrPitchInBins = FDKreadBits(hBs, 7);
            } else {
              hFrameDataRight->sbrPitchInBins = 0;
            }
          } else {
            hFrameDataRight->sbrOversamplingFlag = 0;
            hFrameDataRight->sbrPitchInBins = 0;
          }
        }
      }
    } else {
      if (nCh == 2) {
        hFrameDataRight->sbrPatchingMode = 1;
        hFrameDataRight->sbrOversamplingFlag = 0;
        hFrameDataRight->sbrPitchInBins = 0;
      }

      hFrameDataLeft->sbrPatchingMode = 1;
      hFrameDataLeft->sbrOversamplingFlag = 0;
      hFrameDataLeft->sbrPitchInBins = 0;
    }
  } else {
    if (nCh == 2) {
      hFrameDataRight->sbrPatchingMode = 1;
      hFrameDataRight->sbrOversamplingFlag = 0;
      hFrameDataRight->sbrPitchInBins = 0;
    }

    hFrameDataLeft->sbrPatchingMode = 1;
    hFrameDataLeft->sbrOversamplingFlag = 0;
    hFrameDataLeft->sbrPitchInBins = 0;
  }

  /*
    sbr_grid(): Grid control
  */
  if (hHeaderData->bs_info.pvc_mode) {
    FDK_ASSERT(nCh == 1); /* PVC not possible for CPE */
    if (!extractPvcFrameInfo(hBs, hHeaderData, hFrameDataLeft,
                             hFrameDataLeftPrev, pvc_mode_last, flags))
      return 0;

    if (!checkFrameInfo(&hFrameDataLeft->frameInfo,
                        hHeaderData->numberTimeSlots, overlap,
                        hHeaderData->timeStep))
      return 0;
  } else {
    if (!extractFrameInfo(hBs, hHeaderData, hFrameDataLeft, 1, flags)) return 0;

    if (!checkFrameInfo(&hFrameDataLeft->frameInfo,
                        hHeaderData->numberTimeSlots, overlap,
                        hHeaderData->timeStep))
      return 0;
  }
  if (nCh == 2) {
    if (hFrameDataLeft->coupling) {
      FDKmemcpy(&hFrameDataRight->frameInfo, &hFrameDataLeft->frameInfo,
                sizeof(FRAME_INFO));
      hFrameDataRight->ampResolutionCurrentFrame =
          hFrameDataLeft->ampResolutionCurrentFrame;
    } else {
      if (!extractFrameInfo(hBs, hHeaderData, hFrameDataRight, 2, flags))
        return 0;

      if (!checkFrameInfo(&hFrameDataRight->frameInfo,
                          hHeaderData->numberTimeSlots, overlap,
                          hHeaderData->timeStep))
        return 0;
    }
  }

  /*
    sbr_dtdf(): Fetch domain vectors (time or frequency direction for
    delta-coding)
  */
  sbrGetDirectionControlData(hFrameDataLeft, hBs, flags,
                             hHeaderData->bs_info.pvc_mode);
  if (nCh == 2) {
    sbrGetDirectionControlData(hFrameDataRight, hBs, flags, 0);
  }

  /* sbr_invf() */
  for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
    hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2);
  }
  if (nCh == 2) {
    if (hFrameDataLeft->coupling) {
      for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
        hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i];
      }
    } else {
      for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
        hFrameDataRight->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2);
      }
    }
  }

  if (nCh == 1) {
    if (hHeaderData->bs_info.pvc_mode) {
      if (!sbrGetPvcEnvelope(hHeaderData, hFrameDataLeft, hBs, flags,
                             hHeaderData->bs_info.pvc_mode))
        return 0;
    } else if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags))
      return 0;

    sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs);
  } else if (hFrameDataLeft->coupling) {
    if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) {
      return 0;
    }

    sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs);

    if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) {
      return 0;
    }
    sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs);
  } else { /* nCh == 2 && no coupling */

    if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) return 0;

    if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) return 0;

    sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs);

    sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs);
  }

  sbrGetSyntheticCodedData(hHeaderData, hFrameDataLeft, hBs, flags);
  if (nCh == 2) {
    sbrGetSyntheticCodedData(hHeaderData, hFrameDataRight, hBs, flags);
  }

  if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) {
    if (!extractExtendedData(hHeaderData, hBs, hParametricStereoDec)) {
      return 0;
    }
  }

  return 1;
}

/*!
  \brief   Read direction control data from bitstream
*/
void sbrGetDirectionControlData(
    HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
    HANDLE_FDK_BITSTREAM hBs,           /*!< handle to struct BIT_BUF */
    const UINT flags, const int bs_pvc_mode)

{
  int i;
  int indepFlag = 0;

  if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
    indepFlag = flags & SBRDEC_USAC_INDEP;
  }

  if (bs_pvc_mode == 0) {
    i = 0;
    if (indepFlag) {
      h_frame_data->domain_vec[i++] = 0;
    }
    for (; i < h_frame_data->frameInfo.nEnvelopes; i++) {
      h_frame_data->domain_vec[i] = FDKreadBits(hBs, 1);
    }
  }

  i = 0;
  if (indepFlag) {
    h_frame_data->domain_vec_noise[i++] = 0;
  }
  for (; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) {
    h_frame_data->domain_vec_noise[i] = FDKreadBits(hBs, 1);
  }
}

/*!
  \brief   Read noise-floor-level data from bitstream
*/
void sbrGetNoiseFloorData(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
    HANDLE_FDK_BITSTREAM hBs)           /*!< handle to struct BIT_BUF */
{
  int i, j;
  int delta;
  COUPLING_MODE coupling;
  int noNoiseBands = hHeaderData->freqBandData.nNfb;

  Huffman hcb_noiseF;
  Huffman hcb_noise;
  int envDataTableCompFactor;

  coupling = h_frame_data->coupling;

  /*
    Select huffman codebook depending on coupling mode
  */
  if (coupling == COUPLING_BAL) {
    hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T;
    hcb_noiseF =
        (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; /* "sbr_huffBook_NoiseBalance11F"
                                                              */
    envDataTableCompFactor = 1;
  } else {
    hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T;
    hcb_noiseF =
        (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F; /* "sbr_huffBook_NoiseLevel11F"
                                                            */
    envDataTableCompFactor = 0;
  }

  /*
    Read raw noise-envelope data
  */
  for (i = 0; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) {
    if (h_frame_data->domain_vec_noise[i] == 0) {
      if (coupling == COUPLING_BAL) {
        h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] =
            (FIXP_SGL)(((int)FDKreadBits(hBs, 5)) << envDataTableCompFactor);
      } else {
        h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] =
            (FIXP_SGL)(int)FDKreadBits(hBs, 5);
      }

      for (j = 1; j < noNoiseBands; j++) {
        delta = DecodeHuffmanCW(hcb_noiseF, hBs);
        h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] =
            (FIXP_SGL)(delta << envDataTableCompFactor);
      }
    } else {
      for (j = 0; j < noNoiseBands; j++) {
        delta = DecodeHuffmanCW(hcb_noise, hBs);
        h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] =
            (FIXP_SGL)(delta << envDataTableCompFactor);
      }
    }
  }
}

/* ns = mapNsMode2ns[pvcMode-1][nsMode] */
static const UCHAR mapNsMode2ns[2][2] = {
    {16, 4}, /* pvcMode = 1 */
    {12, 3}  /* pvcMode = 2 */
};

static int sbrGetPvcEnvelope(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
    HANDLE_FDK_BITSTREAM hBs,           /*!< handle to struct BIT_BUF */
    const UINT flags, const UINT pvcMode) {
  int divMode, nsMode;
  int indepFlag = flags & SBRDEC_USAC_INDEP;
  UCHAR *pvcID = h_frame_data->pvcID;

  divMode = FDKreadBits(hBs, PVC_DIVMODE_BITS);
  nsMode = FDKreadBit(hBs);
  FDK_ASSERT((pvcMode == 1) || (pvcMode == 2));
  h_frame_data->ns = mapNsMode2ns[pvcMode - 1][nsMode];

  if (divMode <= 3) {
    int i, k = 1, sum_length = 0, reuse_pcvID;

    /* special treatment for first time slot k=0 */
    indepFlag ? (reuse_pcvID = 0) : (reuse_pcvID = FDKreadBit(hBs));
    if (reuse_pcvID) {
      pvcID[0] = hHeaderData->pvcIDprev;
    } else {
      pvcID[0] = FDKreadBits(hBs, PVC_PVCID_BITS);
    }

    /* other time slots k>0 */
    for (i = 0; i < divMode; i++) {
      int length, numBits = 4;

      if (sum_length >= 13) {
        numBits = 1;
      } else if (sum_length >= 11) {
        numBits = 2;
      } else if (sum_length >= 7) {
        numBits = 3;
      }

      length = FDKreadBits(hBs, numBits);
      sum_length += length + 1;
      if (sum_length >= PVC_NTIMESLOT) {
        return 0; /* parse error */
      }
      for (; length--; k++) {
        pvcID[k] = pvcID[k - 1];
      }
      pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS);
    }
    for (; k < 16; k++) {
      pvcID[k] = pvcID[k - 1];
    }
  } else { /* divMode >= 4 */
    int num_grid_info, fixed_length, grid_info, j, k = 0;

    divMode -= 4;
    num_grid_info = 2 << divMode;
    fixed_length = 8 >> divMode;
    FDK_ASSERT(num_grid_info * fixed_length == PVC_NTIMESLOT);

    /* special treatment for first time slot k=0 */
    indepFlag ? (grid_info = 1) : (grid_info = FDKreadBit(hBs));
    if (grid_info) {
      pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS);
    } else {
      pvcID[k++] = hHeaderData->pvcIDprev;
    }
    j = fixed_length - 1;
    for (; j--; k++) {
      pvcID[k] = pvcID[k - 1];
    }
    num_grid_info--;

    /* other time slots k>0 */
    for (; num_grid_info--;) {
      j = fixed_length;
      grid_info = FDKreadBit(hBs);
      if (grid_info) {
        pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS);
        j--;
      }
      for (; j--; k++) {
        pvcID[k] = pvcID[k - 1];
      }
    }
  }

  hHeaderData->pvcIDprev = pvcID[PVC_NTIMESLOT - 1];

  /* usage of PVC excludes inter-TES tool */
  h_frame_data->iTESactive = (UCHAR)0;

  return 1;
}
/*!
  \brief   Read envelope data from bitstream
*/
static int sbrGetEnvelope(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
    HANDLE_FDK_BITSTREAM hBs,           /*!< handle to struct BIT_BUF */
    const UINT flags) {
  int i, j;
  UCHAR no_band[MAX_ENVELOPES];
  int delta = 0;
  int offset = 0;
  COUPLING_MODE coupling = h_frame_data->coupling;
  int ampRes = hHeaderData->bs_info.ampResolution;
  int nEnvelopes = h_frame_data->frameInfo.nEnvelopes;
  int envDataTableCompFactor;
  int start_bits, start_bits_balance;
  Huffman hcb_t, hcb_f;

  h_frame_data->nScaleFactors = 0;

  if ((h_frame_data->frameInfo.frameClass == 0) && (nEnvelopes == 1)) {
    if (flags & SBRDEC_ELD_GRID)
      ampRes = h_frame_data->ampResolutionCurrentFrame;
    else
      ampRes = 0;
  }
  h_frame_data->ampResolutionCurrentFrame = ampRes;

  /*
    Set number of bits for first value depending on amplitude resolution
  */
  if (ampRes == 1) {
    start_bits = 6;
    start_bits_balance = 5;
  } else {
    start_bits = 7;
    start_bits_balance = 6;
  }

  /*
    Calculate number of values for each envelope and alltogether
  */
  for (i = 0; i < nEnvelopes; i++) {
    no_band[i] =
        hHeaderData->freqBandData.nSfb[h_frame_data->frameInfo.freqRes[i]];
    h_frame_data->nScaleFactors += no_band[i];
  }
  if (h_frame_data->nScaleFactors > MAX_NUM_ENVELOPE_VALUES) return 0;

  /*
    Select Huffman codebook depending on coupling mode and amplitude resolution
  */
  if (coupling == COUPLING_BAL) {
    envDataTableCompFactor = 1;
    if (ampRes == 0) {
      hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10T;
      hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10F;
    } else {
      hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11T;
      hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F;
    }
  } else {
    envDataTableCompFactor = 0;
    if (ampRes == 0) {
      hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10T;
      hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10F;
    } else {
      hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11T;
      hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F;
    }
  }

  h_frame_data->iTESactive = (UCHAR)0; /* disable inter-TES by default */
  /*
    Now read raw envelope data
  */
  for (j = 0, offset = 0; j < nEnvelopes; j++) {
    if (h_frame_data->domain_vec[j] == 0) {
      if (coupling == COUPLING_BAL) {
        h_frame_data->iEnvelope[offset] =
            (FIXP_SGL)(((int)FDKreadBits(hBs, start_bits_balance))
                       << envDataTableCompFactor);
      } else {
        h_frame_data->iEnvelope[offset] =
            (FIXP_SGL)(int)FDKreadBits(hBs, start_bits);
      }
    }

    for (i = (1 - h_frame_data->domain_vec[j]); i < no_band[j]; i++) {
      if (h_frame_data->domain_vec[j] == 0) {
        delta = DecodeHuffmanCW(hcb_f, hBs);
      } else {
        delta = DecodeHuffmanCW(hcb_t, hBs);
      }

      h_frame_data->iEnvelope[offset + i] =
          (FIXP_SGL)(delta << envDataTableCompFactor);
    }
    if ((flags & SBRDEC_SYNTAX_USAC) && (flags & SBRDEC_USAC_ITES)) {
      int bs_temp_shape = FDKreadBit(hBs);
      FDK_ASSERT(j < 8);
      h_frame_data->iTESactive |= (UCHAR)(bs_temp_shape << j);
      if (bs_temp_shape) {
        h_frame_data->interTempShapeMode[j] =
            FDKread2Bits(hBs); /* bs_inter_temp_shape_mode */
      } else {
        h_frame_data->interTempShapeMode[j] = 0;
      }
    }
    offset += no_band[j];
  }

#if ENV_EXP_FRACT
  /* Convert from int to scaled fract (ENV_EXP_FRACT bits for the fractional
   * part) */
  for (i = 0; i < h_frame_data->nScaleFactors; i++) {
    h_frame_data->iEnvelope[i] <<= ENV_EXP_FRACT;
  }
#endif

  return 1;
}

/***************************************************************************/
/*!
  \brief    Generates frame info for FIXFIXonly frame class used for low delay
 version

  \return   zero for error, one for correct.
 ****************************************************************************/
static int generateFixFixOnly(FRAME_INFO *hSbrFrameInfo, int tranPosInternal,
                              int numberTimeSlots, const UINT flags) {
  int nEnv, i, tranIdx;
  const int *pTable;

  switch (numberTimeSlots) {
    case 8:
      pTable = FDK_sbrDecoder_envelopeTable_8[tranPosInternal];
      break;
    case 15:
      pTable = FDK_sbrDecoder_envelopeTable_15[tranPosInternal];
      break;
    case 16:
      pTable = FDK_sbrDecoder_envelopeTable_16[tranPosInternal];
      break;
    default:
      return 0;
  }

  /* look number of envelopes in table */
  nEnv = pTable[0];
  /* look up envelope distribution in table */
  for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2];
  /* open and close frame border */
  hSbrFrameInfo->borders[0] = 0;
  hSbrFrameInfo->borders[nEnv] = numberTimeSlots;
  hSbrFrameInfo->nEnvelopes = nEnv;

  /* transient idx */
  tranIdx = hSbrFrameInfo->tranEnv = pTable[1];

  /* add noise floors */
  hSbrFrameInfo->bordersNoise[0] = 0;
  hSbrFrameInfo->bordersNoise[1] =
      hSbrFrameInfo->borders[tranIdx ? tranIdx : 1];
  hSbrFrameInfo->bordersNoise[2] = numberTimeSlots;
  /* nEnv is always > 1, so nNoiseEnvelopes is always 2 (IEC 14496-3 4.6.19.3.2)
   */
  hSbrFrameInfo->nNoiseEnvelopes = 2;

  return 1;
}

/*!
  \brief  Extracts LowDelaySBR control data from the bitstream.

  \return zero for bitstream error, one for correct.
*/
static int extractLowDelayGrid(
    HANDLE_FDK_BITSTREAM hBitBuf, /*!< bitbuffer handle */
    HANDLE_SBR_HEADER_DATA hHeaderData,
    HANDLE_SBR_FRAME_DATA
        h_frame_data, /*!< contains the FRAME_INFO struct to be filled */
    int timeSlots, const UINT flags) {
  FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo;
  INT numberTimeSlots = hHeaderData->numberTimeSlots;
  INT temp = 0, k;

  /* FIXFIXonly framing case */
  h_frame_data->frameInfo.frameClass = 0;

  /* get the transient position from the bitstream */
  switch (timeSlots) {
    case 8:
      /* 3bit transient position (temp={0;..;7}) */
      temp = FDKreadBits(hBitBuf, 3);
      break;

    case 16:
    case 15:
      /* 4bit transient position (temp={0;..;15}) */
      temp = FDKreadBits(hBitBuf, 4);
      break;

    default:
      return 0;
  }

  /* For "case 15" only*/
  if (temp >= timeSlots) {
    return 0;
  }

  /* calculate borders according to the transient position */
  if (!generateFixFixOnly(pFrameInfo, temp, numberTimeSlots, flags)) {
    return 0;
  }

  /* decode freq res: */
  for (k = 0; k < pFrameInfo->nEnvelopes; k++) {
    pFrameInfo->freqRes[k] =
        (UCHAR)FDKreadBits(hBitBuf, 1); /* f = F [1 bits] */
  }

  return 1;
}

/*!
  \brief   Extract the PVC frame information (structure FRAME_INFO) from the
  bitstream \return  Zero for bitstream error, one for correct.
*/
int extractPvcFrameInfo(
    HANDLE_FDK_BITSTREAM hBs,           /*!< bitbuffer handle */
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the
                                           frame-info will be stored */
    HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where
                                                     the previous frame-info
                                                     will be stored */
    UCHAR pvc_mode_last,                          /**< PVC mode of last frame */
    const UINT flags) {
  FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo;
  FRAME_INFO *pPrevFrameInfo = &h_prev_frame_data->prevFrameInfo;
  int bs_var_len_hf, bs_noise_position;
  bs_noise_position = FDKreadBits(hBs, 4); /* SBR_PVC_NOISEPOSITION_BITS 4 */
  bs_var_len_hf = FDKreadBit(hBs);
  pFrameInfo->noisePosition = bs_noise_position;
  pFrameInfo->tranEnv = -1;

  /* Init for bs_noise_position == 0 in case a parse error is found below. */
  pFrameInfo->nEnvelopes = 1;
  pFrameInfo->nNoiseEnvelopes = 1;
  pFrameInfo->freqRes[0] = 0;

  if (bs_var_len_hf) { /* 1 or 3 Bits */
    pFrameInfo->varLength = FDKreadBits(hBs, 2) + 1;
    if (pFrameInfo->varLength > 3) {
      pFrameInfo->varLength =
          0;    /* assume bs_var_len_hf == 0 in case of error */
      return 0; /* reserved value -> parse error */
    }
  } else {
    pFrameInfo->varLength = 0;
  }

  if (bs_noise_position) {
    pFrameInfo->nEnvelopes = 2;
    pFrameInfo->nNoiseEnvelopes = 2;
    FDKmemclear(pFrameInfo->freqRes, sizeof(pFrameInfo->freqRes));
  }

  /* frame border calculation */
  if (hHeaderData->bs_info.pvc_mode > 0) {
    /* See "7.5.1.4 HF adjustment of SBR envelope scalefactors" for reference.
     */

    FDK_ASSERT((pFrameInfo->nEnvelopes == 1) || (pFrameInfo->nEnvelopes == 2));

    /* left timeborder-offset: use the timeborder of prev SBR frame */
    if (pPrevFrameInfo->nEnvelopes > 0) {
      pFrameInfo->borders[0] =
          pPrevFrameInfo->borders[pPrevFrameInfo->nEnvelopes] - PVC_NTIMESLOT;
      FDK_ASSERT(pFrameInfo->borders[0] <= 3);
    } else {
      pFrameInfo->borders[0] = 0;
    }

    /* right timeborder-offset: */
    pFrameInfo->borders[pFrameInfo->nEnvelopes] = 16 + pFrameInfo->varLength;

    if (pFrameInfo->nEnvelopes == 2) {
      pFrameInfo->borders[1] = pFrameInfo->noisePosition;
    }

    /* Calculation of PVC time borders t_EPVC */
    if (pvc_mode_last == 0) {
      /* there was a legacy SBR frame before this frame => use bs_var_len' for
       * first PVC timeslot */
      pFrameInfo->pvcBorders[0] = pFrameInfo->borders[0];
    } else {
      pFrameInfo->pvcBorders[0] = 0;
    }
    if (pFrameInfo->nEnvelopes == 2) {
      pFrameInfo->pvcBorders[1] = pFrameInfo->borders[1];
    }
    pFrameInfo->pvcBorders[pFrameInfo->nEnvelopes] = 16;

    /* calculation of SBR noise-floor time-border vector: */
    for (INT i = 0; i <= pFrameInfo->nNoiseEnvelopes; i++) {
      pFrameInfo->bordersNoise[i] = pFrameInfo->borders[i];
    }

    pFrameInfo->tranEnv = -1; /* tranEnv not used */
  }
  return 1;
}

/*!
  \brief   Extract the frame information (structure FRAME_INFO) from the
  bitstream \return  Zero for bitstream error, one for correct.
*/
int extractFrameInfo(
    HANDLE_FDK_BITSTREAM hBs,           /*!< bitbuffer handle */
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the
                                           frame-info will be stored */
    const UINT nrOfChannels, const UINT flags) {
  FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo;
  int numberTimeSlots = hHeaderData->numberTimeSlots;
  int pointer_bits = 0, nEnv = 0, b = 0, border, i, n = 0, k, p, aL, aR, nL, nR,
      temp = 0, staticFreqRes;
  UCHAR frameClass;

  if (flags & SBRDEC_ELD_GRID) {
    /* CODEC_AACLD (LD+SBR) only uses the normal 0 Grid for non-transient Frames
     * and the LowDelayGrid for transient Frames */
    frameClass = FDKreadBits(hBs, 1); /* frameClass = [1 bit] */
    if (frameClass == 1) {
      /* if frameClass == 1, extract LowDelaySbrGrid, otherwise extract normal
       * SBR-Grid for FIXIFX */
      /* extract the AACLD-Sbr-Grid */
      pFrameInfo->frameClass = frameClass;
      int err = 1;
      err = extractLowDelayGrid(hBs, hHeaderData, h_frame_data, numberTimeSlots,
                                flags);
      return err;
    }
  } else {
    frameClass = FDKreadBits(hBs, 2); /* frameClass = C [2 bits] */
  }

  switch (frameClass) {
    case 0:
      temp = FDKreadBits(hBs, 2); /* E [2 bits ] */
      nEnv = (int)(1 << temp);    /* E -> e */

      if ((flags & SBRDEC_ELD_GRID) && (nEnv == 1))
        h_frame_data->ampResolutionCurrentFrame =
            FDKreadBits(hBs, 1); /* new ELD Syntax 07-11-09 */

      staticFreqRes = FDKreadBits(hBs, 1);

      if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
        if (nEnv > MAX_ENVELOPES_USAC) return 0;
      } else

        b = nEnv + 1;
      switch (nEnv) {
        case 1:
          switch (numberTimeSlots) {
            case 15:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_15,
                        sizeof(FRAME_INFO));
              break;
            case 16:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_16,
                        sizeof(FRAME_INFO));
              break;
            default:
              FDK_ASSERT(0);
          }
          break;
        case 2:
          switch (numberTimeSlots) {
            case 15:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_15,
                        sizeof(FRAME_INFO));
              break;
            case 16:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_16,
                        sizeof(FRAME_INFO));
              break;
            default:
              FDK_ASSERT(0);
          }
          break;
        case 4:
          switch (numberTimeSlots) {
            case 15:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_15,
                        sizeof(FRAME_INFO));
              break;
            case 16:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_16,
                        sizeof(FRAME_INFO));
              break;
            default:
              FDK_ASSERT(0);
          }
          break;
        case 8:
#if (MAX_ENVELOPES >= 8)
          switch (numberTimeSlots) {
            case 15:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_15,
                        sizeof(FRAME_INFO));
              break;
            case 16:
              FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_16,
                        sizeof(FRAME_INFO));
              break;
            default:
              FDK_ASSERT(0);
          }
          break;
#else
          return 0;
#endif
      }
      /* Apply correct freqRes (High is default) */
      if (!staticFreqRes) {
        for (i = 0; i < nEnv; i++) pFrameInfo->freqRes[i] = 0;
      }

      break;
    case 1:
    case 2:
      temp = FDKreadBits(hBs, 2); /* A [2 bits] */

      n = FDKreadBits(hBs, 2); /* n = N [2 bits] */

      nEnv = n + 1; /* # envelopes */
      b = nEnv + 1; /* # borders   */

      break;
  }

  switch (frameClass) {
    case 1:
      /* Decode borders: */
      pFrameInfo->borders[0] = 0;      /* first border          */
      border = temp + numberTimeSlots; /* A -> aR               */
      i = b - 1;                       /* frame info index for last border */
      pFrameInfo->borders[i] = border; /* last border                      */

      for (k = 0; k < n; k++) {
        temp = FDKreadBits(hBs, 2); /* R [2 bits] */
        border -= (2 * temp + 2);   /* R -> r                */
        pFrameInfo->borders[--i] = border;
      }

      /* Decode pointer: */
      pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1));
      p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */

      if (p > n + 1) return 0;

      pFrameInfo->tranEnv = p ? n + 2 - p : -1;

      /* Decode freq res: */
      for (k = n; k >= 0; k--) {
        pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */
      }

      /* Calculate noise floor middle border: */
      if (p == 0 || p == 1)
        pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n];
      else
        pFrameInfo->bordersNoise[1] = pFrameInfo->borders[pFrameInfo->tranEnv];

      break;

    case 2:
      /* Decode borders: */
      border = temp;                   /* A -> aL */
      pFrameInfo->borders[0] = border; /* first border */

      for (k = 1; k <= n; k++) {
        temp = FDKreadBits(hBs, 2); /* R [2 bits] */
        border += (2 * temp + 2);   /* R -> r                */
        pFrameInfo->borders[k] = border;
      }
      pFrameInfo->borders[k] = numberTimeSlots; /* last border */

      /* Decode pointer: */
      pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1));
      p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */
      if (p > n + 1) return 0;

      if (p == 0 || p == 1)
        pFrameInfo->tranEnv = -1;
      else
        pFrameInfo->tranEnv = p - 1;

      /* Decode freq res: */
      for (k = 0; k <= n; k++) {
        pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */
      }

      /* Calculate noise floor middle border: */
      switch (p) {
        case 0:
          pFrameInfo->bordersNoise[1] = pFrameInfo->borders[1];
          break;
        case 1:
          pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n];
          break;
        default:
          pFrameInfo->bordersNoise[1] =
              pFrameInfo->borders[pFrameInfo->tranEnv];
          break;
      }

      break;

    case 3:
      /* v_ctrlSignal = [frameClass,aL,aR,nL,nR,v_rL,v_rR,p,v_fLR]; */

      aL = FDKreadBits(hBs, 2); /* AL [2 bits], AL -> aL */

      aR = FDKreadBits(hBs, 2) + numberTimeSlots; /* AR [2 bits], AR -> aR */

      nL = FDKreadBits(hBs, 2); /* nL = NL [2 bits] */

      nR = FDKreadBits(hBs, 2); /* nR = NR [2 bits] */

      /*-------------------------------------------------------------------------
        Calculate help variables
        --------------------------------------------------------------------------*/

      /* general: */
      nEnv = nL + nR + 1; /* # envelopes */
      if (nEnv > MAX_ENVELOPES) return 0;
      b = nEnv + 1; /* # borders   */

      /*-------------------------------------------------------------------------
        Decode envelopes
        --------------------------------------------------------------------------*/

      /* L-borders:   */
      border = aL; /* first border */
      pFrameInfo->borders[0] = border;

      for (k = 1; k <= nL; k++) {
        temp = FDKreadBits(hBs, 2); /* R [2 bits] */
        border += (2 * temp + 2);   /* R -> r                */
        pFrameInfo->borders[k] = border;
      }

      /* R-borders:  */
      border = aR; /* last border */
      i = nEnv;

      pFrameInfo->borders[i] = border;

      for (k = 0; k < nR; k++) {
        temp = FDKreadBits(hBs, 2); /* R [2 bits] */
        border -= (2 * temp + 2);   /* R -> r                */
        pFrameInfo->borders[--i] = border;
      }

      /* decode pointer: */
      pointer_bits =
          DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(nL + nR + 1));
      p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */

      if (p > nL + nR + 1) return 0;

      pFrameInfo->tranEnv = p ? b - p : -1;

      /* decode freq res: */
      for (k = 0; k < nEnv; k++) {
        pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */
      }

      /*-------------------------------------------------------------------------
        Decode noise floors
        --------------------------------------------------------------------------*/
      pFrameInfo->bordersNoise[0] = aL;

      if (nEnv == 1) {
        /* 1 noise floor envelope: */
        pFrameInfo->bordersNoise[1] = aR;
      } else {
        /* 2 noise floor envelopes */
        if (p == 0 || p == 1)
          pFrameInfo->bordersNoise[1] = pFrameInfo->borders[nEnv - 1];
        else
          pFrameInfo->bordersNoise[1] =
              pFrameInfo->borders[pFrameInfo->tranEnv];
        pFrameInfo->bordersNoise[2] = aR;
      }
      break;
  }

  /*
    Store number of envelopes, noise floor envelopes and frame class
  */
  pFrameInfo->nEnvelopes = nEnv;

  if (nEnv == 1)
    pFrameInfo->nNoiseEnvelopes = 1;
  else
    pFrameInfo->nNoiseEnvelopes = 2;

  pFrameInfo->frameClass = frameClass;

  if (pFrameInfo->frameClass == 2 || pFrameInfo->frameClass == 1) {
    /* calculate noise floor first and last borders: */
    pFrameInfo->bordersNoise[0] = pFrameInfo->borders[0];
    pFrameInfo->bordersNoise[pFrameInfo->nNoiseEnvelopes] =
        pFrameInfo->borders[nEnv];
  }

  return 1;
}

/*!
  \brief   Check if the frameInfo vector has reasonable values.
  \return  Zero for error, one for correct
*/
static int checkFrameInfo(
    FRAME_INFO *pFrameInfo, /*!< pointer to frameInfo */
    int numberOfTimeSlots,  /*!< QMF time slots per frame */
    int overlap,            /*!< Amount of overlap QMF time slots */
    int timeStep)           /*!< QMF slots to SBR slots step factor */
{
  int maxPos, i, j;
  int startPos;
  int stopPos;
  int tranEnv;
  int startPosNoise;
  int stopPosNoise;
  int nEnvelopes = pFrameInfo->nEnvelopes;
  int nNoiseEnvelopes = pFrameInfo->nNoiseEnvelopes;

  if (nEnvelopes < 1 || nEnvelopes > MAX_ENVELOPES) return 0;

  if (nNoiseEnvelopes > MAX_NOISE_ENVELOPES) return 0;

  startPos = pFrameInfo->borders[0];
  stopPos = pFrameInfo->borders[nEnvelopes];
  tranEnv = pFrameInfo->tranEnv;
  startPosNoise = pFrameInfo->bordersNoise[0];
  stopPosNoise = pFrameInfo->bordersNoise[nNoiseEnvelopes];

  if (overlap < 0 || overlap > (3 * (4))) {
    return 0;
  }
  if (timeStep < 1 || timeStep > (4)) {
    return 0;
  }
  maxPos = numberOfTimeSlots + (overlap / timeStep);

  /* Check that the start and stop positions of the frame are reasonable values.
   */
  if ((startPos < 0) || (startPos >= stopPos)) return 0;
  if (startPos > maxPos - numberOfTimeSlots) /* First env. must start in or
                                                directly after the overlap
                                                buffer */
    return 0;
  if (stopPos < numberOfTimeSlots) /* One complete frame must be ready for
                                      output after processing */
    return 0;
  if (stopPos > maxPos) return 0;

  /* Check that the  start border for every envelope is strictly later in time
   */
  for (i = 0; i < nEnvelopes; i++) {
    if (pFrameInfo->borders[i] >= pFrameInfo->borders[i + 1]) return 0;
  }

  /* Check that the envelope to be shortened is actually among the envelopes */
  if (tranEnv > nEnvelopes) return 0;

  /* Check the noise borders */
  if (nEnvelopes == 1 && nNoiseEnvelopes > 1) return 0;

  if (startPos != startPosNoise || stopPos != stopPosNoise) return 0;

  /* Check that the  start border for every noise-envelope is strictly later in
   * time*/
  for (i = 0; i < nNoiseEnvelopes; i++) {
    if (pFrameInfo->bordersNoise[i] >= pFrameInfo->bordersNoise[i + 1])
      return 0;
  }

  /* Check that every noise border is the same as an envelope border*/
  for (i = 0; i < nNoiseEnvelopes; i++) {
    startPosNoise = pFrameInfo->bordersNoise[i];

    for (j = 0; j < nEnvelopes; j++) {
      if (pFrameInfo->borders[j] == startPosNoise) break;
    }
    if (j == nEnvelopes) return 0;
  }

  return 1;
}
