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

/*********************** MPEG surround decoder library *************************

   Author(s):

   Description: SAC Decoder Library Interface

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

#include "sac_dec_lib.h"
#include "sac_dec_interface.h"
#include "sac_dec.h"
#include "sac_bitdec.h"
#include "FDK_matrixCalloc.h"

#define MPS_DATA_BUFFER_SIZE (2048)

/**
 * \brief MPEG Surround data indication.
 **/
typedef enum {
  MPEGS_ANCTYPE_FRAME = 0, /*!< MPEG Surround frame, see ISO/IEC 23003-1 */
  MPEGS_ANCTYPE_HEADER_AND_FRAME = 1, /*!< MPEG Surround header and MPEG
                                         Surround frame, see ISO/IEC 23003-1 */
  MPEGS_ANCTYPE_RESERVED_1 = 2,       /*!< reserved, see ISO/IEC 23003-1 */
  MPEGS_ANCTYPE_RESERVED_2 = 3        /*!< reserved, see ISO/IEC 23003-1*/
} MPEGS_ANCTYPE;

/**
 * \brief MPEG Surround data segment indication.
 **/
typedef enum {
  MPEGS_CONTINUE = 0, /*!< Indicates if data segment continues a data block. */
  MPEGS_STOP = 1,     /*!< Indicates if data segment ends a data block. */
  MPEGS_START = 2,    /*!< Indicates if data segment begins a data block. */
  MPEGS_START_STOP =
      3 /*!< Indicates if data segment begins and ends a data block. */
} MPEGS_ANCSTARTSTOP;

/**
 * \brief MPEG Surround synchronizaiton state.
 *
 *  CAUTION: Changing the enumeration values can break the sync mechanism
 *because it is based on comparing the state values.
 **/
typedef enum {
  MPEGS_SYNC_LOST =
      0, /*!< Indicates lost sync because of current discontinuity. */
  MPEGS_SYNC_FOUND = 1,   /*!< Parsed a valid header and (re)intialization was
                             successfully completed. */
  MPEGS_SYNC_COMPLETE = 2 /*!< In sync and continuous. Found an independent
                             frame in addition to MPEGS_SYNC_FOUND.
                               Precondition: MPEGS_SYNC_FOUND. */
} MPEGS_SYNCSTATE;

/**
 * \brief MPEG Surround operation mode.
 **/
typedef enum {
  MPEGS_OPMODE_EMM = 0,           /*!< Mode: Enhanced Matrix Mode (Blind) */
  MPEGS_OPMODE_MPS_PAYLOAD = 1,   /*!< Mode: Normal, Stereo or Binaural */
  MPEGS_OPMODE_NO_MPS_PAYLOAD = 2 /*!< Mode: no MPEG Surround payload */
} MPEGS_OPMODE;

/**
 * \brief MPEG Surround init flags.
 **/
typedef enum {
  MPEGS_INIT_OK = 0x00000000, /*!< indicate correct initialization */
  MPEGS_INIT_ENFORCE_REINIT =
      0x00000001, /*!< indicate complete initialization */

  MPEGS_INIT_CHANGE_OUTPUT_MODE =
      0x00000010, /*!< indicate change of the output mode */
  MPEGS_INIT_CHANGE_PARTIALLY_COMPLEX =
      0x00000020, /*!< indicate change of low power/high quality */
  MPEGS_INIT_CHANGE_TIME_FREQ_INTERFACE =
      0x00000040, /*!< indicate change of qmf/time interface */
  MPEGS_INIT_CHANGE_HEADER = 0x00000080, /*!< indicate change of header */

  MPEGS_INIT_ERROR_PAYLOAD =
      0x00000100, /*!< indicate payload/ancType/ancStartStop error */

  MPEGS_INIT_BS_INTERRUPTION =
      0x00001000, /*!< indicate bitstream interruption  */
  MPEGS_INIT_CLEAR_HISTORY =
      0x00002000, /*!< indicate that all states shall be cleared */

  /* Re-initialization of submodules */

  MPEGS_INIT_CHANGE_CONCEAL_PARAMS = 0x00100000, /*!< indicate a change of at
                                                    least one error concealment
                                                    param */

  /* No re-initialization needed, currently not used */
  MPEGS_INIT_CHANGE_BYPASS_MODE =
      0x01000000, /*!< indicate change of bypass mode */

  /* Re-initialization needed, currently not used */
  MPEGS_INIT_ERROR_ANC_TYPE = 0x10000000, /*!< indicate ancType error*/
  MPEGS_INIT_ERROR_ANC_STARTSTOP =
      0x20000000 /*!< indicate ancStartStop error */
} MPEGS_INIT_FLAGS;

struct MpegSurroundDecoder {
  HANDLE_FDK_QMF_DOMAIN pQmfDomain;
  UCHAR mpsData[MPS_DATA_BUFFER_SIZE]; /* Buffer for MPS payload accross more
                                          than one segment */
  INT mpsDataBits;                     /* Amount of bits in mpsData */
  /* MPEG Surround decoder */
  SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig[1]; /* SSC delay line which is
                                                       used during decoding */
  spatialDec *pSpatialDec;
  SPATIAL_SPECIFIC_CONFIG
  spatialSpecificConfigBackup; /* SSC used while parsing */

  /* Creation parameter */
  UCHAR mpegSurroundDecoderLevel;
  /* Run-time parameter */
  UCHAR mpegSurroundSscIsGlobalCfg; /* Flag telling that the SSC
                                       (::spatialSpecificConfig) is a
                                       out-of-band configuration. */
  UCHAR mpegSurroundUseTimeInterface;

  SPATIAL_BS_FRAME
  bsFrames[1];         /* Bitstream Structs that contain data read from the
                          SpatialFrame() bitstream element */
  BS_LL_STATE llState; /* Bit stream parser state memory */
  UCHAR bsFrameParse;  /* Current parse frame context index */
  UCHAR bsFrameDecode; /* Current decode/apply frame context index */
  UCHAR bsFrameDelay;  /* Amount of frames delay between parsing and processing.
                          Required i.e. for interpolation error concealment. */

  /* User prameters */
  SPATIALDEC_PARAM mpegSurroundUserParams;

  /* Internal flags */
  SPATIAL_DEC_UPMIX_TYPE upmixType;
  int initFlags[1];
  MPEGS_ANCSTARTSTOP ancStartStopPrev;
  MPEGS_SYNCSTATE fOnSync[1];

  /* Inital decoder configuration */
  SPATIAL_DEC_CONFIG decConfig;
};

SACDEC_ERROR
static sscCheckOutOfBand(const SPATIAL_SPECIFIC_CONFIG *pSsc,
                         const INT coreCodec, const INT sampleRate,
                         const INT frameSize);

static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc);

/**
 * \brief Get the number of QMF bands from the sampling frequency (in Hz)
 **/
static int mpegSurroundDecoder_GetNrOfQmfBands(
    const SPATIAL_SPECIFIC_CONFIG *pSsc, UINT sampleRate) {
  UINT samplingFrequency = sampleRate;
  int qmfBands = 64;

  if (pSsc != NULL) {
    switch (pSsc->coreCodec) {
      case AOT_USAC:
        if ((pSsc->stereoConfigIndex == 3)) {
          static const UCHAR mapIdx2QmfBands[3] = {24, 32, 16};
          FDK_ASSERT((pSsc->coreSbrFrameLengthIndex >= 2) &&
                     (pSsc->coreSbrFrameLengthIndex <= 4));
          qmfBands = mapIdx2QmfBands[pSsc->coreSbrFrameLengthIndex - 2];
        }
        return qmfBands;
      default:
        samplingFrequency = pSsc->samplingFreq;
        break;
    }
  }

  /* number of QMF bands depend on sampling frequency, see FDIS 23003-1:2006
   * Chapter 6.3.3 */
  if (samplingFrequency < 27713) {
    qmfBands = 32;
  }
  if (samplingFrequency > 55426) {
    qmfBands = 128;
  }

  return qmfBands;
}

/**
 * \brief Analyse init flags
 **/
static int mpegSurroundDecoder_CalcInitFlags(SPATIAL_SPECIFIC_CONFIG *pSsc1,
                                             SPATIAL_SPECIFIC_CONFIG *pSsc2,
                                             int upmixTypeFlag,
                                             int binauralQualityFlag,
                                             int partiallyComplexFlag,
                                             int *ctrlFlags) {
  /* Analyse core coder */
  if (pSsc1->coreCodec != pSsc2->coreCodec) {
    *ctrlFlags |= MASK_MPEGS_INIT_ALL_STATES;
    *ctrlFlags |= MASK_MPEGS_INIT_ALL_PARAMS;
  } else {
    /* Analyse elements for initialization of space analysis qmf filterbank */
    if ((partiallyComplexFlag) || (pSsc1->treeConfig != pSsc2->treeConfig) ||
        (pSsc1->samplingFreq != pSsc2->samplingFreq)) {
      *ctrlFlags |= MPEGS_INIT_STATES_ANA_QMF_FILTER;
      *ctrlFlags |= MPEGS_INIT_STATES_ANA_HYB_FILTER;
    }

    /* Analyse elements for initialization of space synthesis qmf filterbank */
    if ((upmixTypeFlag) || (partiallyComplexFlag) ||
        (pSsc1->treeConfig != pSsc2->treeConfig) ||
        (pSsc1->samplingFreq != pSsc2->samplingFreq) ||
        (pSsc1->bsFixedGainDMX != pSsc2->bsFixedGainDMX)) {
      *ctrlFlags |= MPEGS_INIT_STATES_SYN_QMF_FILTER;
    }

    /* Analyse elements for initialization of decorrelator */
    if ((upmixTypeFlag) || (partiallyComplexFlag) ||
        (pSsc1->treeConfig != pSsc2->treeConfig) ||
        (pSsc1->samplingFreq != pSsc2->samplingFreq) ||
        (pSsc1->decorrConfig != pSsc2->decorrConfig)) {
      *ctrlFlags |= MPEGS_INIT_STATES_DECORRELATOR;
    }

    /* Analyse elements for initialization of m1 and m2 calculation */
    if ((upmixTypeFlag) || (binauralQualityFlag) ||
        (pSsc1->treeConfig != pSsc2->treeConfig) ||
        (pSsc1->samplingFreq != pSsc2->samplingFreq))

    {
      *ctrlFlags |= MPEGS_INIT_STATES_M1M2;
    }

    /* Analyse elements for initialization of GES */
    if ((upmixTypeFlag) || (pSsc1->treeConfig != pSsc2->treeConfig) ||
        (pSsc1->tempShapeConfig != pSsc2->tempShapeConfig)) {
      *ctrlFlags |= MPEGS_INIT_STATES_GES;
    }

    /* Analyse elements for initialization of FDreverb */
    if ((upmixTypeFlag) || (binauralQualityFlag) || (partiallyComplexFlag) ||
        (pSsc1->samplingFreq != pSsc2->samplingFreq) ||
        (pSsc1->nTimeSlots != pSsc2->nTimeSlots)) {
      *ctrlFlags |= MPEGS_INIT_STATES_REVERB;
    }

    /* Reset previous frame data whenever the config changes */
    if (*ctrlFlags & MPEGS_INIT_CONFIG) {
      *ctrlFlags |= MPEGS_INIT_STATES_PARAM;
    }
  }

  return MPS_OK;
}

/**
 * \brief Reset MPEG Surround status info
 **/
static void updateMpegSurroundDecoderStatus(
    CMpegSurroundDecoder *pMpegSurroundDecoder, int initFlags,
    MPEGS_SYNCSTATE fOnSync, MPEGS_ANCSTARTSTOP ancStartStopPrev) {
  pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
      initFlags;
  if ((pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg != 0) &&
      (pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] >=
       MPEGS_SYNC_FOUND) &&
      (fOnSync < MPEGS_SYNC_FOUND)) {
    pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
        MPEGS_SYNC_FOUND;
  } else {
    pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
        fOnSync;
  }
  pMpegSurroundDecoder->ancStartStopPrev = ancStartStopPrev;
}

static SACDEC_ERROR mpegSurroundDecoder_Create(
    CMpegSurroundDecoder **pMpegSurroundDecoder, int stereoConfigIndex,
    HANDLE_FDK_QMF_DOMAIN pQmfDomain);

SAC_INSTANCE_AVAIL
mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
    CMpegSurroundDecoder *pMpegSurroundDecoder) {
  SAC_INSTANCE_AVAIL instanceAvailable = SAC_INSTANCE_NOT_FULL_AVAILABLE;

  if (pMpegSurroundDecoder->pSpatialDec != NULL) {
    instanceAvailable = SAC_INSTANCE_FULL_AVAILABLE;
  }

  return instanceAvailable;
}

SACDEC_ERROR mpegSurroundDecoder_Open(
    CMpegSurroundDecoder **pMpegSurroundDecoder, int stereoConfigIndex,
    HANDLE_FDK_QMF_DOMAIN pQmfDomain) {
  SACDEC_ERROR error;

  error = mpegSurroundDecoder_Create(pMpegSurroundDecoder, stereoConfigIndex,
                                     pQmfDomain);

  return error;
}

/**
 * \brief  Renamed function from getUpmixType to check_UParam_Build_DecConfig.
 *         This function checks if user params, decoder config and SSC are valid
 *         and if the decoder build can handle all this settings.
 *         The upmix type may be modified by this function.
 *         It is called in initMpegSurroundDecoder() after the ssc parse check,
 *         to have all checks in one place and to ensure these checks are always
 *         performed if config changes (inband and out-of-band).
 *
 * \param pUserParams  User data handle.
 * \param pDecConfig   decoder config handle.
 * \param pSsc         spatial specific config handle.
 * \param pUpmixType   upmix type which is set by this function
 *
 * \return  MPS_OK on sucess, and else on failure.
 */
static SACDEC_ERROR check_UParam_Build_DecConfig(
    SPATIALDEC_PARAM const *pUserParams, SPATIAL_DEC_CONFIG const *pDecConfig,
    const SPATIAL_SPECIFIC_CONFIG *pSsc, SPATIAL_DEC_UPMIX_TYPE *pUpmixType) {
  int dmxChannels, outChannels, maxNumOutChannels;

  FDK_ASSERT(pUserParams != NULL);
  FDK_ASSERT(pUpmixType != NULL);

  /* checks if implementation can handle the Ssc */

  switch (pSsc->treeConfig) {
    case SPATIALDEC_MODE_RSVD7: /* 212 */
      dmxChannels = 1;
      outChannels = 2;
      break;
    default:
      return MPS_UNSUPPORTED_CONFIG;
  }

  /* ------------------------------------------- */

  /* Analyse pDecConfig params */
  switch (pDecConfig->binauralMode) {
    case BINAURAL_NONE:
      break;
    default:
      return MPS_UNSUPPORTED_CONFIG;
  }

  switch (pDecConfig->decoderMode) {
    case EXT_HQ_ONLY:
      break;
    default:
      return MPS_UNSUPPORTED_CONFIG;
  }

  switch (pDecConfig->maxNumOutputChannels) {
    case OUTPUT_CHANNELS_DEFAULT:
      /* No special restrictions -> Get the level restriction: */
      switch (pDecConfig->decoderLevel) {
        case DECODER_LEVEL_0:
          maxNumOutChannels = 2;
          break;
        default:
          return MPS_UNSUPPORTED_CONFIG;
      }
      break;
    case OUTPUT_CHANNELS_2_0:
      maxNumOutChannels = 2;
      break;
    default:
      return MPS_UNSUPPORTED_CONFIG;
  }
  /* ------------------------- */

  /* check if we can handle user params */
  if (pUserParams->blindEnable == 1) {
    return MPS_UNSUPPORTED_CONFIG;
  }
  {
    switch ((SAC_DEC_OUTPUT_MODE)pUserParams->outputMode) {
      case SACDEC_OUT_MODE_NORMAL:
        if (maxNumOutChannels >= outChannels) {
          *pUpmixType = UPMIX_TYPE_NORMAL;
        } else {
          { *pUpmixType = UPMIX_TYPE_BYPASS; }
        }
        break;
      case SACDEC_OUT_MODE_STEREO:
        if (dmxChannels == 1) {
          if (outChannels == 2) {
            *pUpmixType = UPMIX_TYPE_NORMAL;
          }
        } else {
          *pUpmixType = UPMIX_TYPE_BYPASS;
        }
        break;
      case SACDEC_OUT_MODE_6CHANNEL:
        if (outChannels > 6) {
          { *pUpmixType = UPMIX_TYPE_BYPASS; }
        } else {
          *pUpmixType = UPMIX_TYPE_NORMAL;
        }
        break;
      default:
        return MPS_UNSUPPORTED_CONFIG;
    }
  }

  return MPS_OK;
}

/**
 * \brief Init MPEG Surround decoder.
 **/
static SACDEC_ERROR initMpegSurroundDecoder(
    CMpegSurroundDecoder *pMpegSurroundDecoder) {
  SACDEC_ERROR err;
  int initFlags = MPEGS_INIT_NONE, initFlagsDec;
  int upmixTypeCurr = pMpegSurroundDecoder->upmixType;

  FDK_ASSERT(pMpegSurroundDecoder != NULL);

  SPATIAL_SPECIFIC_CONFIG *const pSSCinput =
      &pMpegSurroundDecoder->spatialSpecificConfigBackup;
  SPATIAL_SPECIFIC_CONFIG *const pSSCtarget =
      &pMpegSurroundDecoder
           ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
  initFlagsDec =
      pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode];

  if (pSSCinput->coreCodec != AOT_USAC) {
    /* here we check if we have a valid Ssc */
    err = sscParseCheck(pSSCinput);
    if (err != MPS_OK) goto bail;
  }

  /* here we check if Ssc matches build; also check UParams and DecConfig */
  /* if desired upmixType is changes                                      */
  err = check_UParam_Build_DecConfig(
      &pMpegSurroundDecoder->mpegSurroundUserParams,
      &pMpegSurroundDecoder->decConfig, pSSCinput,
      &pMpegSurroundDecoder->upmixType);
  if (err != MPS_OK) goto bail;

  /* init config */
  if (initFlagsDec & MPEGS_INIT_CHANGE_HEADER) {
    initFlags |= MPEGS_INIT_CONFIG;
  }
  /* init all states */
  if (initFlagsDec & MPEGS_INIT_CLEAR_HISTORY) {
    initFlags |= MASK_MPEGS_INIT_ALL_STATES;
  }
  if (initFlagsDec & MPEGS_INIT_CHANGE_CONCEAL_PARAMS) {
    initFlags |= MPEGS_INIT_PARAMS_ERROR_CONCEALMENT;
  }

  if (initFlagsDec & MPEGS_INIT_ENFORCE_REINIT) {
    /* init all states */
    initFlags |= MASK_MPEGS_INIT_ALL_STATES;
    initFlags |= MASK_MPEGS_INIT_ALL_PARAMS;
  } else {
    /* analyse states which have to be initialized */
    mpegSurroundDecoder_CalcInitFlags(
        pSSCtarget, pSSCinput,
        (upmixTypeCurr !=
         pMpegSurroundDecoder->upmixType), /* upmixType changed */
        0, (initFlagsDec & MPEGS_INIT_CHANGE_PARTIALLY_COMPLEX) ? 1 : 0,
        &initFlags);
  }

  {
    int nrOfQmfBands;
    FDKmemcpy(pSSCtarget, pSSCinput, sizeof(SPATIAL_SPECIFIC_CONFIG));

    nrOfQmfBands = mpegSurroundDecoder_GetNrOfQmfBands(
        pSSCtarget, pSSCtarget->samplingFreq);
    err = FDK_SpatialDecInit(
        pMpegSurroundDecoder->pSpatialDec,
        &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
        pSSCtarget, nrOfQmfBands, pMpegSurroundDecoder->upmixType,
        &pMpegSurroundDecoder->mpegSurroundUserParams, initFlags);

    if (err != MPS_OK) goto bail;

    /* Signal that we got a header and can go on decoding */
    if (err == MPS_OK) {
      initFlagsDec = MPEGS_INIT_OK;
      {
        pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
            MPEGS_SYNC_FOUND;
      }
    }
  }

bail:
  pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] =
      initFlagsDec;
  return err;
}

/**
 * \brief Init MPEG Surround decoder.
 **/
SACDEC_ERROR mpegSurroundDecoder_Init(
    CMpegSurroundDecoder *pMpegSurroundDecoder) {
  SACDEC_ERROR err = MPS_OK;

  if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode]) {
    err = initMpegSurroundDecoder(pMpegSurroundDecoder);
  }
  return err;
}

/**
 * \brief Open MPEG Surround decoder.
 **/
static SACDEC_ERROR mpegSurroundDecoder_Create(
    CMpegSurroundDecoder **pMpegSurroundDecoder, int stereoConfigIndex,
    HANDLE_FDK_QMF_DOMAIN pQmfDomain) {
  SACDEC_ERROR err = MPS_OK;
  CMpegSurroundDecoder *sacDec = NULL;
  spatialDec *self = NULL;

  /* decoderLevel  decoderMode  maxNumOutputChannels  binauralMode */
  static const SPATIAL_DEC_CONFIG decConfig = {
      (CFG_LEVEL)(0), EXT_HQ_ONLY, OUTPUT_CHANNELS_DEFAULT, BINAURAL_NONE};

  if (*pMpegSurroundDecoder == NULL) {
    FDK_ALLOCATE_MEMORY_1D(*pMpegSurroundDecoder, 1, CMpegSurroundDecoder)

    for (int i = 0; i < 1; i++) {
      err = SpatialDecCreateBsFrame(&(*pMpegSurroundDecoder)->bsFrames[i],
                                    &(*pMpegSurroundDecoder)->llState);
      if (err != MPS_OK) {
        sacDec = *pMpegSurroundDecoder;
        goto bail;
      }
    }
    (*pMpegSurroundDecoder)->pQmfDomain = pQmfDomain;

    (*pMpegSurroundDecoder)->bsFrameDelay = 1;
    (*pMpegSurroundDecoder)->bsFrameParse = 0;
    (*pMpegSurroundDecoder)->bsFrameDecode = 0;

    return err;
  } else {
    sacDec = *pMpegSurroundDecoder;
  }

  if (sacDec->pSpatialDec == NULL) {
    if ((self = FDK_SpatialDecOpen(&decConfig, stereoConfigIndex)) == NULL) {
      err = MPS_OUTOFMEMORY;
      goto bail;
    }
  } else {
    self = sacDec->pSpatialDec;
  }

  self->pQmfDomain = sacDec->pQmfDomain;

  sacDec->pSpatialDec = self;

  /* default parameter set */
  sacDec->mpegSurroundUserParams.outputMode = SACDEC_OUT_MODE_NORMAL;
  sacDec->mpegSurroundUserParams.blindEnable = 0;
  sacDec->mpegSurroundUserParams.bypassMode = 0;
  sacDec->mpegSurroundUserParams.concealMethod = 1;
  sacDec->mpegSurroundUserParams.concealNumKeepFrames = 10;
  sacDec->mpegSurroundUserParams.concealFadeOutSlopeLength = 5;
  sacDec->mpegSurroundUserParams.concealFadeInSlopeLength = 5;
  sacDec->mpegSurroundUserParams.concealNumReleaseFrames = 3;
  sacDec->mpegSurroundSscIsGlobalCfg = 0;
  sacDec->mpegSurroundUseTimeInterface = 1;
  sacDec->mpegSurroundDecoderLevel = decConfig.decoderLevel;

  sacDec->upmixType = UPMIX_TYPE_NORMAL;

  /* signalize spatial decoder re-initalization */
  updateMpegSurroundDecoderStatus(sacDec, MPEGS_INIT_ENFORCE_REINIT,
                                  MPEGS_SYNC_LOST, MPEGS_STOP);

  /* return decoder instance */
  *pMpegSurroundDecoder = sacDec;
  sacDec->decConfig = decConfig;

  SpatialDecInitParserContext(sacDec->pSpatialDec);

  return err;

bail:
  if (sacDec != NULL) {
    mpegSurroundDecoder_Close(sacDec);
  }
  *pMpegSurroundDecoder = NULL;
  if (err == MPS_OK) {
    return MPS_OUTOFMEMORY;
  } else {
    return err;
  }
}

/**
 * \brief Config MPEG Surround decoder.
 **/
SACDEC_ERROR mpegSurroundDecoder_Config(
    CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
    AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
    INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes,
    const UCHAR configMode, UCHAR *configChanged) {
  SACDEC_ERROR err = MPS_OK;
  SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig;
  SPATIAL_SPECIFIC_CONFIG *pSsc =
      &pMpegSurroundDecoder->spatialSpecificConfigBackup;

  switch (coreCodec) {
    case AOT_DRM_USAC:
    case AOT_USAC:
      if (configMode == AC_CM_DET_CFG_CHANGE) {
        /* In config detection mode write spatial specific config parameters
         * into temporarily allocated structure */
        err = SpatialDecParseMps212Config(
            hBs, &spatialSpecificConfig, samplingRate, coreCodec,
            stereoConfigIndex, coreSbrFrameLengthIndex);
        pSsc = &spatialSpecificConfig;
      } else {
        err = SpatialDecParseMps212Config(
            hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
            samplingRate, coreCodec, stereoConfigIndex,
            coreSbrFrameLengthIndex);
      }
      break;
    case AOT_ER_AAC_ELD:
    case AOT_ER_AAC_LD:
      if (configMode == AC_CM_DET_CFG_CHANGE) {
        /* In config detection mode write spatial specific config parameters
         * into temporarily allocated structure */
        err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig,
                                            configBytes, coreCodec);
        pSsc = &spatialSpecificConfig;
      } else {
        err = SpatialDecParseSpecificConfig(
            hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
            configBytes, coreCodec);
      }
      break;
    default:
      err = MPS_UNSUPPORTED_FORMAT;
      break;
  }

  if (err != MPS_OK) {
    goto bail;
  }

  err = sscCheckOutOfBand(pSsc, coreCodec, samplingRate, frameSize);

  if (err != MPS_OK) {
    goto bail;
  }

  if (configMode & AC_CM_DET_CFG_CHANGE) {
    return err;
  }

  if (configMode & AC_CM_ALLOC_MEM) {
    if (*configChanged) {
      err = mpegSurroundDecoder_Open(&pMpegSurroundDecoder, stereoConfigIndex,
                                     NULL);
      if (err) {
        return err;
      }
    }
  }

  {
    SPATIAL_SPECIFIC_CONFIG *sscParse =
        &pMpegSurroundDecoder
             ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameParse];

    if (FDK_SpatialDecCompareSpatialSpecificConfigHeader(
            &pMpegSurroundDecoder->spatialSpecificConfigBackup, sscParse)) {
      pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameParse] |=
          MPEGS_INIT_CHANGE_HEADER;
      /* Error resilience code */
      if (pMpegSurroundDecoder->pSpatialDec == NULL) {
        err = MPS_NOTOK;
        goto bail;
      }
      SpatialDecInitParserContext(pMpegSurroundDecoder->pSpatialDec);
      pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
          &pMpegSurroundDecoder
               ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
    }
  }

  if (err == MPS_OK) {
    /* We got a valid out-of-band configuration so label it accordingly. */
    pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg = 1;
  }

bail:
  return err;
}

/**
 * \brief Determine MPEG Surround operation mode.
 **/
static MPEGS_OPMODE mpegSurroundOperationMode(
    CMpegSurroundDecoder *pMpegSurroundDecoder, int mpsDataBits) {
  MPEGS_OPMODE mode;

  {
    if ((mpsDataBits > 0) &&
        (pMpegSurroundDecoder->mpegSurroundUserParams.blindEnable == 0)) {
      mode = MPEGS_OPMODE_MPS_PAYLOAD; /* Mode: Normal, Stereo or Binaural */
    } else {
      mode = MPEGS_OPMODE_NO_MPS_PAYLOAD; /* Mode: No MPEG Surround Payload */
      updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                      MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
                                      MPEGS_STOP);
    }
  }

  return (mode);
}

/**
 * \brief  Check ssc for parse errors.
 *         This one is called in initMpegSurroundDecoder()
 *         to ensure checking of inband and out-of-band mps configs.
 *         Only parse errors checked here! Check for valid config is done
 *         in check_UParam_Build_DecConfig()!
 *
 * \param pSsc         spatial specific config handle.
 *
 * \return  MPS_OK on sucess, and else on parse error.
 */
static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc) {
  if (pSsc->samplingFreq > 96000) return MPS_PARSE_ERROR;
  if (pSsc->samplingFreq < 8000) return MPS_PARSE_ERROR;

  if ((pSsc->treeConfig < 0) || (pSsc->treeConfig > 7)) {
    return MPS_PARSE_ERROR;
  }

  if ((pSsc->quantMode < 0) || (pSsc->quantMode > 2)) {
    return MPS_PARSE_ERROR;
  }

  /* now we are sure there were no parsing errors */

  return MPS_OK;
}

/**
 * \brief  Check number of time slots
 *
 * Basically the mps frame length must be a multiple of the core coder frame
 * length. The below table shows all valid configurations in detail. See ISO/IEC
 * 23003-1: "Table 4A - Allowed values for bsFrameLength in the Baseline MPEG
 * Surround Profile"
 *
 * Downmix Coder        Downmix Code      Allowed values for bsFrameLength
 * Allowed frame sizes for normal, downsampled and upsampled MPS Framelength
 *                      (QMF Samples)
 *
 * AAC 1024                  16           15, 31, 47, 63 1024  2048  3072  4096
 * downsampled MPS           32           31, 63 1024  2048 upsampled MPS
 * 8            7, 15, 23, 31, 39, 47, 55, 63, 71    1024  2048  3072  4096
 * 5120  6144  7168  8192  9216
 *
 * AAC 960                   15           14, 29, 44, 59 960  1920  2880  3840
 * downsampled MPS           30           29, 59 960  1920 upsampled MPS
 * 7,5           14, 29, 44, 59                        1920  3840  5760  7680
 *
 * HE-AAC 1024/2048          32           31, 63 2048  4096 downsampled MPS
 * 64           63                                    2048 upsampled MPS
 * 16           15, 31, 47, 63                        2048  4096  6144  8192
 *
 * HE-AAC 960/1920           30           29, 59 1920  3840 downsampled MPS
 * 60           59                                    1920 upsampled MPS
 * 15           14, 29, 44, 59                        1920  3840  5760  7680
 *
 * BSAC                      16           15, 31, 47, 63 1024  2048  3072  4096
 * downsampled MPS           32           31, 63 1024  2048 upsampled MPS
 * 8            7, 15, 23, 31, 39, 47, 55, 63, 71    1024  2048  3072  4096
 * 5120  6144  7168  8192  9216
 *
 * BSAC with SBR             32           31, 63 2048  4096 downsampled MPS
 * 64           63                                    2048 upsampled MPS
 * 16           15, 31, 47, 63                        2048  4096  6144  8192
 *
 * AAC LD 512                 8            7, 15, 23, 31, 39, 47, 55, 63, 71
 * 512  1024  1536  2048  2560  3072  3584  4096  4608 downsampled MPS
 * 16           15, 31, 47, 63                         512  1024  1536  2048
 *
 * AAC ELD 512                8            7, 15, 23, 31, 39, 47, 55, 63, 71
 * 512  1024  1536  2048  2560  3072  3584  4096  4608 downsampled MPS
 * 16           15, 31, 47, 63                         512  1024  1536  2048
 *
 * AAC ELD with SBR 512/1024 16           15, 31, 47, 63 1024  2048  3072  4096
 * downsampled MPS           32           31, 63 1024  2048 upsampled MPS
 * 8            7, 15, 23, 31, 39, 47, 55, 63, 71    1024  2048  3072  4096
 * 5120  6144  7168  8192  9216
 *
 * MPEG1/2 Layer II          18           17, 35, 53, 71 1152  2304  3456  4608
 * downsampled MPS           36           35, 71 1152  2304
 *
 * MPEG1/2 Layer III         18           17, 35, 53, 71 1152  2304  3456  4608
 * downsampled MPS           36           35, 71 1152  2304
 *
 * \param frameLength
 * \param qmfBands
 * \param timeSlots
 *
 * \return  error code
 */
SACDEC_ERROR checkTimeSlots(int frameLength, int qmfBands, int timeSlots) {
  int len;
  int maxFrameLength;

  if (qmfBands == 64) {
    /* normal MPEG Surround */
    switch (frameLength) {
      case 960:
      case 1920:
        maxFrameLength = 3840;
        break;
      case 1024:
      case 2048:
        maxFrameLength = 4096;
        break;
      case 512:
      case 1152:
        maxFrameLength = 4608;
        break;
      default:
        return MPS_PARSE_ERROR;
    }
  } else if (qmfBands == 32) {
    /* downsampled MPEG Surround */
    switch (frameLength) {
      case 960:
      case 1920:
        maxFrameLength = 1920;
        break;
      case 512:
      case 1024:
      case 2048:
        maxFrameLength = 2048;
        break;
      case 1152:
        maxFrameLength = 2304;
        break;
      default:
        return MPS_PARSE_ERROR;
    }
  } else if (qmfBands == 128) {
    /* upsampled MPEG Surround */
    switch (frameLength) {
      case 1920:
        maxFrameLength = 7680;
        break;
      case 1024:
        maxFrameLength = 9216;
        break;
      case 2048:
        maxFrameLength = 8192;
        break;
      case 512:
      case 960:
      case 1152:
      /* no break, no support for upsampled MPEG Surround */
      default:
        return MPS_PARSE_ERROR;
    }
  } else {
    return MPS_PARSE_ERROR;
  }

  len = frameLength;

  while (len <= maxFrameLength) {
    if (len == timeSlots * qmfBands) {
      return MPS_OK;
    }
    len += frameLength;
  }
  return MPS_PARSE_ERROR;
}

/**
 * \brief  Check ssc for consistency (e.g. bit errors could cause trouble)
 *         First of currently two ssc-checks.
 *         This (old) one is called in mpegSurroundDecoder_Apply()
 *         only if inband mps config is contained in stream.
 *
 *         New ssc check is split in two functions sscParseCheck() and
 * check_UParam_Build_DecConfig(). sscParseCheck() checks only for correct
 * parsing. check_UParam_Build_DecConfig() is used to check if we have a
 * valid config. Both are called in initMpegSurroundDecoder() to ensure
 * checking of inband and out-of-band mps configs.
 *
 *         If this function can be integrated into the new functions.
 *         We can remove this one.
 *
 * \param pSsc         spatial specific config handle.
 * \param frameLength
 * \param sampleRate
 *
 * \return  MPS_OK on sucess, and else on failure.
 */
static SACDEC_ERROR sscCheckInBand(SPATIAL_SPECIFIC_CONFIG *pSsc,
                                   int frameLength, int sampleRate) {
  SACDEC_ERROR err = MPS_OK;
  int qmfBands;

  FDK_ASSERT(pSsc != NULL);

  /* check ssc for parse errors */
  if (sscParseCheck(pSsc) != MPS_OK) {
    err = MPS_PARSE_ERROR;
  }

  /* core fs and mps fs must match */
  if (pSsc->samplingFreq != sampleRate) {
    err = MPS_PARSE_ERROR /* MPEGSDEC_SSC_PARSE_ERROR */;
  }

  qmfBands = mpegSurroundDecoder_GetNrOfQmfBands(pSsc, pSsc->samplingFreq);

  if (checkTimeSlots(frameLength, qmfBands, pSsc->nTimeSlots) != MPS_OK) {
    err = MPS_PARSE_ERROR;
  }

  return err;
}

SACDEC_ERROR
mpegSurroundDecoder_ConfigureQmfDomain(
    CMpegSurroundDecoder *pMpegSurroundDecoder,
    SAC_INPUT_CONFIG sac_dec_interface, UINT coreSamplingRate,
    AUDIO_OBJECT_TYPE coreCodec) {
  SACDEC_ERROR err = MPS_OK;
  FDK_QMF_DOMAIN_GC *pGC = NULL;

  if (pMpegSurroundDecoder == NULL) {
    return MPS_INVALID_HANDLE;
  }

  FDK_ASSERT(pMpegSurroundDecoder->pSpatialDec);

  pGC = &pMpegSurroundDecoder->pQmfDomain->globalConf;
  if (pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg) {
    SPATIAL_SPECIFIC_CONFIG *pSSC =
        &pMpegSurroundDecoder->spatialSpecificConfigBackup;
    if (sac_dec_interface == SAC_INTERFACE_TIME) {
      /* For SAC_INTERFACE_QMF these parameters are set by SBR. */
      pGC->nBandsAnalysis_requested = mpegSurroundDecoder_GetNrOfQmfBands(
          pSSC, coreSamplingRate); /* coreSamplingRate == outputSamplingRate for
                                      SAC_INTERFACE_TIME */
      pGC->nBandsSynthesis_requested = pGC->nBandsAnalysis_requested;
      pGC->nInputChannels_requested =
          fMax((UINT)pSSC->nInputChannels, (UINT)pGC->nInputChannels_requested);
    }
    pGC->nOutputChannels_requested =
        fMax((UINT)pSSC->nOutputChannels, (UINT)pGC->nOutputChannels_requested);
  } else {
    if (sac_dec_interface == SAC_INTERFACE_TIME) {
      /* For SAC_INTERFACE_QMF these parameters are set by SBR. */
      pGC->nBandsAnalysis_requested = mpegSurroundDecoder_GetNrOfQmfBands(
          NULL, coreSamplingRate); /* coreSamplingRate == outputSamplingRate for
                                      SAC_INTERFACE_TIME */
      pGC->nBandsSynthesis_requested = pGC->nBandsAnalysis_requested;
      pGC->nInputChannels_requested =
          pMpegSurroundDecoder->pSpatialDec->createParams.maxNumInputChannels;
    }
    pGC->nOutputChannels_requested =
        pMpegSurroundDecoder->pSpatialDec->createParams.maxNumOutputChannels;
  }
  pGC->nQmfProcBands_requested = 64;
  pGC->nQmfProcChannels_requested =
      fMin((INT)pGC->nInputChannels_requested,
           pMpegSurroundDecoder->pSpatialDec->createParams.maxNumInputChannels);

  if (coreCodec == AOT_ER_AAC_ELD) {
    pGC->flags_requested |= QMF_FLAG_MPSLDFB;
    pGC->flags_requested &= ~QMF_FLAG_CLDFB;
  }

  return err;
}

/**
 * \brief  Check out-of-band config
 *
 * \param pSsc         spatial specific config handle.
 * \param coreCodec    core codec.
 * \param sampleRate   sampling frequency.
 *
 * \return  errorStatus
 */
SACDEC_ERROR
sscCheckOutOfBand(const SPATIAL_SPECIFIC_CONFIG *pSsc, const INT coreCodec,
                  const INT sampleRate, const INT frameSize) {
  FDK_ASSERT(pSsc != NULL);
  int qmfBands = 0;

  /* check ssc for parse errors */
  if (sscParseCheck(pSsc) != MPS_OK) {
    return MPS_PARSE_ERROR;
  }

  switch (coreCodec) {
    case AOT_USAC:
    case AOT_DRM_USAC:
      /* ISO/IEC 23003-1:2007(E), Chapter 6.3.3, Support for lower and higher
       * sampling frequencies */
      if (pSsc->samplingFreq >= 55426) {
        return MPS_PARSE_ERROR;
      }
      break;
    case AOT_ER_AAC_LD:
    case AOT_ER_AAC_ELD:
      /* core fs and mps fs must match */
      if (pSsc->samplingFreq != sampleRate) {
        return MPS_PARSE_ERROR;
      }

      /* ISO/IEC 14496-3:2009 FDAM 3: Chapter 1.5.2.3, Levels for the Low Delay
       * AAC v2 profile */
      if (pSsc->samplingFreq > 48000) {
        return MPS_PARSE_ERROR;
      }

      qmfBands = mpegSurroundDecoder_GetNrOfQmfBands(pSsc, pSsc->samplingFreq);
      switch (frameSize) {
        case 480:
          if (!((qmfBands == 32) && (pSsc->nTimeSlots == 15))) {
            return MPS_PARSE_ERROR;
          }
          break;
        case 960:
          if (!((qmfBands == 64) && (pSsc->nTimeSlots == 15))) {
            return MPS_PARSE_ERROR;
          }
          break;
        case 512:
          if (!(((qmfBands == 32) && (pSsc->nTimeSlots == 16)) ||
                ((qmfBands == 64) && (pSsc->nTimeSlots == 8)))) {
            return MPS_PARSE_ERROR;
          }
          break;
        case 1024:
          if (!((qmfBands == 64) && (pSsc->nTimeSlots == 16))) {
            return MPS_PARSE_ERROR;
          }
          break;
        default:
          return MPS_PARSE_ERROR;
      }
      break;
    default:
      return MPS_PARSE_ERROR;
      break;
  }

  return MPS_OK;
}

/**
 * \brief Decode MPEG Surround frame.
 **/
int mpegSurroundDecoder_ParseNoHeader(
    CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
    int *pMpsDataBits, int fGlobalIndependencyFlag) {
  SACDEC_ERROR err = MPS_OK;
  SPATIAL_SPECIFIC_CONFIG *sscParse;
  int bitsAvail, numSacBits;

  if (pMpegSurroundDecoder == NULL || hBs == NULL) {
    return MPS_INVALID_HANDLE;
  }

  sscParse = &pMpegSurroundDecoder
                  ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameParse];

  bitsAvail = FDKgetValidBits(hBs);

  /* First spatial specific config is parsed into spatialSpecificConfigBackup,
   * second spatialSpecificConfigBackup is copied into
   * spatialSpecificConfig[bsFrameDecode] */
  if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameParse]) {
    FDKmemcpy(sscParse, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
              sizeof(SPATIAL_SPECIFIC_CONFIG));
    pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameParse] =
        MPEGS_SYNC_FOUND;
  }

  if (bitsAvail <= 0) {
    err = MPS_PARSE_ERROR;
  } else {
    err = SpatialDecParseFrameData(
        pMpegSurroundDecoder->pSpatialDec,
        &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse],
        hBs, sscParse, (UPMIXTYPE)pMpegSurroundDecoder->upmixType,
        fGlobalIndependencyFlag);
    if (err == MPS_OK) {
      pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse]
          .newBsData = 1;
    }
  }

  numSacBits = bitsAvail - (INT)FDKgetValidBits(hBs);

  if (numSacBits > bitsAvail) {
    pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse]
        .newBsData = 0;
    err = MPS_PARSE_ERROR;
  }

  *pMpsDataBits -= numSacBits;

  return err;
}

/**
 * \brief Check, if ancType is valid.
 **/
static int isValidAncType(CMpegSurroundDecoder *pMpegSurroundDecoder,
                          int ancType) {
  int ret = 1;

  if ((ancType != MPEGS_ANCTYPE_HEADER_AND_FRAME) &&
      (ancType != MPEGS_ANCTYPE_FRAME)) {
    ret = 0;
  }

  if (ret == 0) {
    updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                    MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
                                    MPEGS_STOP);
  }

  return (ret);
}

/**
 * \brief Check, if ancStartStop is valid.
 **/
static int isValidAncStartStop(CMpegSurroundDecoder *pMpegSurroundDecoder,
                               int ancStartStop) {
  int ret = 1;

  switch (ancStartStop) {
    case MPEGS_START:
      /* Sequence start - start and continue - start not allowed */
      if ((pMpegSurroundDecoder->ancStartStopPrev == MPEGS_START) ||
          (pMpegSurroundDecoder->ancStartStopPrev == MPEGS_CONTINUE)) {
        ret = 0;
      }
      break;

    case MPEGS_STOP:
      /* MPS payload of the previous frame must be valid if current type is stop
         Sequence startstop - stop and stop - stop not allowed
         Sequence startstop - continue and stop - continue are allowed */
      if ((pMpegSurroundDecoder->ancStartStopPrev == MPEGS_STOP) ||
          (pMpegSurroundDecoder->ancStartStopPrev == MPEGS_START_STOP)) {
        ret = 0;
      }
      break;

    case MPEGS_CONTINUE:
    case MPEGS_START_STOP:
      /* No error detection possible for this states */
      break;
  }

  if (ret == 0) {
    updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                    MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
                                    MPEGS_STOP);
  } else {
    pMpegSurroundDecoder->ancStartStopPrev = (MPEGS_ANCSTARTSTOP)ancStartStop;
  }

  return (ret);
}

int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder,
                              HANDLE_FDK_BITSTREAM hBs, int *pMpsDataBits,
                              AUDIO_OBJECT_TYPE coreCodec, int sampleRate,
                              int frameSize, int fGlobalIndependencyFlag) {
  SACDEC_ERROR err = MPS_OK;
  SPATIAL_SPECIFIC_CONFIG *sscParse;
  SPATIAL_BS_FRAME *bsFrame;
  HANDLE_FDK_BITSTREAM hMpsBsData = NULL;
  FDK_BITSTREAM mpsBsData;
  int mpsDataBits = *pMpsDataBits;
  int mpsBsBits;
  MPEGS_ANCTYPE ancType;
  MPEGS_ANCSTARTSTOP ancStartStop;

  if (pMpegSurroundDecoder == NULL) {
    return MPS_INVALID_HANDLE;
  }

  FDK_ASSERT(pMpegSurroundDecoder->pSpatialDec);

  mpsBsBits = (INT)FDKgetValidBits(hBs);

  sscParse = &pMpegSurroundDecoder
                  ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameParse];
  bsFrame = &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse];

  /*
     Find operation mode of mpeg surround decoder:
     - MPEGS_OPMODE_EMM:            Mode: Enhanced Matrix Mode (Blind)
     - MPEGS_OPMODE_MPS_PAYLOAD:    Mode: Normal, Stereo or Binaural
     - MPEGS_OPMODE_NO_MPS_PAYLOAD: Mode: No MpegSurround Payload
  */
  {
    /* Parse ancType and ancStartStop */
    ancType = (MPEGS_ANCTYPE)FDKreadBits(hBs, 2);
    ancStartStop = (MPEGS_ANCSTARTSTOP)FDKreadBits(hBs, 2);
    mpsDataBits -= 4;

    /* Set valid anc type flag, if ancType signals a payload with either header
     * and frame or frame */
    if (isValidAncType(pMpegSurroundDecoder, ancType)) {
      /* Set valid anc startstop flag, if transmitted sequence is not illegal */
      if (isValidAncStartStop(pMpegSurroundDecoder, ancStartStop)) {
        switch (ancStartStop) {
          case MPEGS_START:
            /* Assuming that core coder frame size (AAC) is smaller than MPS
               coder frame size. Save audio data for next frame. */
            if (mpsDataBits > MPS_DATA_BUFFER_SIZE * 8) {
              err = MPS_NOTOK;
              goto bail;
            }
            for (int i = 0; i < mpsDataBits / 8; i++) {
              pMpegSurroundDecoder->mpsData[i] = FDKreadBits(hBs, 8);
            }
            pMpegSurroundDecoder->mpsDataBits = mpsDataBits;
            break;

          case MPEGS_CONTINUE:
          case MPEGS_STOP:
            /* Assuming that core coder frame size (AAC) is smaller than MPS
               coder frame size. Save audio data for next frame. */
            if ((pMpegSurroundDecoder->mpsDataBits + mpsDataBits) >
                MPS_DATA_BUFFER_SIZE * 8) {
              err = MPS_NOTOK;
              goto bail;
            }
            for (int i = 0; i < mpsDataBits / 8; i++) {
              pMpegSurroundDecoder
                  ->mpsData[(pMpegSurroundDecoder->mpsDataBits / 8) + i] =
                  FDKreadBits(hBs, 8);
            }
            pMpegSurroundDecoder->mpsDataBits += mpsDataBits;
            FDKinitBitStream(&mpsBsData, pMpegSurroundDecoder->mpsData,
                             MAX_BUFSIZE_BYTES,
                             pMpegSurroundDecoder->mpsDataBits, BS_READER);
            hMpsBsData = &mpsBsData;
            break;

          case MPEGS_START_STOP:
            pMpegSurroundDecoder->mpsDataBits = mpsDataBits;
            hMpsBsData = hBs;
            break;

          default:
            FDK_ASSERT(0);
        }

        if ((ancStartStop == MPEGS_STOP) ||
            (ancStartStop == MPEGS_START_STOP)) {
          switch (ancType) {
            case MPEGS_ANCTYPE_HEADER_AND_FRAME: {
              int parseResult, bitsRead;
              SPATIAL_SPECIFIC_CONFIG spatialSpecificConfigTmp =
                  pMpegSurroundDecoder->spatialSpecificConfigBackup;

              /* Parse spatial specific config */
              bitsRead = (INT)FDKgetValidBits(hMpsBsData);

              err = SpatialDecParseSpecificConfigHeader(
                  hMpsBsData,
                  &pMpegSurroundDecoder->spatialSpecificConfigBackup, coreCodec,
                  pMpegSurroundDecoder->upmixType);

              bitsRead = (bitsRead - (INT)FDKgetValidBits(hMpsBsData));
              parseResult = ((err == MPS_OK) ? bitsRead : -bitsRead);

              if (parseResult < 0) {
                parseResult = -parseResult;
                err = MPS_PARSE_ERROR;
              } else if (err == MPS_OK) {
                /* Check SSC for consistency (e.g. bit errors could cause
                 * trouble) */
                err = sscCheckInBand(
                    &pMpegSurroundDecoder->spatialSpecificConfigBackup,
                    frameSize, sampleRate);
              }
              if (err != MPS_OK) {
                pMpegSurroundDecoder->spatialSpecificConfigBackup =
                    spatialSpecificConfigTmp;
                break;
              }

              pMpegSurroundDecoder->mpsDataBits -= parseResult;

              /* Initiate re-initialization, if header has changed */
              if (FDK_SpatialDecCompareSpatialSpecificConfigHeader(
                      &pMpegSurroundDecoder->spatialSpecificConfigBackup,
                      sscParse) == MPS_UNEQUAL_SSC) {
                pMpegSurroundDecoder
                    ->initFlags[pMpegSurroundDecoder->bsFrameParse] |=
                    MPEGS_INIT_CHANGE_HEADER;
                SpatialDecInitParserContext(pMpegSurroundDecoder->pSpatialDec);
                /* We found a valid in-band configuration. Therefore any
                 * previous config is invalid now. */
                pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg = 0;
              }
            }
              FDK_FALLTHROUGH;
            case MPEGS_ANCTYPE_FRAME:

              if (pMpegSurroundDecoder
                      ->initFlags[pMpegSurroundDecoder->bsFrameParse] &
                  MPEGS_INIT_ERROR_PAYLOAD) {
                err = MPS_PARSE_ERROR;
                break;
              }

              /* First spatial specific config is parsed into
               * spatialSpecificConfigBackup, second spatialSpecificConfigBackup
               * is copied into spatialSpecificConfig[bsFrameDecode] */
              if (pMpegSurroundDecoder
                      ->initFlags[pMpegSurroundDecoder->bsFrameParse]) {
                FDKmemcpy(sscParse,
                          &pMpegSurroundDecoder->spatialSpecificConfigBackup,
                          sizeof(SPATIAL_SPECIFIC_CONFIG));
                pMpegSurroundDecoder
                    ->fOnSync[pMpegSurroundDecoder->bsFrameParse] =
                    MPEGS_SYNC_FOUND;
              }

              if (pMpegSurroundDecoder
                      ->fOnSync[pMpegSurroundDecoder->bsFrameParse] >=
                  MPEGS_SYNC_FOUND) {
                int nbits = 0, bitsAvail;

                if (err != MPS_OK) {
                  break;
                }

                bitsAvail = FDKgetValidBits(hMpsBsData);

                if (bitsAvail <= 0) {
                  err = MPS_PARSE_ERROR;
                } else {
                  err = SpatialDecParseFrameData(
                      pMpegSurroundDecoder->pSpatialDec, bsFrame, hMpsBsData,
                      sscParse, (UPMIXTYPE)pMpegSurroundDecoder->upmixType,
                      fGlobalIndependencyFlag);
                  if (err == MPS_OK) {
                    bsFrame->newBsData = 1;
                  }
                }

                nbits = bitsAvail - (INT)FDKgetValidBits(hMpsBsData);

                if ((nbits > bitsAvail) ||
                    (nbits > pMpegSurroundDecoder->mpsDataBits) ||
                    (pMpegSurroundDecoder->mpsDataBits > nbits + 7 &&
                     !IS_LOWDELAY(coreCodec))) {
                  bsFrame->newBsData = 0;
                  err = MPS_PARSE_ERROR;
                  break;
                }
                pMpegSurroundDecoder->mpsDataBits -= nbits;
              }
              break;

            default: /* added to avoid compiler warning */
              err = MPS_NOTOK;
              break; /* added to avoid compiler warning */
          }          /* switch (ancType) */

          if (err == MPS_OK) {
            pMpegSurroundDecoder->ancStartStopPrev = ancStartStop;
          } else {
            updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                            MPEGS_INIT_ERROR_PAYLOAD,
                                            MPEGS_SYNC_LOST, MPEGS_STOP);
            pMpegSurroundDecoder->mpsDataBits = 0;
          }
        } /* (ancStartStop == MPEGS_STOP) || (ancStartStop == MPEGS_START_STOP)
           */
      }   /* validAncStartStop */
    }     /* validAncType */
  }

bail:

  *pMpsDataBits -= (mpsBsBits - (INT)FDKgetValidBits(hBs));

  return err;
}

int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
                              INT_PCM *input, PCM_MPS *pTimeData,
                              const int timeDataSize, int timeDataFrameSize,
                              int *nChannels, int *frameSize, int sampleRate,
                              AUDIO_OBJECT_TYPE coreCodec,
                              AUDIO_CHANNEL_TYPE channelType[],
                              UCHAR channelIndices[],
                              const FDK_channelMapDescr *const mapDescr) {
  SACDEC_ERROR err = MPS_OK;
  PCM_MPS *pTimeOut = pTimeData;
  UINT initControlFlags = 0, controlFlags = 0;
  int timeDataRequiredSize = 0;
  int newData;

  if (pMpegSurroundDecoder == NULL) {
    return MPS_INVALID_HANDLE;
  }

  FDK_ASSERT(pMpegSurroundDecoder->pSpatialDec);

  if (!FDK_chMapDescr_isValid(mapDescr)) {
    return MPS_INVALID_HANDLE;
  }

  if ((*nChannels <= 0) || (*nChannels > 2)) {
    return MPS_NOTOK;
  }

  pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
      &pMpegSurroundDecoder
           ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
  newData = pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse]
                .newBsData;

  switch (mpegSurroundOperationMode(pMpegSurroundDecoder, 1000)) {
    case MPEGS_OPMODE_MPS_PAYLOAD:
      if (pMpegSurroundDecoder
              ->initFlags[pMpegSurroundDecoder->bsFrameDecode]) {
        err = initMpegSurroundDecoder(pMpegSurroundDecoder);
      }

      if (err == MPS_OK) {
        if ((pMpegSurroundDecoder
                 ->fOnSync[pMpegSurroundDecoder->bsFrameDecode] !=
             MPEGS_SYNC_COMPLETE) &&
            (pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode]
                 .bsIndependencyFlag == 1)) {
          /* We got a valid header and independently decodeable frame data.
              -> Go to the next sync level and start processing. */
          pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
              MPEGS_SYNC_COMPLETE;
        }
      } else {
        /* We got a valid config header but found an error while parsing the
           bitstream. Wait for the next independent frame and apply error
           conealment in the meantime. */
        pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
            MPEGS_SYNC_FOUND;
        controlFlags |= MPEGS_CONCEAL;
        err = MPS_OK;
      }
      /*
         Concealment:
         - Bitstream is available, no sync found during bitstream processing
         - Bitstream is available, sync lost due to corrupted bitstream
         - Bitstream is available, sync found but no independent frame
      */
      if (pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] !=
          MPEGS_SYNC_COMPLETE) {
        controlFlags |= MPEGS_CONCEAL;
      }
      break;

    case MPEGS_OPMODE_NO_MPS_PAYLOAD:
      /* Concealment: No bitstream is available */
      controlFlags |= MPEGS_CONCEAL;
      break;

    default:
      err = MPS_NOTOK;
  }

  if (err != MPS_OK) {
    goto bail;
  }

  /*
   * Force BypassMode if choosen by user
   */
  if (pMpegSurroundDecoder->mpegSurroundUserParams.bypassMode) {
    controlFlags |= MPEGS_BYPASSMODE;
  }

  if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode]) {
    int startWithDfltCfg = 0;
    /*
     * Init with a default configuration if we came here and are still not
     * initialized.
     */
    if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] &
        MPEGS_INIT_ENFORCE_REINIT) {
      /* Get default spatial specific config */
      if (FDK_SpatialDecInitDefaultSpatialSpecificConfig(
              &pMpegSurroundDecoder->spatialSpecificConfigBackup, coreCodec,
              *nChannels, sampleRate,
              *frameSize /
                  mpegSurroundDecoder_GetNrOfQmfBands(NULL, sampleRate),
              pMpegSurroundDecoder->mpegSurroundDecoderLevel,
              pMpegSurroundDecoder->mpegSurroundUserParams.blindEnable)) {
        err = MPS_NOTOK;
        goto bail;
      }

      /* Initiate re-initialization, if header has changed */
      if (FDK_SpatialDecCompareSpatialSpecificConfigHeader(
              &pMpegSurroundDecoder->spatialSpecificConfigBackup,
              &pMpegSurroundDecoder->spatialSpecificConfig
                   [pMpegSurroundDecoder->bsFrameDecode]) == MPS_UNEQUAL_SSC) {
        pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
            MPEGS_INIT_CHANGE_HEADER;
        SpatialDecInitParserContext(pMpegSurroundDecoder->pSpatialDec);
      }

      startWithDfltCfg = 1;
    }

    /* First spatial specific config is parsed into spatialSpecificConfigBackup,
     * second spatialSpecificConfigBackup is copied into spatialSpecificConfig
     */
    err = initMpegSurroundDecoder(pMpegSurroundDecoder);

    if (startWithDfltCfg) {
      /* initialized with default config, but no sync found */
      /* maybe use updateMpegSurroundDecoderStatus later on */
      pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
          MPEGS_SYNC_LOST;
    }

    /* Since we do not have state MPEGS_SYNC_COMPLETE apply concealment */
    controlFlags |= MPEGS_CONCEAL;

    if (err != MPS_OK) {
      goto bail;
    }
  }

  /*
   * Process MPEG Surround Audio
   */
  initControlFlags = controlFlags;

  /* Check that provided output buffer is large enough. */
  if (pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis == 0) {
    err = MPS_UNSUPPORTED_FORMAT;
    goto bail;
  }
  timeDataRequiredSize =
      (timeDataFrameSize *
       pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT *
       pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
      pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
  if (timeDataSize < timeDataRequiredSize) {
    err = MPS_OUTPUT_BUFFER_TOO_SMALL;
    goto bail;
  }

  if ((pMpegSurroundDecoder->pSpatialDec->pConfigCurrent->syntaxFlags &
       SACDEC_SYNTAX_USAC) &&
      (pMpegSurroundDecoder->pSpatialDec->stereoConfigIndex > 1)) {
    FDK_ASSERT(timeDataRequiredSize >= timeDataFrameSize * *nChannels);
    /* Place samples comprising QMF time slots spaced at QMF output Band raster
     * to allow slot wise processing */
    int timeDataFrameSizeOut =
        (timeDataFrameSize *
         pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
        pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
    pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput =
        pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
    for (int i = *nChannels - 1; i >= 0; i--) {
      FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize,
                 pTimeData + timeDataFrameSize * i,
                 sizeof(PCM_MPS) * timeDataFrameSize);
      FDKmemclear(pTimeData + i * timeDataFrameSizeOut,
                  sizeof(PCM_MPS) * (timeDataFrameSizeOut - timeDataFrameSize));
    }
  } else {
    if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) {
      FDKmemcpy(input, pTimeData,
                sizeof(INT_PCM) * (*nChannels) * (*frameSize));
      pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input;
    }
  }

  /*
   * Process MPEG Surround Audio
   */
  err = SpatialDecApplyFrame(
      pMpegSurroundDecoder->pSpatialDec,
      &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
      pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME
                                                         : INPUTMODE_QMF_SBR,
      pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL,
      pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr);
  *nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT;

  if (err !=
      MPS_OK) { /* A fatal error occured. Go back to start and try again: */
    updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                    MPEGS_INIT_ENFORCE_REINIT, MPEGS_SYNC_LOST,
                                    MPEGS_STOP);
    *frameSize =
        0; /* Declare that framework can not use the data in pTimeOut. */
  } else {
    if (((controlFlags & MPEGS_CONCEAL) &&
         !(initControlFlags & MPEGS_CONCEAL)) ||
        (pMpegSurroundDecoder->pSpatialDec->errInt !=
         MPS_OK)) { /* Account for errors that occured in
                       SpatialDecApplyFrame(): */
      updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                      MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
                                      MPEGS_STOP);
    }
  }

  if ((err == MPS_OK) && !(controlFlags & MPEGS_BYPASSMODE) &&
      !(pMpegSurroundDecoder->upmixType == UPMIX_TYPE_BYPASS)) {
    SpatialDecChannelProperties(pMpegSurroundDecoder->pSpatialDec, channelType,
                                channelIndices, mapDescr);
  }

bail:

  if (newData) {
    /* numParameterSetsPrev shall only be read in the decode process, because of
       that we can update this state variable here */
    pMpegSurroundDecoder->pSpatialDec->numParameterSetsPrev =
        pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode]
            .numParameterSets;
  }

  return (err);
}

/**
 * \brief Free config dependent MPEG Surround memory.
 **/
SACDEC_ERROR mpegSurroundDecoder_FreeMem(
    CMpegSurroundDecoder *pMpegSurroundDecoder) {
  SACDEC_ERROR err = MPS_OK;

  if (pMpegSurroundDecoder != NULL) {
    FDK_SpatialDecClose(pMpegSurroundDecoder->pSpatialDec);
    pMpegSurroundDecoder->pSpatialDec = NULL;
  }

  return err;
}

/**
 * \brief Close MPEG Surround decoder.
 **/
void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) {
  if (pMpegSurroundDecoder != NULL) {
    FDK_SpatialDecClose(pMpegSurroundDecoder->pSpatialDec);
    pMpegSurroundDecoder->pSpatialDec = NULL;

    for (int i = 0; i < 1; i++) {
      SpatialDecCloseBsFrame(&pMpegSurroundDecoder->bsFrames[i]);
    }

    FDK_FREE_MEMORY_1D(pMpegSurroundDecoder);
  }
}

#define SACDEC_VL0 2
#define SACDEC_VL1 0
#define SACDEC_VL2 0

int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
  int i;

  if (info == NULL) {
    return -1;
  }

  /* search for next free tab */
  for (i = 0; i < FDK_MODULE_LAST; i++) {
    if (info[i].module_id == FDK_NONE) break;
  }
  if (i == FDK_MODULE_LAST) return -1;

  info += i;

  info->module_id = FDK_MPSDEC;
#ifdef __ANDROID__
  info->build_date = "";
  info->build_time = "";
#else
  info->build_date = __DATE__;
  info->build_time = __TIME__;
#endif
  info->title = "MPEG Surround Decoder";
  info->version = LIB_VERSION(SACDEC_VL0, SACDEC_VL1, SACDEC_VL2);
  LIB_VERSION_STRING(info);
  info->flags = 0 | CAPF_MPS_LD | CAPF_MPS_USAC | CAPF_MPS_HQ |
                CAPF_MPS_1CH_IN | CAPF_MPS_2CH_OUT; /* end flags */

  return 0;
}

SACDEC_ERROR mpegSurroundDecoder_SetParam(
    CMpegSurroundDecoder *pMpegSurroundDecoder, const SACDEC_PARAM param,
    const INT value) {
  SACDEC_ERROR err = MPS_OK;
  SPATIALDEC_PARAM *pUserParams = NULL;

  /* check decoder handle */
  if (pMpegSurroundDecoder != NULL) {
    /* init local shortcuts */
    pUserParams = &pMpegSurroundDecoder->mpegSurroundUserParams;
  } else {
    err = MPS_INVALID_HANDLE;
    /* check the parameter values before exiting. */
  }

  /* apply param value */
  switch (param) {
    case SACDEC_OUTPUT_MODE:
      switch ((SAC_DEC_OUTPUT_MODE)value) {
        case SACDEC_OUT_MODE_NORMAL:
        case SACDEC_OUT_MODE_STEREO:
          break;
        default:
          err = MPS_INVALID_PARAMETER;
      }
      if (err == MPS_OK) {
        if (0) {
          err = MPS_INVALID_PARAMETER;
        } else if (pUserParams->outputMode != (UCHAR)value) {
          pUserParams->outputMode = (UCHAR)value;
          pMpegSurroundDecoder
              ->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
              MPEGS_INIT_CHANGE_OUTPUT_MODE;
        }
      }
      break;

    case SACDEC_INTERFACE:
      if (value < 0 || value > 1) {
        err = MPS_INVALID_PARAMETER;
      }
      if (err != MPS_OK) {
        goto bail;
      }
      if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface != (UCHAR)value) {
        pMpegSurroundDecoder->mpegSurroundUseTimeInterface = (UCHAR)value;
        pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
            MPEGS_INIT_CHANGE_TIME_FREQ_INTERFACE;
      }
      break;

    case SACDEC_BS_INTERRUPTION:
      if ((err == MPS_OK) && (value != 0)) {
        updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                        MPEGS_INIT_BS_INTERRUPTION,
                                        MPEGS_SYNC_LOST, MPEGS_STOP);
      }
      break;

    case SACDEC_CLEAR_HISTORY:
      if ((err == MPS_OK) && (value != 0)) {
        /* Just reset the states and go on. */
        updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
                                        MPEGS_INIT_CLEAR_HISTORY,
                                        MPEGS_SYNC_LOST, MPEGS_STOP);
      }
      break;

    case SACDEC_CONCEAL_NUM_KEEP_FRAMES:
      if (value < 0) { /* Check valid value range */
        err = MPS_INVALID_PARAMETER;
      }
      if (err != MPS_OK) {
        goto bail;
      }
      if (pUserParams->concealNumKeepFrames != (UINT)value) {
        pUserParams->concealNumKeepFrames = (UINT)value;
        pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
            MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
      }
      break;

    case SACDEC_CONCEAL_FADE_OUT_SLOPE_LENGTH:
      if (value < 0) { /* Check valid value range */
        err = MPS_INVALID_PARAMETER;
      }
      if (err != MPS_OK) {
        goto bail;
      }
      if (pUserParams->concealFadeOutSlopeLength != (UINT)value) {
        pUserParams->concealFadeOutSlopeLength = (UINT)value;
        pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
            MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
      }
      break;

    case SACDEC_CONCEAL_FADE_IN_SLOPE_LENGTH:
      if (value < 0) { /* Check valid value range */
        err = MPS_INVALID_PARAMETER;
      }
      if (err != MPS_OK) {
        goto bail;
      }
      if (pUserParams->concealFadeInSlopeLength != (UINT)value) {
        pUserParams->concealFadeInSlopeLength = (UINT)value;
        pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
            MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
      }
      break;

    case SACDEC_CONCEAL_NUM_RELEASE_FRAMES:
      if (value < 0) { /* Check valid value range */
        err = MPS_INVALID_PARAMETER;
      }
      if (err != MPS_OK) {
        goto bail;
      }
      if (pUserParams->concealNumReleaseFrames != (UINT)value) {
        pUserParams->concealNumReleaseFrames = (UINT)value;
        pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
            MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
      }
      break;

    default:
      err = MPS_INVALID_PARAMETER;
      break;
  } /* switch(param) */

bail:
  return err;
}

SACDEC_ERROR mpegSurroundDecoder_IsPseudoLR(
    CMpegSurroundDecoder *pMpegSurroundDecoder, int *bsPseudoLr) {
  if (pMpegSurroundDecoder != NULL) {
    const SPATIAL_SPECIFIC_CONFIG *sscDecode =
        &pMpegSurroundDecoder
             ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
    *bsPseudoLr = (int)sscDecode->bsPseudoLr;
    return MPS_OK;
  } else
    return MPS_INVALID_HANDLE;
}

/**
 * \brief Get the signal delay caused by the MPEG Surround decoder module.
 **/
UINT mpegSurroundDecoder_GetDelay(const CMpegSurroundDecoder *self) {
  INT outputDelay = 0;

  if (self != NULL) {
    const SPATIAL_SPECIFIC_CONFIG *sscDecode =
        &self->spatialSpecificConfig[self->bsFrameDecode];
    AUDIO_OBJECT_TYPE coreCodec = sscDecode->coreCodec;

    /* See chapter 4.5 (delay and synchronization) of ISO/IEC FDIS 23003-1 and
       chapter 5.4.3 of ISO/IEC FDIS 23003-2 for details on the following
       figures. */

    if (coreCodec > AOT_NULL_OBJECT) {
      if (IS_LOWDELAY(coreCodec)) {
        /* All low delay variants (ER-AAC-(E)LD): */
        outputDelay += 256;
      } else if (!IS_USAC(coreCodec)) {
        /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...)
         * branch: */
        outputDelay += 320 + 257; /* cos to exp delay + QMF synthesis */
        if (self->mpegSurroundUseTimeInterface) {
          outputDelay += 320 + 384; /* QMF and hybrid analysis */
        }
      }
    }
  }

  return (outputDelay);
}
