/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2019 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

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

#include "sac_dec_errorcodes.h"
#include "sac_dec.h"

#include "sac_process.h"
#include "sac_bitdec.h"
#include "sac_smoothing.h"
#include "sac_calcM1andM2.h"
#include "sac_reshapeBBEnv.h"
#include "sac_stp.h"
#include "sac_rom.h"

#include "FDK_decorrelate.h"

#include "FDK_trigFcts.h"
#include "FDK_matrixCalloc.h"

/* static int pbStrideTable[] = {1, 2, 5, 28}; see sac_rom.cpp */

enum {
  APPLY_M2_NONE = 0,    /* init value */
  APPLY_M2 = 1,         /* apply m2 fallback implementation */
  APPLY_M2_MODE212 = 2, /* apply m2 for 212 mode */
  APPLY_M2_MODE212_Res_PhaseCoding =
      3 /* apply m2 for 212 mode with residuals and phase coding */
};

/******************************************************************************************/
/* function: FDK_SpatialDecInitDefaultSpatialSpecificConfig */
/* output:   struct of type SPATIAL_SPECIFIC_CONFIG */
/* input:    core coder audio object type */
/* input:    nr of core channels */
/* input:    sampling rate */
/* input:    nr of time slots */
/* input:    decoder level */
/* input:    flag indicating upmix type blind */
/*                                                                                        */
/* returns:  error code */
/******************************************************************************************/
int FDK_SpatialDecInitDefaultSpatialSpecificConfig(
    SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
    AUDIO_OBJECT_TYPE coreCodec, int coreChannels, int samplingFreq,
    int nTimeSlots, int decoderLevel, int isBlind) {
  return SpatialDecDefaultSpecificConfig(pSpatialSpecificConfig, coreCodec,
                                         samplingFreq, nTimeSlots, decoderLevel,
                                         isBlind, coreChannels);
}

/******************************************************************************************/
/* function: FDK_SpatialDecCompareSpatialSpecificConfigHeader */
/* input:    2 pointers to a ssc */
/*                                                                                        */
/* output:   - */
/* returns:  error code (0 = equal, <>0 unequal) */
/******************************************************************************************/
int FDK_SpatialDecCompareSpatialSpecificConfigHeader(
    SPATIAL_SPECIFIC_CONFIG *pSsc1, SPATIAL_SPECIFIC_CONFIG *pSsc2) {
  int result = MPS_OK;

  /* we assume: every bit must be equal */
  if (FDKmemcmp(pSsc1, pSsc2, sizeof(SPATIAL_SPECIFIC_CONFIG)) != 0) {
    result = MPS_UNEQUAL_SSC;
  }
  return result;
}

/*******************************************************************************
 Functionname: SpatialDecClearFrameData
 *******************************************************************************

 Description: Clear/Fake frame data to avoid misconfiguration and allow proper
              error concealment.
 Arguments:
 Input:       self (frame data)
 Output:      No return value.

*******************************************************************************/
static void SpatialDecClearFrameData(
    spatialDec *self, /* Shall be removed */
    SPATIAL_BS_FRAME *bsFrame, const SACDEC_CREATION_PARAMS *const setup) {
  int i;

  FDK_ASSERT(self != NULL);
  FDK_ASSERT(bsFrame != NULL);
  FDK_ASSERT(setup != NULL);

  /* do not apply shaping tools (GES or STP) */
  for (i = 0; i < setup->maxNumOutputChannels;
       i += 1) { /* MAX_OUTPUT_CHANNELS */
    bsFrame->tempShapeEnableChannelSTP[i] = 0;
    bsFrame->tempShapeEnableChannelGES[i] = 0;
  }

  bsFrame->TsdData->bsTsdEnable = 0;

  /* use only 1 parameter set at the end of the frame */
  bsFrame->numParameterSets = 1;
  bsFrame->paramSlot[0] = self->timeSlots - 1;

  /* parameter smoothing tool set to off */
  bsFrame->bsSmoothMode[0] = 0;
  initParameterSmoothing(self);

  /* reset residual data */
  {
    int resQmfBands, resTimeSlots = (1);

    resQmfBands = setup->maxNumQmfBands;

    for (i = 0; i < setup->bProcResidual
                    ? fMin(setup->maxNumResChannels,
                           setup->maxNumOttBoxes + setup->maxNumInputChannels)
                    : 0;
         i += 1) {
      for (int j = 0; j < resTimeSlots; j += 1) {
        for (int k = 0; k < resQmfBands; k += 1) {
          self->qmfResidualReal__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
          self->qmfResidualImag__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
        }
      }
    }
  }

  return;
}

/*******************************************************************************
 Functionname: FDK_SpatialDecOpen
 *******************************************************************************

 Description:

 Arguments:

 Return:

*******************************************************************************/
spatialDec *FDK_SpatialDecOpen(const SPATIAL_DEC_CONFIG *config,
                               int stereoConfigIndex) {
  int i;
  int lfSize, hfSize;
  spatialDec *self = NULL;
  SACDEC_CREATION_PARAMS setup;

  switch (config->decoderLevel) {
    case DECODER_LEVEL_0: /* 212 maxNumOutputChannels== 2 */
      setup.maxNumInputChannels = 1;
      setup.maxNumOutputChannels = 2;
      setup.maxNumQmfBands = 64;
      setup.maxNumXChannels = 2;
      setup.maxNumVChannels = 2;
      setup.maxNumDecorChannels = 1;
      setup.bProcResidual = 1;
      setup.maxNumResidualChannels = 0;
      setup.maxNumOttBoxes = 1;
      setup.maxNumParams = setup.maxNumInputChannels + setup.maxNumOttBoxes;
      break;
    default:
      return NULL;
  }

  setup.maxNumResChannels = 1;

  {
    switch (config->maxNumOutputChannels) {
      case OUTPUT_CHANNELS_2_0:
        setup.maxNumOutputChannels = fMin(setup.maxNumOutputChannels, 2);
        break;
      case OUTPUT_CHANNELS_DEFAULT:
      default:
        break;
    }
  }

  setup.maxNumHybridBands = SacGetHybridSubbands(setup.maxNumQmfBands);

  switch (config->decoderMode) {
    case EXT_HQ_ONLY:
      setup.maxNumCmplxQmfBands = setup.maxNumQmfBands;
      setup.maxNumCmplxHybBands = setup.maxNumHybridBands;
      break;
    default:
      setup.maxNumCmplxQmfBands = fixMax(PC_NUM_BANDS, setup.maxNumQmfBands);
      setup.maxNumCmplxHybBands =
          fixMax(PC_NUM_HYB_BANDS, setup.maxNumHybridBands);
      break;
  } /* switch config->decoderMode */

  FDK_ALLOCATE_MEMORY_1D_INT(self, 1, spatialDec, SECT_DATA_L2)

  self->createParams = setup;

  FDK_ALLOCATE_MEMORY_1D(self->param2hyb, MAX_PARAMETER_BANDS + 1, int)

  FDK_ALLOCATE_MEMORY_1D(self->numOttBands, setup.maxNumOttBoxes, int)

  /* allocate arrays */

  FDK_ALLOCATE_MEMORY_1D(self->smgTime, MAX_PARAMETER_SETS, int)
  FDK_ALLOCATE_MEMORY_2D(self->smgData, MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS,
                         UCHAR)

  FDK_ALLOCATE_MEMORY_3D(self->ottCLD__FDK, setup.maxNumOttBoxes,
                         MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_3D(self->ottICC__FDK, setup.maxNumOttBoxes,
                         MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_3D(self->ottIPD__FDK, setup.maxNumOttBoxes,
                         MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)

  /* Last parameters from prev frame */
  FDK_ALLOCATE_MEMORY_2D(self->ottCLDidxPrev, setup.maxNumOttBoxes,
                         MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_2D(self->ottICCidxPrev, setup.maxNumOttBoxes,
                         MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_3D(self->ottICCdiffidx, setup.maxNumOttBoxes,
                         MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_2D(self->ottIPDidxPrev, setup.maxNumOttBoxes,
                         MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_2D(self->arbdmxGainIdxPrev, setup.maxNumInputChannels,
                         MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_2D(self->cmpOttCLDidxPrev, setup.maxNumOttBoxes,
                         MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_2D(self->cmpOttICCidxPrev, setup.maxNumOttBoxes,
                         MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_3D(self->outIdxData, setup.maxNumOttBoxes,
                         MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)

  FDK_ALLOCATE_MEMORY_3D(self->arbdmxGain__FDK, setup.maxNumInputChannels,
                         MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
  FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlpha__FDK, setup.maxNumInputChannels,
                         FIXP_DBL)
  FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlphaPrev__FDK, setup.maxNumInputChannels,
                         FIXP_DBL)
  FDK_ALLOCATE_MEMORY_2D(self->cmpArbdmxGainIdxPrev, setup.maxNumInputChannels,
                         MAX_PARAMETER_BANDS, SCHAR)

  FDK_ALLOCATE_MEMORY_2D(self->cmpOttIPDidxPrev, setup.maxNumOttBoxes,
                         MAX_PARAMETER_BANDS, SCHAR)

  FDK_ALLOCATE_MEMORY_3D_INT(self->M2Real__FDK, setup.maxNumOutputChannels,
                             setup.maxNumVChannels, MAX_PARAMETER_BANDS,
                             FIXP_DBL, SECT_DATA_L2)
  FDK_ALLOCATE_MEMORY_3D(self->M2Imag__FDK, setup.maxNumOutputChannels,
                         setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)

  FDK_ALLOCATE_MEMORY_3D_INT(self->M2RealPrev__FDK, setup.maxNumOutputChannels,
                             setup.maxNumVChannels, MAX_PARAMETER_BANDS,
                             FIXP_DBL, SECT_DATA_L2)
  FDK_ALLOCATE_MEMORY_3D(self->M2ImagPrev__FDK, setup.maxNumOutputChannels,
                         setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)

  FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
      self->qmfInputReal__FDK, setup.maxNumInputChannels, setup.maxNumQmfBands,
      FIXP_DBL, SECT_DATA_L2)
  FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
      self->qmfInputImag__FDK, setup.maxNumInputChannels,
      setup.maxNumCmplxQmfBands, FIXP_DBL, SECT_DATA_L2)

  FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputReal__FDK, setup.maxNumInputChannels,
                             setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
  FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputImag__FDK, setup.maxNumInputChannels,
                             setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)

  if (setup.bProcResidual) {
    FDK_ALLOCATE_MEMORY_1D(self->qmfResidualReal__FDK, setup.maxNumResChannels,
                           FIXP_DBL **)
    FDK_ALLOCATE_MEMORY_1D(self->qmfResidualImag__FDK, setup.maxNumResChannels,
                           FIXP_DBL **)

    FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK, setup.maxNumResChannels,
                           FIXP_DBL *)
    FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK, setup.maxNumResChannels,
                           FIXP_DBL *)

    for (i = 0; i < setup.maxNumResChannels; i++) {
      int resQmfBands = (config->decoderMode == EXT_LP_ONLY)
                            ? PC_NUM_BANDS
                            : setup.maxNumQmfBands;
      int resHybBands = (config->decoderMode == EXT_LP_ONLY)
                            ? PC_NUM_HYB_BANDS
                            : setup.maxNumHybridBands;
      /* Alignment is needed for USAC residuals because QMF analysis directly
       * writes to this buffer. */
      FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualReal__FDK[i], (1),
                                         resQmfBands, FIXP_DBL, SECT_DATA_L1)
      FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualImag__FDK[i], (1),
                                         resQmfBands, FIXP_DBL, SECT_DATA_L1)

      FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK[i],
                             setup.maxNumHybridBands, FIXP_DBL)
      FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK[i], resHybBands,
                             FIXP_DBL)
    }
  } /* if (setup.bProcResidual) */

  FDK_ALLOCATE_MEMORY_2D_INT(self->wReal__FDK, setup.maxNumVChannels,
                             setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
  FDK_ALLOCATE_MEMORY_2D_INT(self->wImag__FDK, setup.maxNumVChannels,
                             setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)

  FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealDry__FDK,
                             setup.maxNumOutputChannels,
                             setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
  FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagDry__FDK,
                             setup.maxNumOutputChannels,
                             setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)

  FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealWet__FDK,
                             setup.maxNumOutputChannels,
                             setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
  FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagWet__FDK,
                             setup.maxNumOutputChannels,
                             setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)

  FDK_ALLOCATE_MEMORY_1D(self->hybridSynthesis, setup.maxNumOutputChannels,
                         FDK_SYN_HYB_FILTER)

  FDK_ALLOCATE_MEMORY_1D(
      self->hybridAnalysis,
      setup.bProcResidual ? setup.maxNumInputChannels + setup.maxNumResChannels
                          : setup.maxNumInputChannels,
      FDK_ANA_HYB_FILTER)

  lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
  {
    hfSize =
        BUFFER_LEN_HF * ((setup.maxNumQmfBands - MAX_QMF_BANDS_TO_HYBRID) +
                         (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));
  }

  FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFdmx,
                             setup.maxNumInputChannels, lfSize, FIXP_DBL,
                             SECT_DATA_L2) {
    FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFdmx,
                           setup.maxNumInputChannels, hfSize, FIXP_DBL)
  }

  for (i = 0; i < setup.maxNumInputChannels; i++) {
    FIXP_DBL *pHybridAnaStatesHFdmx;

    pHybridAnaStatesHFdmx = self->pHybridAnaStatesHFdmx[i];

    FDKhybridAnalysisOpen(&self->hybridAnalysis[i],
                          self->pHybridAnaStatesLFdmx[i],
                          lfSize * sizeof(FIXP_DBL), pHybridAnaStatesHFdmx,
                          hfSize * sizeof(FIXP_DBL));
  }
  if (setup.bProcResidual) {
    lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
    hfSize = BUFFER_LEN_HF *
             ((((config->decoderMode == EXT_LP_ONLY) ? PC_NUM_BANDS
                                                     : setup.maxNumQmfBands) -
               MAX_QMF_BANDS_TO_HYBRID) +
              (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));

    FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFres,
                               setup.maxNumResChannels, lfSize, FIXP_DBL,
                               SECT_DATA_L2)
    FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFres, setup.maxNumResChannels,
                           hfSize, FIXP_DBL)

    for (i = setup.maxNumInputChannels;
         i < (setup.maxNumInputChannels + setup.maxNumResChannels); i++) {
      FDKhybridAnalysisOpen(
          &self->hybridAnalysis[i],
          self->pHybridAnaStatesLFres[i - setup.maxNumInputChannels],
          lfSize * sizeof(FIXP_DBL),
          self->pHybridAnaStatesHFres[i - setup.maxNumInputChannels],
          hfSize * sizeof(FIXP_DBL));
    }
  }

  FDK_ALLOCATE_MEMORY_1D(self->smoothState, 1, SMOOTHING_STATE)
  FDK_ALLOCATE_MEMORY_1D(self->reshapeBBEnvState, 1, RESHAPE_BBENV_STATE)

  FDK_ALLOCATE_MEMORY_1D(self->apDecor, setup.maxNumDecorChannels, DECORR_DEC)
  FDK_ALLOCATE_MEMORY_2D_INT(self->pDecorBufferCplx, setup.maxNumDecorChannels,
                             (2 * ((825) + (373))), FIXP_DBL, SECT_DATA_L2)

  for (i = 0; i < setup.maxNumDecorChannels; i++) {
    if (FDKdecorrelateOpen(&self->apDecor[i], self->pDecorBufferCplx[i],
                           (2 * ((825) + (373))))) {
      goto bail;
    }
  }

  if (subbandTPCreate(&self->hStpDec) != MPS_OK) {
    goto bail;
  }

  /* save general decoder configuration */
  self->decoderLevel = config->decoderLevel;
  self->decoderMode = config->decoderMode;
  self->binauralMode = config->binauralMode;

  /* preinitialize configuration */
  self->partiallyComplex = (config->decoderMode != EXT_HQ_ONLY) ? 1 : 0;

  /* Set to default state */
  SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_ALL);

  /* Everything is fine so return the handle */
  return self;

bail:
  /* Collector for all errors.
     Deallocate all memory and return a invalid handle. */
  FDK_SpatialDecClose(self);

  return NULL;
}

/*******************************************************************************
 Functionname: isValidConfig
 *******************************************************************************

 Description: Validate if configuration is supported in present instance

 Arguments:

 Return: 1: all okay
         0: configuration not supported
*******************************************************************************/
static int isValidConfig(spatialDec const *const self,
                         const SPATIAL_DEC_UPMIX_TYPE upmixType,
                         SPATIALDEC_PARAM const *const pUserParams,
                         const AUDIO_OBJECT_TYPE coreAot) {
  UPMIXTYPE nUpmixType;

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

  nUpmixType = (UPMIXTYPE)upmixType;

  switch (nUpmixType) {
    case UPMIXTYPE_BYPASS: /* UPMIX_TYPE_BYPASS */
      break;
    case UPMIXTYPE_NORMAL: /* UPMIX_TYPE_NORMAL */
      break;
    default:
      return 0; /* unsupported upmixType */
  }

  return 1; /* upmixType supported */
}

static SACDEC_ERROR CheckLevelTreeUpmixType(
    const SACDEC_CREATION_PARAMS *const pCreateParams,
    const SPATIAL_SPECIFIC_CONFIG *const pSsc, const int decoderLevel,
    const UPMIXTYPE upmixType) {
  SACDEC_ERROR err = MPS_OK;
  int nOutputChannels, treeConfig;

  FDK_ASSERT(pCreateParams != NULL);
  FDK_ASSERT(pSsc != NULL);

  treeConfig = pSsc->treeConfig;

  switch (decoderLevel) {
    case 0: {
      if (treeConfig != SPATIALDEC_MODE_RSVD7) {
        err = MPS_INVALID_TREECONFIG;
        goto bail;
      }
      break;
    }
    default:
      err = MPS_INVALID_PARAMETER /* MPS_UNIMPLEMENTED */;
      goto bail;
  }

  switch (upmixType) {
    case UPMIXTYPE_BYPASS:
      nOutputChannels = pSsc->nInputChannels;
      break;
    default:
      nOutputChannels = pSsc->nOutputChannels;
      break;
  }

  /* Is sufficient memory allocated. */
  if ((pSsc->nInputChannels > pCreateParams->maxNumInputChannels) ||
      (nOutputChannels > pCreateParams->maxNumOutputChannels) ||
      (pSsc->nOttBoxes > pCreateParams->maxNumOttBoxes)) {
    err = MPS_INVALID_PARAMETER;
  }

bail:
  return err;
}

void SpatialDecInitParserContext(spatialDec *self) {
  int i, j;

  for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
    for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
      self->ottCLDidxPrev[i][j] = 0;
      self->ottICCidxPrev[i][j] = 0;
      self->cmpOttCLDidxPrev[i][j] = 0;
      self->cmpOttICCidxPrev[i][j] = 0;
    }
  }
  for (i = 0; i < self->createParams.maxNumInputChannels; i++) {
    for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
      self->arbdmxGainIdxPrev[i][j] = 0;
      self->cmpArbdmxGainIdxPrev[i][j] = 0;
    }
  }
}

/*******************************************************************************
 Functionname: FDK_SpatialDecInit
 *******************************************************************************

 Description:

 Arguments:

 Return:

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

SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
                                SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
                                int nQmfBands,
                                SPATIAL_DEC_UPMIX_TYPE const upmixType,
                                SPATIALDEC_PARAM *pUserParams, UINT initFlags) {
  SACDEC_ERROR err = MPS_OK;
  int nCh, i, j, k;
  int maxQmfBands;
  int bypassMode = 0;

  self->useFDreverb = 0;

  /* check configuration parameter */
  if (!isValidConfig(self, upmixType, pUserParams,
                     pSpatialSpecificConfig->coreCodec)) {
    return MPS_INVALID_PARAMETER;
  }

  /* check tree configuration */
  err = CheckLevelTreeUpmixType(&self->createParams, pSpatialSpecificConfig,
                                self->decoderLevel, (UPMIXTYPE)upmixType);
  if (err != MPS_OK) {
    goto bail;
  }

  /* Store and update instance after all checks passed successfully: */
  self->upmixType = (UPMIXTYPE)upmixType;

  if (initFlags & MPEGS_INIT_PARAMS_ERROR_CONCEALMENT) { /* At least one error
                                                            concealment
                                                            parameter changed */
    err = SpatialDecConcealment_SetParam(
        &self->concealInfo, SAC_DEC_CONCEAL_METHOD, pUserParams->concealMethod);
    if (err != MPS_OK) {
      goto bail;
    }
    err = SpatialDecConcealment_SetParam(&self->concealInfo,
                                         SAC_DEC_CONCEAL_NUM_KEEP_FRAMES,
                                         pUserParams->concealNumKeepFrames);
    if (err != MPS_OK) {
      goto bail;
    }
    err = SpatialDecConcealment_SetParam(
        &self->concealInfo, SAC_DEC_CONCEAL_FADE_OUT_SLOPE_LENGTH,
        pUserParams->concealFadeOutSlopeLength);
    if (err != MPS_OK) {
      goto bail;
    }
    err = SpatialDecConcealment_SetParam(&self->concealInfo,
                                         SAC_DEC_CONCEAL_FADE_IN_SLOPE_LENGTH,
                                         pUserParams->concealFadeInSlopeLength);
    if (err != MPS_OK) {
      goto bail;
    }
    err = SpatialDecConcealment_SetParam(&self->concealInfo,
                                         SAC_DEC_CONCEAL_NUM_RELEASE_FRAMES,
                                         pUserParams->concealNumReleaseFrames);
    if (err != MPS_OK) {
      goto bail;
    }
  }

  if (initFlags &
      MPEGS_INIT_STATES_ERROR_CONCEALMENT) { /* Set to default state */
    SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_STATE);
  }

  /* determine bypass mode */
  bypassMode |= pUserParams->bypassMode;
  bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);

  /* static decoder scale depends on number of qmf bands */
  switch (nQmfBands) {
    case 16:
    case 24:
    case 32:
      self->staticDecScale = 21;
      break;
    case 64:
      self->staticDecScale = 22;
      break;
    default:
      return MPS_INVALID_PARAMETER;
  }

  self->numParameterSetsPrev = 1;

  self->qmfBands = nQmfBands;
  /* self->hybridBands will be updated in SpatialDecDecodeHeader() below. */

  self->bShareDelayWithSBR = 0;

  err = SpatialDecDecodeHeader(self, pSpatialSpecificConfig);
  if (err != MPS_OK) {
    goto bail;
  }

  self->stereoConfigIndex = pSpatialSpecificConfig->stereoConfigIndex;

  if (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) {
    self->qmfInputDelayBufPos = 0;
    self->pc_filterdelay = 1; /* Division by 0 not possible */
  }

  maxQmfBands = self->qmfBands;

  /* init residual decoder */

  /* init tonality smoothing */
  if (initFlags & MPEGS_INIT_STATES_PARAM) {
    initParameterSmoothing(self);
  }

  /* init GES */
  initBBEnv(self, (initFlags & MPEGS_INIT_STATES_GES) ? 1 : 0);

  /* Clip protection is applied only for normal processing. */
  if (!isTwoChMode(self->upmixType) && !bypassMode) {
    self->staticDecScale += self->clipProtectGainSF__FDK;
  }

  {
    UINT flags = 0;
    INT initStatesFlag = (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) ? 1 : 0;
    INT useLdFilter =
        (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) ? 1 : 0;

    flags = self->pQmfDomain->globalConf.flags_requested;
    flags &= (~(UINT)QMF_FLAG_LP);

    if (initStatesFlag)
      flags &= ~QMF_FLAG_KEEP_STATES;
    else
      flags |= QMF_FLAG_KEEP_STATES;

    if (useLdFilter)
      flags |= QMF_FLAG_MPSLDFB;
    else
      flags &= ~QMF_FLAG_MPSLDFB;

    self->pQmfDomain->globalConf.flags_requested = flags;
    FDK_QmfDomain_Configure(self->pQmfDomain);

    /* output scaling */
    for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
      int outputScale = 0, outputGain_e = 0, scale = -(8) + (1);
      FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);

      if (!isTwoChMode(self->upmixType) && !bypassMode) {
        outputScale +=
            self->clipProtectGainSF__FDK; /* consider clip protection scaling at
                                             synthesis qmf */
      }

      scale += outputScale;

      qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
      qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
                       outputGain_e);
    }
  }

  for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
    FDKhybridSynthesisInit(&self->hybridSynthesis[nCh], THREE_TO_TEN,
                           self->qmfBands, maxQmfBands);
  }

  /* for input, residual channels and arbitrary down-mix residual channels */
  for (nCh = 0; nCh < self->createParams.maxNumInputChannels; nCh++) {
    FDKhybridAnalysisInit(
        &self->hybridAnalysis[nCh], THREE_TO_TEN, self->qmfBands, maxQmfBands,
        (initFlags & MPEGS_INIT_STATES_ANA_HYB_FILTER) ? 1 : 0);
  }
  for (; nCh < (self->createParams.bProcResidual
                    ? (self->createParams.maxNumInputChannels +
                       self->createParams.maxNumResChannels)
                    : self->createParams.maxNumInputChannels);
       nCh++) {
    FDKhybridAnalysisInit(&self->hybridAnalysis[nCh], THREE_TO_TEN, maxQmfBands,
                          maxQmfBands, 0);
  }

  {
    for (k = 0; k < self->numDecorSignals; k++) {
      int errCode, idec;
      FDK_DECORR_TYPE decorrType = DECORR_PS;
      decorrType = DECORR_LD;
      if (self->pConfigCurrent->syntaxFlags &
          (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) {
        decorrType =
            ((self->treeConfig == TREE_212) && (self->decorrType == DECORR_PS))
                ? DECORR_PS
                : DECORR_USAC;
      }
      {
        idec = k;
        if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
          if (self->treeConfig == TREE_212 && k == 0) {
            idec = 2;
          }
        }
      }
      errCode = FDKdecorrelateInit(
          &self->apDecor[k], self->hybridBands, decorrType, DUCKER_AUTOMATIC,
          self->decorrConfig, idec, 0, /* self->partiallyComplex */
          0, 0,                        /* isLegacyPS */
          (initFlags & MPEGS_INIT_STATES_DECORRELATOR) ? 1 : 0);
      if (errCode) return MPS_NOTOK;
    }
  } /* !self->partiallyComplex */

  err = initM1andM2(self, (initFlags & MPEGS_INIT_STATES_M1M2) ? 1 : 0,
                    (initFlags & MPEGS_INIT_CONFIG) ? 1 : 0);
  if (err != MPS_OK) return err;

  /* Initialization of previous frame data */
  if (initFlags & MPEGS_INIT_STATES_PARAM) {
    for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
      /* reset icc diff data */
      for (k = 0; k < MAX_PARAMETER_SETS; k += 1) {
        for (j = 0; j < MAX_PARAMETER_BANDS; j += 1) {
          self->ottICCdiffidx[i][k][j] = 0;
        }
      }
    }
    /* Parameter Smoothing */
    /* robustness: init with one of the values of smgTimeTable[] = {64, 128,
       256, 512} to avoid division by zero in calcFilterCoeff__FDK() */
    self->smoothState->prevSmgTime = smgTimeTable[2]; /* == 256 */
    FDKmemclear(self->smoothState->prevSmgData,
                MAX_PARAMETER_BANDS * sizeof(UCHAR));
    FDKmemclear(self->smoothState->opdLeftState__FDK,
                MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
    FDKmemclear(self->smoothState->opdRightState__FDK,
                MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
  }

  self->prevTimeSlot = -1;
  self->curTimeSlot =
      MAX_TIME_SLOTS + 1; /* Initialize with a invalid value to trigger
                             concealment if first frame has no valid data. */
  self->curPs = 0;

  subbandTPInit(self->hStpDec);

bail:
  return err;
}

void SpatialDecChannelProperties(spatialDec *self,
                                 AUDIO_CHANNEL_TYPE channelType[],
                                 UCHAR channelIndices[],
                                 const FDK_channelMapDescr *const mapDescr) {
  if ((self == NULL) || (channelType == NULL) || (channelIndices == NULL) ||
      (mapDescr == NULL)) {
    return; /* no extern buffer to be filled */
  }

  if (self->numOutputChannelsAT !=
      treePropertyTable[self->treeConfig].numOutputChannels) {
    int ch;
    /* Declare all channels to be front channels: */
    for (ch = 0; ch < self->numOutputChannelsAT; ch += 1) {
      channelType[ch] = ACT_FRONT;
      channelIndices[ch] = ch;
    }
  } else {
    /* ISO/IEC FDIS 23003-1:2006(E), page 46, Table 40 bsTreeConfig */
    switch (self->treeConfig) {
      case TREE_212:
        channelType[0] = ACT_FRONT;
        channelIndices[0] = 0;
        channelType[1] = ACT_FRONT;
        channelIndices[1] = 1;
        break;
      default:;
    }
  }
}

/*******************************************************************************
 Functionname: FDK_SpatialDecClose
 *******************************************************************************

 Description:

 Arguments:

 Return:

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

void FDK_SpatialDecClose(spatialDec *self) {
  if (self) {
    int k;

    if (self->apDecor != NULL) {
      for (k = 0; k < self->createParams.maxNumDecorChannels; k++) {
        FDKdecorrelateClose(&(self->apDecor[k]));
      }
      FDK_FREE_MEMORY_1D(self->apDecor);
    }
    if (self->pDecorBufferCplx != NULL) {
      FDK_FREE_MEMORY_2D(self->pDecorBufferCplx);
    }

    subbandTPDestroy(&self->hStpDec);

    FDK_FREE_MEMORY_1D(self->reshapeBBEnvState);
    FDK_FREE_MEMORY_1D(self->smoothState);

    FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFdmx);
    FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFdmx);
    FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFres);
    FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFres);
    FDK_FREE_MEMORY_1D(self->hybridAnalysis);

    FDK_FREE_MEMORY_1D(self->hybridSynthesis);

    /* The time buffer is passed to the decoder from outside to avoid copying
     * (zero copy). */
    /* FDK_FREE_MEMORY_2D(self->timeOut__FDK); */

    FDK_FREE_MEMORY_2D(self->hybOutputImagWet__FDK);
    FDK_FREE_MEMORY_2D(self->hybOutputRealWet__FDK);

    FDK_FREE_MEMORY_2D(self->hybOutputImagDry__FDK);
    FDK_FREE_MEMORY_2D(self->hybOutputRealDry__FDK);

    FDK_FREE_MEMORY_2D(self->wImag__FDK);
    FDK_FREE_MEMORY_2D(self->wReal__FDK);

    if (self->createParams.bProcResidual) {
      int i;

      for (i = 0; i < self->createParams.maxNumResChannels; i++) {
        if (self->hybResidualImag__FDK != NULL)
          FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK[i]);
        if (self->hybResidualReal__FDK != NULL)
          FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK[i]);
        if (self->qmfResidualImag__FDK != NULL)
          FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualImag__FDK[i]);
        if (self->qmfResidualReal__FDK != NULL)
          FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualReal__FDK[i]);
      }

      FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK);
      FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK);

      FDK_FREE_MEMORY_1D(self->qmfResidualImag__FDK);
      FDK_FREE_MEMORY_1D(self->qmfResidualReal__FDK);

    } /* self->createParams.bProcResidual */

    FDK_FREE_MEMORY_2D(self->hybInputImag__FDK);
    FDK_FREE_MEMORY_2D(self->hybInputReal__FDK);

    FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputImag__FDK);
    FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputReal__FDK);

    FDK_FREE_MEMORY_3D(self->M2ImagPrev__FDK);

    FDK_FREE_MEMORY_3D(self->M2RealPrev__FDK);

    FDK_FREE_MEMORY_3D(self->M2Imag__FDK);

    FDK_FREE_MEMORY_3D(self->M2Real__FDK);

    FDK_FREE_MEMORY_1D(self->arbdmxAlphaPrev__FDK);
    FDK_FREE_MEMORY_1D(self->arbdmxAlpha__FDK);

    FDK_FREE_MEMORY_3D(self->arbdmxGain__FDK);

    FDK_FREE_MEMORY_3D(self->ottIPD__FDK);
    FDK_FREE_MEMORY_3D(self->ottICC__FDK);
    FDK_FREE_MEMORY_3D(self->ottCLD__FDK);

    /* Last parameters from prev frame */
    FDK_FREE_MEMORY_2D(self->ottCLDidxPrev);
    FDK_FREE_MEMORY_2D(self->ottICCidxPrev);
    FDK_FREE_MEMORY_3D(self->ottICCdiffidx);
    FDK_FREE_MEMORY_2D(self->ottIPDidxPrev);
    FDK_FREE_MEMORY_2D(self->arbdmxGainIdxPrev);

    FDK_FREE_MEMORY_2D(self->cmpOttCLDidxPrev);
    FDK_FREE_MEMORY_2D(self->cmpOttICCidxPrev);
    FDK_FREE_MEMORY_3D(self->outIdxData);
    FDK_FREE_MEMORY_2D(self->cmpOttIPDidxPrev);
    FDK_FREE_MEMORY_2D(self->cmpArbdmxGainIdxPrev);

    FDK_FREE_MEMORY_2D(self->smgData);
    FDK_FREE_MEMORY_1D(self->smgTime);

    FDK_FREE_MEMORY_1D(self->numOttBands);

    FDK_FREE_MEMORY_1D(self->param2hyb);

    FDK_FREE_MEMORY_1D(self);
  }

  return;
}

/**
 * \brief Apply Surround bypass buffer copies
 * \param self spatialDec handle
 * \param hybInputReal
 * \param hybInputImag
 * \param hybOutputReal
 * \param hybOutputImag
 * \param numInputChannels amount if input channels available in hybInputReal
 * and hybInputImag, which may differ from self->numInputChannels.
 */
static void SpatialDecApplyBypass(spatialDec *self, FIXP_DBL **hybInputReal,
                                  FIXP_DBL **hybInputImag,
                                  FIXP_DBL **hybOutputReal,
                                  FIXP_DBL **hybOutputImag,
                                  const int numInputChannels) {
  int complexHybBands;

  complexHybBands = self->hybridBands;

  {
    int ch;
    int rf = -1, lf = -1, cf = -1; /* Right Front, Left Front, Center Front */

    /* Determine output channel indices according to tree config */
    switch (self->treeConfig) {
      case TREE_212: /* 212  */
        lf = 0;
        rf = 1;
        break;
      default:;
    }

    /* Note: numInputChannels might not match the tree config ! */
    switch (numInputChannels) {
      case 1:
        if (cf > 0) {
          FDKmemcpy(hybOutputReal[cf], hybInputReal[0],
                    self->hybridBands * sizeof(FIXP_DBL));
          FDKmemcpy(hybOutputImag[cf], hybInputImag[0],
                    complexHybBands * sizeof(FIXP_DBL));
        } else {
          FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
                    self->hybridBands * sizeof(FIXP_DBL));
          FDKmemcpy(hybOutputReal[rf], hybInputReal[0],
                    self->hybridBands * sizeof(FIXP_DBL));
          FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
                    complexHybBands * sizeof(FIXP_DBL));
          FDKmemcpy(hybOutputImag[rf], hybInputImag[0],
                    complexHybBands * sizeof(FIXP_DBL));
        }
        break;
      case 2:
        FDK_ASSERT(lf != -1);
        FDK_ASSERT(rf != -1);
        FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
                  self->hybridBands * sizeof(FIXP_DBL));
        FDKmemcpy(hybOutputReal[rf], hybInputReal[1],
                  self->hybridBands * sizeof(FIXP_DBL));
        FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
                  complexHybBands * sizeof(FIXP_DBL));
        FDKmemcpy(hybOutputImag[rf], hybInputImag[1],
                  complexHybBands * sizeof(FIXP_DBL));
        break;
    }
    for (ch = 0; ch < self->numOutputChannelsAT; ch++) {
      if (ch == lf || ch == rf || ch == cf) {
        continue; /* Skip bypassed channels */
      }
      FDKmemclear(hybOutputReal[ch], self->hybridBands * sizeof(FIXP_DBL));
      FDKmemclear(hybOutputImag[ch], complexHybBands * sizeof(FIXP_DBL));
    }
  }
}

/*******************************************************************************
 Functionname: SpatialDecApplyParameterSets
 *******************************************************************************

 Description:

 Arguments:

 Return:

*******************************************************************************/
static SACDEC_ERROR SpatialDecApplyParameterSets(
    spatialDec *self, const SPATIAL_BS_FRAME *frame, SPATIALDEC_INPUT_MODE mode,
    PCM_MPS *inData,          /* Time domain input  */
    FIXP_DBL **qmfInDataReal, /* QMF domain data l/r */
    FIXP_DBL **qmfInDataImag, /* QMF domain data l/r */
    UINT nSamples, UINT controlFlags, int numInputChannels,
    const FDK_channelMapDescr *const mapDescr) {
  SACDEC_ERROR err = MPS_OK;

  FIXP_SGL alpha;

  int ts;
  int ch;
  int hyb;

  int prevSlot = self->prevTimeSlot;
  int ps = self->curPs;
  int ts_io = 0; /* i/o dependent slot */
  int bypassMode = (controlFlags & MPEGS_BYPASSMODE) ? 1 : 0;

  /* Bypass can be triggered by the upmixType, too. */
  bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);

  /*
   * Decode available slots
   */
  for (ts = self->curTimeSlot;
       ts <= fixMin(self->curTimeSlot + (int)nSamples / self->qmfBands - 1,
                    self->timeSlots - 1);
       ts++, ts_io++) {
    int currSlot = frame->paramSlot[ps];

    /*
     * Get new parameter set
     */
    if (ts == prevSlot + 1) {
      err = SpatialDecCalculateM1andM2(self, ps,
                                       frame); /* input: ottCLD, ottICC, ... */
      /* output: M1param(Real/Imag), M2(Real/Imag) */
      if (err != MPS_OK) {
        bypassMode = 1;
        if (self->errInt == MPS_OK) {
          /* store internal error befor it gets overwritten */
          self->errInt = err;
        }
        err = MPS_OK;
      }

      if ((ps == 0) && (self->bOverwriteM1M2prev != 0)) {
        /* copy matrix entries of M1/M2 of the first parameter set to the
           previous matrices (of the last frame). This avoids the interpolation
           of incompatible values. E.g. for residual bands the coefficients are
           calculated differently compared to non-residual bands.
         */
        SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
                                        /* output: M(1/2)param(Real/Imag)Prev */
        self->bOverwriteM1M2prev = 0;
      }

      SpatialDecSmoothM1andM2(
          self, frame,
          ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */
               /* output: M1param(Real/Imag), M2(Real/Imag) */
    }

    alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot));

    switch (mode) {
      case INPUTMODE_QMF_SBR:
        if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD)
          self->bShareDelayWithSBR = 0; /* We got no hybrid delay */
        else
          self->bShareDelayWithSBR = 1;
        SpatialDecFeedQMF(self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode,
                          self->qmfInputReal__FDK, self->qmfInputImag__FDK,
                          self->numInputChannels);
        break;
      case INPUTMODE_TIME:
        self->bShareDelayWithSBR = 0;
        SpatialDecQMFAnalysis(self, inData, ts_io, bypassMode,
                              self->qmfInputReal__FDK, self->qmfInputImag__FDK,
                              self->numInputChannels);
        break;
      default:
        break;
    }

    if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
        self->residualCoding) {
      int offset;
      ch = 1;

      offset = self->pQmfDomain->globalConf.nBandsSynthesis *
               self->pQmfDomain->globalConf.nQmfTimeSlots;

      {
        const PCM_MPS *inSamples =
            &inData[ts * self->pQmfDomain->globalConf.nBandsAnalysis];

        CalculateSpaceAnalysisQmf(
            &self->pQmfDomain->QmfDomainIn[ch].fb, inSamples + (ch * offset),
            self->qmfResidualReal__FDK[0][0], self->qmfResidualImag__FDK[0][0]);

        if (!isTwoChMode(self->upmixType) && !bypassMode) {
          int i;
          FIXP_DBL *RESTRICT self_qmfResidualReal__FDK_0_0 =
              &self->qmfResidualReal__FDK[0][0][0];
          FIXP_DBL *RESTRICT self_qmfResidualImag__FDK_0_0 =
              &self->qmfResidualImag__FDK[0][0][0];

          if ((self->pQmfDomain->globalConf.nBandsAnalysis == 24) &&
              !(self->stereoConfigIndex == 3)) {
            for (i = 0; i < self->qmfBands; i++) {
              self_qmfResidualReal__FDK_0_0[i] =
                  fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
                                           1 + self->sacInDataHeadroom - (1)),
                        self->clipProtectGain__FDK);
              self_qmfResidualImag__FDK_0_0[i] =
                  fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
                                           1 + self->sacInDataHeadroom - (1)),
                        self->clipProtectGain__FDK);
            }
          } else {
            for (i = 0; i < self->qmfBands; i++) {
              self_qmfResidualReal__FDK_0_0[i] =
                  fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
                                           self->sacInDataHeadroom - (1)),
                        self->clipProtectGain__FDK);
              self_qmfResidualImag__FDK_0_0[i] =
                  fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
                                           self->sacInDataHeadroom - (1)),
                        self->clipProtectGain__FDK);
            }
          }
        }
      }
    }

    SpatialDecHybridAnalysis(
        self, /* input: qmfInput(Real/Imag), qmfResidual(Real/Imag) */
        self->qmfInputReal__FDK, self->qmfInputImag__FDK,
        self->hybInputReal__FDK, self->hybInputImag__FDK, ts, numInputChannels);

    if (bypassMode) {
      SpatialDecApplyBypass(
          self, self->hybInputReal__FDK, /* input: hybInput(Real/Imag) */
          self->hybInputImag__FDK,
          self->hybOutputRealDry__FDK, /* output: hybOutput(Real/Imag)Dry */
          self->hybOutputImagDry__FDK, numInputChannels);
    } else /* !bypassMode */
    {
      FIXP_DBL *pxReal[MAX_NUM_XCHANNELS] = {NULL};
      FIXP_DBL *pxImag[MAX_NUM_XCHANNELS] = {NULL};

      SpatialDecCreateX(self,
                        self->hybInputReal__FDK, /* input: hybInput(Real/Imag),
                                                    hybResidual(Real/Imag) */
                        self->hybInputImag__FDK, pxReal, pxImag);

      {
        SpatialDecApplyM1_CreateW_Mode212(
            self, frame, pxReal, pxImag,
            self->wReal__FDK, /* output: w(Real/Imag) */
            self->wImag__FDK);
      }
      if (err != MPS_OK) goto bail;

      int applyM2Config = APPLY_M2_NONE;

      applyM2Config = APPLY_M2;
      if ((self->pConfigCurrent->syntaxFlags &
           (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
          (self->tempShapeConfig != 1) && (self->tempShapeConfig != 2)) {
        if (self->phaseCoding == 3)
          applyM2Config = APPLY_M2_MODE212_Res_PhaseCoding;
        else
          applyM2Config = APPLY_M2_MODE212;
      }

      switch (applyM2Config) {
        case APPLY_M2_MODE212: {
          err = SpatialDecApplyM2_Mode212(
              self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
              self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
        } break;
        case APPLY_M2_MODE212_Res_PhaseCoding:
          err = SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
              self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
              self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
          break;
        case APPLY_M2:
          err = SpatialDecApplyM2(
              self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
              self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK,
              self->hybOutputRealWet__FDK, self->hybOutputImagWet__FDK);
          break;
        default:
          err = MPS_APPLY_M2_ERROR;
          goto bail;
      }

      if (err != MPS_OK) goto bail;

      if ((self->tempShapeConfig == 2) && (!isTwoChMode(self->upmixType))) {
        SpatialDecReshapeBBEnv(self, frame,
                               ts); /* input: reshapeBBEnvState,
                                       hybOutput(Real/Imag)(Dry/Wet),
                                       hybInput(Real/Imag) */
      }                             /* output: hybOutput(Real/Imag)Dry */

      /* Merge parts of the dry and wet QMF buffers. */
      if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
        for (ch = 0; ch < self->numOutputChannels; ch++) {
          for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
            self->hybOutputRealDry__FDK[ch][hyb] =
                fAddSaturate(self->hybOutputRealDry__FDK[ch][hyb],
                             self->hybOutputRealWet__FDK[ch][hyb]);
            self->hybOutputImagDry__FDK[ch][hyb] =
                fAddSaturate(self->hybOutputImagDry__FDK[ch][hyb],
                             self->hybOutputImagWet__FDK[ch][hyb]);
          } /* loop hyb */
        }   /* loop ch */
        err = subbandTPApply(
            self, frame); /* input: hStpDec, hybOutput(Real/Imag)Dry/Wet */
                          /* output: hStpDec, hybOutput(Real/Imag)Dry */
        if (err != MPS_OK) goto bail;
      } /* (self->tempShapeConfig == 1) */
      else {
        /* The wet signal is added to the dry signal in applyM2 if GES and STP
         * are disabled */
        if ((self->tempShapeConfig == 1) || (self->tempShapeConfig == 2)) {
          int nHybBands;
          nHybBands = self->hybridBands;

          for (ch = 0; ch < self->numOutputChannels; ch++) {
            FIXP_DBL *RESTRICT pRealDry = self->hybOutputRealDry__FDK[ch];
            FIXP_DBL *RESTRICT pImagDry = self->hybOutputImagDry__FDK[ch];
            FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
            FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
            for (hyb = 0; hyb < nHybBands; hyb++) {
              pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
              pImagDry[hyb] = fAddSaturate(pImagDry[hyb], pImagWet[hyb]);
            } /* loop hyb */
            for (; hyb < self->hybridBands; hyb++) {
              pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
            } /* loop hyb */
          }   /* loop ch */
        } /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
      }   /* !self->tempShapeConfig == 1 */
    }     /*  !bypassMode */

    if (self->phaseCoding == 1) {
      /* only if bsPhaseCoding == 1 and bsResidualCoding == 0 */

      SpatialDecApplyPhase(
          self, alpha, (ts == currSlot) /* signal the last slot of the set */
      );
    }

    /*
     * Synthesis Filtering
     */

    err = SpatialDecSynthesis(
        self, ts_io,
        self->hybOutputRealDry__FDK, /* input: hybOutput(Real/Imag)Dry */
        self->hybOutputImagDry__FDK, self->timeOut__FDK, /* output: timeOut */
        numInputChannels, mapDescr);

    if (err != MPS_OK) goto bail;

    /*
     * Update parameter buffer
     */
    if (ts == currSlot) {
      SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
                                      /* output: M(1/2)param(Real/Imag)Prev */

      prevSlot = currSlot;
      ps++;
    } /* if (ts==currSlot) */

  } /* ts loop */

  /*
   * Save parameter states
   */
  self->prevTimeSlot = prevSlot;
  self->curTimeSlot = ts;
  self->curPs = ps;

bail:

  return err;
}

SACDEC_ERROR SpatialDecApplyFrame(
    spatialDec *self,
    SPATIAL_BS_FRAME *frame, /* parsed frame data to be applied */
    SPATIALDEC_INPUT_MODE inputMode, PCM_MPS *inData, /* Time domain input  */
    FIXP_DBL **qmfInDataReal,                         /* QMF domain data l/r */
    FIXP_DBL **qmfInDataImag,                         /* QMF domain data l/r */
    PCM_MPS *pcmOutBuf, /* MAX_OUTPUT_CHANNELS*MAX_TIME_SLOTS*NUM_QMF_BANDS] */
    UINT nSamples, UINT *pControlFlags, int numInputChannels,
    const FDK_channelMapDescr *const mapDescr) {
  SACDEC_ERROR err = MPS_OK;

  int fDecAndMapFrameData;
  int controlFlags;

  FDK_ASSERT(self != NULL);
  FDK_ASSERT(pControlFlags != NULL);
  FDK_ASSERT(pcmOutBuf != NULL);
  FDK_ASSERT(self->sacInDataHeadroom >= (1));

  self->errInt = err; /* Init internal error */

  controlFlags = *pControlFlags;

  if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
      (self->stereoConfigIndex > 1)) {
    numInputChannels =
        1; /* Do not count residual channel as input channel. It is handled
              seperately. */
  }

  /* Check if input amount of channels is consistent */
  if (numInputChannels != self->numInputChannels) {
    controlFlags |= MPEGS_CONCEAL;
    if (numInputChannels > self->createParams.maxNumInputChannels) {
      return MPS_INVALID_PARAMETER;
    }
  }

  self->timeOut__FDK = pcmOutBuf;

  /* Determine local function control flags */
  fDecAndMapFrameData = frame->newBsData;

  if (((fDecAndMapFrameData ==
        0) /* assures that conceal flag will not be set for blind mode */
       && (self->curTimeSlot + (int)nSamples / self->qmfBands >
           self->timeSlots)) ||
      (frame->numParameterSets ==
       0)) { /* New input samples but missing side info */
    fDecAndMapFrameData = 1;
    controlFlags |= MPEGS_CONCEAL;
  }

  if ((fDecAndMapFrameData == 0) &&
      (frame->paramSlot[fMax(0, frame->numParameterSets - 1)] !=
           (self->timeSlots - 1) ||
       self->curTimeSlot >
           frame->paramSlot[self->curPs])) { /* Detected faulty parameter slot
                                                data. */
    fDecAndMapFrameData = 1;
    controlFlags |= MPEGS_CONCEAL;
  }

  /* Update concealment state machine */
  SpatialDecConcealment_UpdateState(
      &self->concealInfo,
      (controlFlags & MPEGS_CONCEAL)
          ? 0
          : 1); /* convert from conceal flag to frame ok flag */

  if (fDecAndMapFrameData) {
    /* Reset spatial framing control vars */
    frame->newBsData = 0;
    self->prevTimeSlot = -1;
    self->curTimeSlot = 0;
    self->curPs = 0;

    if (controlFlags & MPEGS_CONCEAL) {
      /* Reset frame data to avoid misconfiguration. */
      SpatialDecClearFrameData(self, frame, &self->createParams);
    }

    {
      err = SpatialDecDecodeFrame(self, frame); /* input: ... */
      /* output: decodeAndMapFrameDATA */
    }

    if (err != MPS_OK) {
      /* Rescue strategy is to apply bypass mode in order
         to keep at least the downmix channels continuous. */
      controlFlags |= MPEGS_CONCEAL;
      if (self->errInt == MPS_OK) {
        /* store internal error befor it gets overwritten */
        self->errInt = err;
      }
    }
  }

  err = SpatialDecApplyParameterSets(
      self, frame, inputMode, inData, qmfInDataReal, qmfInDataImag, nSamples,
      controlFlags | ((err == MPS_OK) ? 0 : MPEGS_BYPASSMODE), numInputChannels,
      mapDescr);
  if (err != MPS_OK) {
    goto bail;
  }

bail:

  *pControlFlags = controlFlags;

  return err;
}
