Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten
      5 Forschung e.V. All rights reserved.
      6 
      7  1.    INTRODUCTION
      8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
      9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
     10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
     11 a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
     14 general perceptual audio codecs. AAC-ELD is considered the best-performing
     15 full-bandwidth communications codec by independent studies and is widely
     16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
     17 specifications.
     18 
     19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
     20 those of Fraunhofer) may be obtained through Via Licensing
     21 (www.vialicensing.com) or through the respective patent owners individually for
     22 the purpose of encoding or decoding bit streams in products that are compliant
     23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
     24 Android devices already license these patent claims through Via Licensing or
     25 directly from the patent owners, and therefore FDK AAC Codec software may
     26 already be covered under those patent licenses when it is used for those
     27 licensed purposes only.
     28 
     29 Commercially-licensed AAC software libraries, including floating-point versions
     30 with enhanced sound quality, are also available from Fraunhofer. Users are
     31 encouraged to check the Fraunhofer website for additional applications
     32 information and documentation.
     33 
     34 2.    COPYRIGHT LICENSE
     35 
     36 Redistribution and use in source and binary forms, with or without modification,
     37 are permitted without payment of copyright license fees provided that you
     38 satisfy the following conditions:
     39 
     40 You must retain the complete text of this software license in redistributions of
     41 the FDK AAC Codec or your modifications thereto in source code form.
     42 
     43 You must retain the complete text of this software license in the documentation
     44 and/or other materials provided with redistributions of the FDK AAC Codec or
     45 your modifications thereto in binary form. You must make available free of
     46 charge copies of the complete source code of the FDK AAC Codec and your
     47 modifications thereto to recipients of copies in binary form.
     48 
     49 The name of Fraunhofer may not be used to endorse or promote products derived
     50 from this library without prior written permission.
     51 
     52 You may not charge copyright license fees for anyone to use, copy or distribute
     53 the FDK AAC Codec software or your modifications thereto.
     54 
     55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
     56 that you changed the software and the date of any change. For modified versions
     57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
     58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
     59 AAC Codec Library for Android."
     60 
     61 3.    NO PATENT LICENSE
     62 
     63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
     64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
     65 Fraunhofer provides no warranty of patent non-infringement with respect to this
     66 software.
     67 
     68 You may use this FDK AAC Codec software or modifications thereto only for
     69 purposes that are authorized by appropriate patent licenses.
     70 
     71 4.    DISCLAIMER
     72 
     73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
     74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
     75 including but not limited to the implied warranties of merchantability and
     76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
     78 or consequential damages, including but not limited to procurement of substitute
     79 goods or services; loss of use, data, or profits, or business interruption,
     80 however caused and on any theory of liability, whether in contract, strict
     81 liability, or tort (including negligence), arising in any way out of the use of
     82 this software, even if advised of the possibility of such damage.
     83 
     84 5.    CONTACT INFORMATION
     85 
     86 Fraunhofer Institute for Integrated Circuits IIS
     87 Attention: Audio and Multimedia Departments - FDK AAC LL
     88 Am Wolfsmantel 33
     89 91058 Erlangen, Germany
     90 
     91 www.iis.fraunhofer.de/amm
     92 amm-info (at) iis.fraunhofer.de
     93 ----------------------------------------------------------------------------- */
     94 
     95 /*********************** MPEG surround decoder library *************************
     96 
     97    Author(s):
     98 
     99    Description: SAC Decoder Library
    100 
    101 *******************************************************************************/
    102 
    103 #include "sac_dec_errorcodes.h"
    104 #include "sac_dec.h"
    105 
    106 #include "sac_process.h"
    107 #include "sac_bitdec.h"
    108 #include "sac_smoothing.h"
    109 #include "sac_calcM1andM2.h"
    110 #include "sac_reshapeBBEnv.h"
    111 #include "sac_stp.h"
    112 #include "sac_rom.h"
    113 
    114 #include "FDK_decorrelate.h"
    115 
    116 #include "FDK_trigFcts.h"
    117 #include "FDK_matrixCalloc.h"
    118 
    119 /* static int pbStrideTable[] = {1, 2, 5, 28}; see sac_rom.cpp */
    120 
    121 enum {
    122   APPLY_M2_NONE = 0,    /* init value */
    123   APPLY_M2 = 1,         /* apply m2 fallback implementation */
    124   APPLY_M2_MODE212 = 2, /* apply m2 for 212 mode */
    125   APPLY_M2_MODE212_Res_PhaseCoding =
    126       3 /* apply m2 for 212 mode with residuals and phase coding */
    127 };
    128 
    129 /******************************************************************************************/
    130 /* function: FDK_SpatialDecInitDefaultSpatialSpecificConfig */
    131 /* output:   struct of type SPATIAL_SPECIFIC_CONFIG */
    132 /* input:    core coder audio object type */
    133 /* input:    nr of core channels */
    134 /* input:    sampling rate */
    135 /* input:    nr of time slots */
    136 /* input:    decoder level */
    137 /* input:    flag indicating upmix type blind */
    138 /*                                                                                        */
    139 /* returns:  error code */
    140 /******************************************************************************************/
    141 int FDK_SpatialDecInitDefaultSpatialSpecificConfig(
    142     SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
    143     AUDIO_OBJECT_TYPE coreCodec, int coreChannels, int samplingFreq,
    144     int nTimeSlots, int decoderLevel, int isBlind) {
    145   return SpatialDecDefaultSpecificConfig(pSpatialSpecificConfig, coreCodec,
    146                                          samplingFreq, nTimeSlots, decoderLevel,
    147                                          isBlind, coreChannels);
    148 }
    149 
    150 /******************************************************************************************/
    151 /* function: FDK_SpatialDecCompareSpatialSpecificConfigHeader */
    152 /* input:    2 pointers to a ssc */
    153 /*                                                                                        */
    154 /* output:   - */
    155 /* returns:  error code (0 = equal, <>0 unequal) */
    156 /******************************************************************************************/
    157 int FDK_SpatialDecCompareSpatialSpecificConfigHeader(
    158     SPATIAL_SPECIFIC_CONFIG *pSsc1, SPATIAL_SPECIFIC_CONFIG *pSsc2) {
    159   int result = MPS_OK;
    160 
    161   /* we assume: every bit must be equal */
    162   if (FDKmemcmp(pSsc1, pSsc2, sizeof(SPATIAL_SPECIFIC_CONFIG)) != 0) {
    163     result = MPS_UNEQUAL_SSC;
    164   }
    165   return result;
    166 }
    167 
    168 /*******************************************************************************
    169  Functionname: SpatialDecClearFrameData
    170  *******************************************************************************
    171 
    172  Description: Clear/Fake frame data to avoid misconfiguration and allow proper
    173               error concealment.
    174  Arguments:
    175  Input:       self (frame data)
    176  Output:      No return value.
    177 
    178 *******************************************************************************/
    179 static void SpatialDecClearFrameData(
    180     spatialDec *self, /* Shall be removed */
    181     SPATIAL_BS_FRAME *bsFrame, const SACDEC_CREATION_PARAMS *const setup) {
    182   int i;
    183 
    184   FDK_ASSERT(self != NULL);
    185   FDK_ASSERT(bsFrame != NULL);
    186   FDK_ASSERT(setup != NULL);
    187 
    188   /* do not apply shaping tools (GES or STP) */
    189   for (i = 0; i < setup->maxNumOutputChannels;
    190        i += 1) { /* MAX_OUTPUT_CHANNELS */
    191     bsFrame->tempShapeEnableChannelSTP[i] = 0;
    192     bsFrame->tempShapeEnableChannelGES[i] = 0;
    193   }
    194 
    195   bsFrame->TsdData->bsTsdEnable = 0;
    196 
    197   /* use only 1 parameter set at the end of the frame */
    198   bsFrame->numParameterSets = 1;
    199   bsFrame->paramSlot[0] = self->timeSlots - 1;
    200 
    201   /* parameter smoothing tool set to off */
    202   bsFrame->bsSmoothMode[0] = 0;
    203 
    204   /* reset residual data */
    205   {
    206     int resQmfBands, resTimeSlots = (1);
    207 
    208     resQmfBands = setup->maxNumQmfBands;
    209 
    210     for (i = 0; i < setup->bProcResidual
    211                     ? fMin(setup->maxNumResChannels,
    212                            setup->maxNumOttBoxes + setup->maxNumInputChannels)
    213                     : 0;
    214          i += 1) {
    215       for (int j = 0; j < resTimeSlots; j += 1) {
    216         for (int k = 0; k < resQmfBands; k += 1) {
    217           self->qmfResidualReal__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
    218           self->qmfResidualImag__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
    219         }
    220       }
    221     }
    222   }
    223 
    224   return;
    225 }
    226 
    227 /*******************************************************************************
    228  Functionname: FDK_SpatialDecOpen
    229  *******************************************************************************
    230 
    231  Description:
    232 
    233  Arguments:
    234 
    235  Return:
    236 
    237 *******************************************************************************/
    238 spatialDec *FDK_SpatialDecOpen(const SPATIAL_DEC_CONFIG *config,
    239                                int stereoConfigIndex) {
    240   int i;
    241   int lfSize, hfSize;
    242   spatialDec *self = NULL;
    243   SACDEC_CREATION_PARAMS setup;
    244 
    245   switch (config->decoderLevel) {
    246     case DECODER_LEVEL_0: /* 212 maxNumOutputChannels== 2 */
    247       setup.maxNumInputChannels = 1;
    248       setup.maxNumOutputChannels = 2;
    249       setup.maxNumQmfBands = 64;
    250       setup.maxNumXChannels = 2;
    251       setup.maxNumVChannels = 2;
    252       setup.maxNumDecorChannels = 1;
    253       setup.bProcResidual = 1;
    254       setup.maxNumResidualChannels = 0;
    255       setup.maxNumOttBoxes = 1;
    256       setup.maxNumParams = setup.maxNumInputChannels + setup.maxNumOttBoxes;
    257       break;
    258     default:
    259       return NULL;
    260   }
    261 
    262   setup.maxNumResChannels = 1;
    263 
    264   {
    265     switch (config->maxNumOutputChannels) {
    266       case OUTPUT_CHANNELS_2_0:
    267         setup.maxNumOutputChannels = fMin(setup.maxNumOutputChannels, 2);
    268         break;
    269       case OUTPUT_CHANNELS_DEFAULT:
    270       default:
    271         break;
    272     }
    273   }
    274 
    275   setup.maxNumHybridBands = SacGetHybridSubbands(setup.maxNumQmfBands);
    276 
    277   switch (config->decoderMode) {
    278     case EXT_HQ_ONLY:
    279       setup.maxNumCmplxQmfBands = setup.maxNumQmfBands;
    280       setup.maxNumCmplxHybBands = setup.maxNumHybridBands;
    281       break;
    282     default:
    283       setup.maxNumCmplxQmfBands = fixMax(PC_NUM_BANDS, setup.maxNumQmfBands);
    284       setup.maxNumCmplxHybBands =
    285           fixMax(PC_NUM_HYB_BANDS, setup.maxNumHybridBands);
    286       break;
    287   } /* switch config->decoderMode */
    288 
    289   FDK_ALLOCATE_MEMORY_1D_INT(self, 1, spatialDec, SECT_DATA_L2)
    290 
    291   self->createParams = setup;
    292 
    293   FDK_ALLOCATE_MEMORY_1D(self->param2hyb, MAX_PARAMETER_BANDS + 1, int)
    294 
    295   FDK_ALLOCATE_MEMORY_1D(self->numOttBands, setup.maxNumOttBoxes, int)
    296 
    297   /* allocate arrays */
    298 
    299   FDK_ALLOCATE_MEMORY_1D(self->smgTime, MAX_PARAMETER_SETS, int)
    300   FDK_ALLOCATE_MEMORY_2D(self->smgData, MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS,
    301                          UCHAR)
    302 
    303   FDK_ALLOCATE_MEMORY_3D(self->ottCLD__FDK, setup.maxNumOttBoxes,
    304                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
    305   FDK_ALLOCATE_MEMORY_3D(self->ottICC__FDK, setup.maxNumOttBoxes,
    306                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
    307   FDK_ALLOCATE_MEMORY_3D(self->ottIPD__FDK, setup.maxNumOttBoxes,
    308                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
    309 
    310   /* Last parameters from prev frame */
    311   FDK_ALLOCATE_MEMORY_2D(self->ottCLDidxPrev, setup.maxNumOttBoxes,
    312                          MAX_PARAMETER_BANDS, SCHAR)
    313   FDK_ALLOCATE_MEMORY_2D(self->ottICCidxPrev, setup.maxNumOttBoxes,
    314                          MAX_PARAMETER_BANDS, SCHAR)
    315   FDK_ALLOCATE_MEMORY_3D(self->ottICCdiffidx, setup.maxNumOttBoxes,
    316                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
    317   FDK_ALLOCATE_MEMORY_2D(self->ottIPDidxPrev, setup.maxNumOttBoxes,
    318                          MAX_PARAMETER_BANDS, SCHAR)
    319   FDK_ALLOCATE_MEMORY_2D(self->arbdmxGainIdxPrev, setup.maxNumInputChannels,
    320                          MAX_PARAMETER_BANDS, SCHAR)
    321   FDK_ALLOCATE_MEMORY_2D(self->cmpOttCLDidxPrev, setup.maxNumOttBoxes,
    322                          MAX_PARAMETER_BANDS, SCHAR)
    323   FDK_ALLOCATE_MEMORY_2D(self->cmpOttICCidxPrev, setup.maxNumOttBoxes,
    324                          MAX_PARAMETER_BANDS, SCHAR)
    325   FDK_ALLOCATE_MEMORY_3D(self->outIdxData, setup.maxNumOttBoxes,
    326                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
    327 
    328   FDK_ALLOCATE_MEMORY_3D(self->arbdmxGain__FDK, setup.maxNumInputChannels,
    329                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
    330   FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlpha__FDK, setup.maxNumInputChannels,
    331                          FIXP_DBL)
    332   FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlphaPrev__FDK, setup.maxNumInputChannels,
    333                          FIXP_DBL)
    334   FDK_ALLOCATE_MEMORY_2D(self->cmpArbdmxGainIdxPrev, setup.maxNumInputChannels,
    335                          MAX_PARAMETER_BANDS, SCHAR)
    336 
    337   FDK_ALLOCATE_MEMORY_2D(self->cmpOttIPDidxPrev, setup.maxNumOttBoxes,
    338                          MAX_PARAMETER_BANDS, SCHAR)
    339 
    340   FDK_ALLOCATE_MEMORY_3D_INT(self->M2Real__FDK, setup.maxNumOutputChannels,
    341                              setup.maxNumVChannels, MAX_PARAMETER_BANDS,
    342                              FIXP_DBL, SECT_DATA_L2)
    343   FDK_ALLOCATE_MEMORY_3D(self->M2Imag__FDK, setup.maxNumOutputChannels,
    344                          setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)
    345 
    346   FDK_ALLOCATE_MEMORY_3D_INT(self->M2RealPrev__FDK, setup.maxNumOutputChannels,
    347                              setup.maxNumVChannels, MAX_PARAMETER_BANDS,
    348                              FIXP_DBL, SECT_DATA_L2)
    349   FDK_ALLOCATE_MEMORY_3D(self->M2ImagPrev__FDK, setup.maxNumOutputChannels,
    350                          setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)
    351 
    352   FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
    353       self->qmfInputReal__FDK, setup.maxNumInputChannels, setup.maxNumQmfBands,
    354       FIXP_DBL, SECT_DATA_L2)
    355   FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
    356       self->qmfInputImag__FDK, setup.maxNumInputChannels,
    357       setup.maxNumCmplxQmfBands, FIXP_DBL, SECT_DATA_L2)
    358 
    359   FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputReal__FDK, setup.maxNumInputChannels,
    360                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
    361   FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputImag__FDK, setup.maxNumInputChannels,
    362                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
    363 
    364   if (setup.bProcResidual) {
    365     FDK_ALLOCATE_MEMORY_1D(self->qmfResidualReal__FDK, setup.maxNumResChannels,
    366                            FIXP_DBL **)
    367     FDK_ALLOCATE_MEMORY_1D(self->qmfResidualImag__FDK, setup.maxNumResChannels,
    368                            FIXP_DBL **)
    369 
    370     FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK, setup.maxNumResChannels,
    371                            FIXP_DBL *)
    372     FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK, setup.maxNumResChannels,
    373                            FIXP_DBL *)
    374 
    375     for (i = 0; i < setup.maxNumResChannels; i++) {
    376       int resQmfBands = (config->decoderMode == EXT_LP_ONLY)
    377                             ? PC_NUM_BANDS
    378                             : setup.maxNumQmfBands;
    379       int resHybBands = (config->decoderMode == EXT_LP_ONLY)
    380                             ? PC_NUM_HYB_BANDS
    381                             : setup.maxNumHybridBands;
    382       /* Alignment is needed for USAC residuals because QMF analysis directly
    383        * writes to this buffer. */
    384       FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualReal__FDK[i], (1),
    385                                          resQmfBands, FIXP_DBL, SECT_DATA_L1)
    386       FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualImag__FDK[i], (1),
    387                                          resQmfBands, FIXP_DBL, SECT_DATA_L1)
    388 
    389       FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK[i],
    390                              setup.maxNumHybridBands, FIXP_DBL)
    391       FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK[i], resHybBands,
    392                              FIXP_DBL)
    393     }
    394   } /* if (setup.bProcResidual) */
    395 
    396   FDK_ALLOCATE_MEMORY_2D_INT(self->wReal__FDK, setup.maxNumVChannels,
    397                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
    398   FDK_ALLOCATE_MEMORY_2D_INT(self->wImag__FDK, setup.maxNumVChannels,
    399                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
    400 
    401   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealDry__FDK,
    402                              setup.maxNumOutputChannels,
    403                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
    404   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagDry__FDK,
    405                              setup.maxNumOutputChannels,
    406                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
    407 
    408   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealWet__FDK,
    409                              setup.maxNumOutputChannels,
    410                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
    411   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagWet__FDK,
    412                              setup.maxNumOutputChannels,
    413                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
    414 
    415   FDK_ALLOCATE_MEMORY_1D(self->hybridSynthesis, setup.maxNumOutputChannels,
    416                          FDK_SYN_HYB_FILTER)
    417 
    418   FDK_ALLOCATE_MEMORY_1D(
    419       self->hybridAnalysis,
    420       setup.bProcResidual ? setup.maxNumInputChannels + setup.maxNumResChannels
    421                           : setup.maxNumInputChannels,
    422       FDK_ANA_HYB_FILTER)
    423 
    424   lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
    425   {
    426     hfSize =
    427         BUFFER_LEN_HF * ((setup.maxNumQmfBands - MAX_QMF_BANDS_TO_HYBRID) +
    428                          (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));
    429   }
    430 
    431   FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFdmx,
    432                              setup.maxNumInputChannels, lfSize, FIXP_DBL,
    433                              SECT_DATA_L2) {
    434     FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFdmx,
    435                            setup.maxNumInputChannels, hfSize, FIXP_DBL)
    436   }
    437 
    438   for (i = 0; i < setup.maxNumInputChannels; i++) {
    439     FIXP_DBL *pHybridAnaStatesHFdmx;
    440 
    441     pHybridAnaStatesHFdmx = self->pHybridAnaStatesHFdmx[i];
    442 
    443     FDKhybridAnalysisOpen(&self->hybridAnalysis[i],
    444                           self->pHybridAnaStatesLFdmx[i],
    445                           lfSize * sizeof(FIXP_DBL), pHybridAnaStatesHFdmx,
    446                           hfSize * sizeof(FIXP_DBL));
    447   }
    448   if (setup.bProcResidual) {
    449     lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
    450     hfSize = BUFFER_LEN_HF *
    451              ((((config->decoderMode == EXT_LP_ONLY) ? PC_NUM_BANDS
    452                                                      : setup.maxNumQmfBands) -
    453                MAX_QMF_BANDS_TO_HYBRID) +
    454               (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));
    455 
    456     FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFres,
    457                                setup.maxNumResChannels, lfSize, FIXP_DBL,
    458                                SECT_DATA_L2)
    459     FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFres, setup.maxNumResChannels,
    460                            hfSize, FIXP_DBL)
    461 
    462     for (i = setup.maxNumInputChannels;
    463          i < (setup.maxNumInputChannels + setup.maxNumResChannels); i++) {
    464       FDKhybridAnalysisOpen(
    465           &self->hybridAnalysis[i],
    466           self->pHybridAnaStatesLFres[i - setup.maxNumInputChannels],
    467           lfSize * sizeof(FIXP_DBL),
    468           self->pHybridAnaStatesHFres[i - setup.maxNumInputChannels],
    469           hfSize * sizeof(FIXP_DBL));
    470     }
    471   }
    472 
    473   FDK_ALLOCATE_MEMORY_1D(self->smoothState, 1, SMOOTHING_STATE)
    474   FDK_ALLOCATE_MEMORY_1D(self->reshapeBBEnvState, 1, RESHAPE_BBENV_STATE)
    475 
    476   FDK_ALLOCATE_MEMORY_1D(self->apDecor, setup.maxNumDecorChannels, DECORR_DEC)
    477   FDK_ALLOCATE_MEMORY_2D_INT(self->pDecorBufferCplx, setup.maxNumDecorChannels,
    478                              (2 * ((825) + (373))), FIXP_DBL, SECT_DATA_L2)
    479 
    480   for (i = 0; i < setup.maxNumDecorChannels; i++) {
    481     if (FDKdecorrelateOpen(&self->apDecor[i], self->pDecorBufferCplx[i],
    482                            (2 * ((825) + (373))))) {
    483       goto bail;
    484     }
    485   }
    486 
    487   if (subbandTPCreate(&self->hStpDec) != MPS_OK) {
    488     goto bail;
    489   }
    490 
    491   /* save general decoder configuration */
    492   self->decoderLevel = config->decoderLevel;
    493   self->decoderMode = config->decoderMode;
    494   self->binauralMode = config->binauralMode;
    495 
    496   /* preinitialize configuration */
    497   self->partiallyComplex = (config->decoderMode != EXT_HQ_ONLY) ? 1 : 0;
    498 
    499   /* Set to default state */
    500   SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_ALL);
    501 
    502   /* Everything is fine so return the handle */
    503   return self;
    504 
    505 bail:
    506   /* Collector for all errors.
    507      Deallocate all memory and return a invalid handle. */
    508   FDK_SpatialDecClose(self);
    509 
    510   return NULL;
    511 }
    512 
    513 /*******************************************************************************
    514  Functionname: isValidConfig
    515  *******************************************************************************
    516 
    517  Description: Validate if configuration is supported in present instance
    518 
    519  Arguments:
    520 
    521  Return: 1: all okay
    522          0: configuration not supported
    523 *******************************************************************************/
    524 static int isValidConfig(spatialDec const *const self,
    525                          const SPATIAL_DEC_UPMIX_TYPE upmixType,
    526                          SPATIALDEC_PARAM const *const pUserParams,
    527                          const AUDIO_OBJECT_TYPE coreAot) {
    528   UPMIXTYPE nUpmixType;
    529 
    530   FDK_ASSERT(self != NULL);
    531   FDK_ASSERT(pUserParams != NULL);
    532 
    533   nUpmixType = (UPMIXTYPE)upmixType;
    534 
    535   switch (nUpmixType) {
    536     case UPMIXTYPE_BYPASS: /* UPMIX_TYPE_BYPASS */
    537       break;
    538     case UPMIXTYPE_NORMAL: /* UPMIX_TYPE_NORMAL */
    539       break;
    540     default:
    541       return 0; /* unsupported upmixType */
    542   }
    543 
    544   return 1; /* upmixType supported */
    545 }
    546 
    547 static SACDEC_ERROR CheckLevelTreeUpmixType(
    548     const SACDEC_CREATION_PARAMS *const pCreateParams,
    549     const SPATIAL_SPECIFIC_CONFIG *const pSsc, const int decoderLevel,
    550     const UPMIXTYPE upmixType) {
    551   SACDEC_ERROR err = MPS_OK;
    552   int nOutputChannels, treeConfig;
    553 
    554   FDK_ASSERT(pCreateParams != NULL);
    555   FDK_ASSERT(pSsc != NULL);
    556 
    557   treeConfig = pSsc->treeConfig;
    558 
    559   switch (decoderLevel) {
    560     case 0: {
    561       if (treeConfig != SPATIALDEC_MODE_RSVD7) {
    562         err = MPS_INVALID_TREECONFIG;
    563         goto bail;
    564       }
    565       break;
    566     }
    567     default:
    568       err = MPS_INVALID_PARAMETER /* MPS_UNIMPLEMENTED */;
    569       goto bail;
    570   }
    571 
    572   switch (upmixType) {
    573     case UPMIXTYPE_BYPASS:
    574       nOutputChannels = pSsc->nInputChannels;
    575       break;
    576     default:
    577       nOutputChannels = pSsc->nOutputChannels;
    578       break;
    579   }
    580 
    581   /* Is sufficient memory allocated. */
    582   if ((pSsc->nInputChannels > pCreateParams->maxNumInputChannels) ||
    583       (nOutputChannels > pCreateParams->maxNumOutputChannels) ||
    584       (pSsc->nOttBoxes > pCreateParams->maxNumOttBoxes)) {
    585     err = MPS_INVALID_PARAMETER;
    586   }
    587 
    588 bail:
    589   return err;
    590 }
    591 
    592 void SpatialDecInitParserContext(spatialDec *self) {
    593   int i, j;
    594 
    595   for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
    596     for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
    597       self->ottCLDidxPrev[i][j] = 0;
    598       self->ottICCidxPrev[i][j] = 0;
    599       self->cmpOttCLDidxPrev[i][j] = 0;
    600       self->cmpOttICCidxPrev[i][j] = 0;
    601     }
    602   }
    603   for (i = 0; i < self->createParams.maxNumInputChannels; i++) {
    604     for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
    605       self->arbdmxGainIdxPrev[i][j] = 0;
    606       self->cmpArbdmxGainIdxPrev[i][j] = 0;
    607     }
    608   }
    609 }
    610 
    611 /*******************************************************************************
    612  Functionname: FDK_SpatialDecInit
    613  *******************************************************************************
    614 
    615  Description:
    616 
    617  Arguments:
    618 
    619  Return:
    620 
    621 *******************************************************************************/
    622 
    623 SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
    624                                 SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
    625                                 int nQmfBands,
    626                                 SPATIAL_DEC_UPMIX_TYPE const upmixType,
    627                                 SPATIALDEC_PARAM *pUserParams, UINT initFlags) {
    628   SACDEC_ERROR err = MPS_OK;
    629   int nCh, i, j, k;
    630   int maxQmfBands;
    631   int bypassMode = 0;
    632 
    633   self->useFDreverb = 0;
    634 
    635   /* check configuration parameter */
    636   if (!isValidConfig(self, upmixType, pUserParams,
    637                      pSpatialSpecificConfig->coreCodec)) {
    638     return MPS_INVALID_PARAMETER;
    639   }
    640 
    641   /* check tree configuration */
    642   err = CheckLevelTreeUpmixType(&self->createParams, pSpatialSpecificConfig,
    643                                 self->decoderLevel, (UPMIXTYPE)upmixType);
    644   if (err != MPS_OK) {
    645     goto bail;
    646   }
    647 
    648   /* Store and update instance after all checks passed successfully: */
    649   self->upmixType = (UPMIXTYPE)upmixType;
    650 
    651   if (initFlags & MPEGS_INIT_PARAMS_ERROR_CONCEALMENT) { /* At least one error
    652                                                             concealment
    653                                                             parameter changed */
    654     err = SpatialDecConcealment_SetParam(
    655         &self->concealInfo, SAC_DEC_CONCEAL_METHOD, pUserParams->concealMethod);
    656     if (err != MPS_OK) {
    657       goto bail;
    658     }
    659     err = SpatialDecConcealment_SetParam(&self->concealInfo,
    660                                          SAC_DEC_CONCEAL_NUM_KEEP_FRAMES,
    661                                          pUserParams->concealNumKeepFrames);
    662     if (err != MPS_OK) {
    663       goto bail;
    664     }
    665     err = SpatialDecConcealment_SetParam(
    666         &self->concealInfo, SAC_DEC_CONCEAL_FADE_OUT_SLOPE_LENGTH,
    667         pUserParams->concealFadeOutSlopeLength);
    668     if (err != MPS_OK) {
    669       goto bail;
    670     }
    671     err = SpatialDecConcealment_SetParam(&self->concealInfo,
    672                                          SAC_DEC_CONCEAL_FADE_IN_SLOPE_LENGTH,
    673                                          pUserParams->concealFadeInSlopeLength);
    674     if (err != MPS_OK) {
    675       goto bail;
    676     }
    677     err = SpatialDecConcealment_SetParam(&self->concealInfo,
    678                                          SAC_DEC_CONCEAL_NUM_RELEASE_FRAMES,
    679                                          pUserParams->concealNumReleaseFrames);
    680     if (err != MPS_OK) {
    681       goto bail;
    682     }
    683   }
    684 
    685   if (initFlags &
    686       MPEGS_INIT_STATES_ERROR_CONCEALMENT) { /* Set to default state */
    687     SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_STATE);
    688   }
    689 
    690   /* determine bypass mode */
    691   bypassMode |= pUserParams->bypassMode;
    692   bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);
    693 
    694   /* static decoder scale depends on number of qmf bands */
    695   switch (nQmfBands) {
    696     case 16:
    697     case 24:
    698     case 32:
    699       self->staticDecScale = 21;
    700       break;
    701     case 64:
    702       self->staticDecScale = 22;
    703       break;
    704     default:
    705       return MPS_INVALID_PARAMETER;
    706   }
    707 
    708   self->numParameterSetsPrev = 1;
    709 
    710   self->qmfBands = nQmfBands;
    711   /* self->hybridBands will be updated in SpatialDecDecodeHeader() below. */
    712 
    713   self->bShareDelayWithSBR = 0;
    714 
    715   err = SpatialDecDecodeHeader(self, pSpatialSpecificConfig);
    716   if (err != MPS_OK) {
    717     goto bail;
    718   }
    719 
    720   self->stereoConfigIndex = pSpatialSpecificConfig->stereoConfigIndex;
    721 
    722   if (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) {
    723     self->qmfInputDelayBufPos = 0;
    724     self->pc_filterdelay = 1; /* Division by 0 not possible */
    725   }
    726 
    727   maxQmfBands = self->qmfBands;
    728 
    729   /* init residual decoder */
    730 
    731   /* init tonality smoothing */
    732   if (initFlags & MPEGS_INIT_STATES_PARAM) {
    733     initParameterSmoothing(self);
    734   }
    735 
    736   /* init GES */
    737   initBBEnv(self, (initFlags & MPEGS_INIT_STATES_GES) ? 1 : 0);
    738 
    739   /* Clip protection is applied only for normal processing. */
    740   if (!isTwoChMode(self->upmixType) && !bypassMode) {
    741     self->staticDecScale += self->clipProtectGainSF__FDK;
    742   }
    743 
    744   {
    745     UINT flags = 0;
    746     INT initStatesFlag = (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) ? 1 : 0;
    747     INT useLdFilter =
    748         (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) ? 1 : 0;
    749 
    750     flags = self->pQmfDomain->globalConf.flags_requested;
    751     flags &= (~(UINT)QMF_FLAG_LP);
    752 
    753     if (initStatesFlag)
    754       flags &= ~QMF_FLAG_KEEP_STATES;
    755     else
    756       flags |= QMF_FLAG_KEEP_STATES;
    757 
    758     if (useLdFilter)
    759       flags |= QMF_FLAG_MPSLDFB;
    760     else
    761       flags &= ~QMF_FLAG_MPSLDFB;
    762 
    763     self->pQmfDomain->globalConf.flags_requested = flags;
    764     FDK_QmfDomain_Configure(self->pQmfDomain);
    765 
    766     /* output scaling */
    767     for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
    768       int outputScale = 0, outputGain_e = 0, scale = 0;
    769       FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);
    770 
    771       if (!isTwoChMode(self->upmixType) && !bypassMode) {
    772         outputScale +=
    773             self->clipProtectGainSF__FDK; /* consider clip protection scaling at
    774                                              synthesis qmf */
    775       }
    776 
    777       scale = outputScale;
    778 
    779       qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
    780       qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
    781                        outputGain_e);
    782     }
    783   }
    784 
    785   for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
    786     FDKhybridSynthesisInit(&self->hybridSynthesis[nCh], THREE_TO_TEN,
    787                            self->qmfBands, maxQmfBands);
    788   }
    789 
    790   /* for input, residual channels and arbitrary down-mix residual channels */
    791   for (nCh = 0; nCh < self->createParams.maxNumInputChannels; nCh++) {
    792     FDKhybridAnalysisInit(
    793         &self->hybridAnalysis[nCh], THREE_TO_TEN, self->qmfBands, maxQmfBands,
    794         (initFlags & MPEGS_INIT_STATES_ANA_HYB_FILTER) ? 1 : 0);
    795   }
    796   for (; nCh < (self->createParams.bProcResidual
    797                     ? (self->createParams.maxNumInputChannels +
    798                        self->createParams.maxNumResChannels)
    799                     : self->createParams.maxNumInputChannels);
    800        nCh++) {
    801     FDKhybridAnalysisInit(&self->hybridAnalysis[nCh], THREE_TO_TEN, maxQmfBands,
    802                           maxQmfBands, 0);
    803   }
    804 
    805   {
    806     for (k = 0; k < self->numDecorSignals; k++) {
    807       int errCode, idec;
    808       FDK_DECORR_TYPE decorrType = DECORR_PS;
    809       decorrType = DECORR_LD;
    810       if (self->pConfigCurrent->syntaxFlags &
    811           (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) {
    812         decorrType =
    813             ((self->treeConfig == TREE_212) && (self->decorrType == DECORR_PS))
    814                 ? DECORR_PS
    815                 : DECORR_USAC;
    816       }
    817       {
    818         idec = k;
    819         if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
    820           if (self->treeConfig == TREE_212 && k == 0) {
    821             idec = 2;
    822           }
    823         }
    824       }
    825       errCode = FDKdecorrelateInit(
    826           &self->apDecor[k], self->hybridBands, decorrType, DUCKER_AUTOMATIC,
    827           self->decorrConfig, idec, 0, /* self->partiallyComplex */
    828           0, 0,                        /* isLegacyPS */
    829           (initFlags & MPEGS_INIT_STATES_DECORRELATOR) ? 1 : 0);
    830       if (errCode) return MPS_NOTOK;
    831     }
    832   } /* !self->partiallyComplex */
    833 
    834   err = initM1andM2(self, (initFlags & MPEGS_INIT_STATES_M1M2) ? 1 : 0,
    835                     (initFlags & MPEGS_INIT_CONFIG) ? 1 : 0);
    836   if (err != MPS_OK) return err;
    837 
    838   /* Initialization of previous frame data */
    839   if (initFlags & MPEGS_INIT_STATES_PARAM) {
    840     for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
    841       /* reset icc diff data */
    842       for (k = 0; k < MAX_PARAMETER_SETS; k += 1) {
    843         for (j = 0; j < MAX_PARAMETER_BANDS; j += 1) {
    844           self->ottICCdiffidx[i][k][j] = 0;
    845         }
    846       }
    847     }
    848     /* Parameter Smoothing */
    849     /* robustness: init with one of the values of smgTimeTable[] = {64, 128,
    850        256, 512} to avoid division by zero in calcFilterCoeff__FDK() */
    851     self->smoothState->prevSmgTime = smgTimeTable[2]; /* == 256 */
    852     FDKmemclear(self->smoothState->prevSmgData,
    853                 MAX_PARAMETER_BANDS * sizeof(UCHAR));
    854     FDKmemclear(self->smoothState->opdLeftState__FDK,
    855                 MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
    856     FDKmemclear(self->smoothState->opdRightState__FDK,
    857                 MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
    858   }
    859 
    860   self->prevTimeSlot = -1;
    861   self->curTimeSlot =
    862       MAX_TIME_SLOTS + 1; /* Initialize with a invalid value to trigger
    863                              concealment if first frame has no valid data. */
    864   self->curPs = 0;
    865 
    866   subbandTPInit(self->hStpDec);
    867 
    868 bail:
    869   return err;
    870 }
    871 
    872 void SpatialDecChannelProperties(spatialDec *self,
    873                                  AUDIO_CHANNEL_TYPE channelType[],
    874                                  UCHAR channelIndices[],
    875                                  const FDK_channelMapDescr *const mapDescr) {
    876   if ((self == NULL) || (channelType == NULL) || (channelIndices == NULL) ||
    877       (mapDescr == NULL)) {
    878     return; /* no extern buffer to be filled */
    879   }
    880 
    881   if (self->numOutputChannelsAT !=
    882       treePropertyTable[self->treeConfig].numOutputChannels) {
    883     int ch;
    884     /* Declare all channels to be front channels: */
    885     for (ch = 0; ch < self->numOutputChannelsAT; ch += 1) {
    886       channelType[ch] = ACT_FRONT;
    887       channelIndices[ch] = ch;
    888     }
    889   } else {
    890     /* ISO/IEC FDIS 23003-1:2006(E), page 46, Table 40 bsTreeConfig */
    891     switch (self->treeConfig) {
    892       case TREE_212:
    893         channelType[0] = ACT_FRONT;
    894         channelIndices[0] = 0;
    895         channelType[1] = ACT_FRONT;
    896         channelIndices[1] = 1;
    897         break;
    898       default:;
    899     }
    900   }
    901 }
    902 
    903 /*******************************************************************************
    904  Functionname: FDK_SpatialDecClose
    905  *******************************************************************************
    906 
    907  Description:
    908 
    909  Arguments:
    910 
    911  Return:
    912 
    913 *******************************************************************************/
    914 
    915 void FDK_SpatialDecClose(spatialDec *self) {
    916   if (self) {
    917     int k;
    918 
    919     if (self->apDecor != NULL) {
    920       for (k = 0; k < self->createParams.maxNumDecorChannels; k++) {
    921         FDKdecorrelateClose(&(self->apDecor[k]));
    922       }
    923       FDK_FREE_MEMORY_1D(self->apDecor);
    924     }
    925     if (self->pDecorBufferCplx != NULL) {
    926       FDK_FREE_MEMORY_2D(self->pDecorBufferCplx);
    927     }
    928 
    929     subbandTPDestroy(&self->hStpDec);
    930 
    931     FDK_FREE_MEMORY_1D(self->reshapeBBEnvState);
    932     FDK_FREE_MEMORY_1D(self->smoothState);
    933 
    934     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFdmx);
    935     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFdmx);
    936     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFres);
    937     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFres);
    938     FDK_FREE_MEMORY_1D(self->hybridAnalysis);
    939 
    940     FDK_FREE_MEMORY_1D(self->hybridSynthesis);
    941 
    942     /* The time buffer is passed to the decoder from outside to avoid copying
    943      * (zero copy). */
    944     /* FDK_FREE_MEMORY_2D(self->timeOut__FDK); */
    945 
    946     FDK_FREE_MEMORY_2D(self->hybOutputImagWet__FDK);
    947     FDK_FREE_MEMORY_2D(self->hybOutputRealWet__FDK);
    948 
    949     FDK_FREE_MEMORY_2D(self->hybOutputImagDry__FDK);
    950     FDK_FREE_MEMORY_2D(self->hybOutputRealDry__FDK);
    951 
    952     FDK_FREE_MEMORY_2D(self->wImag__FDK);
    953     FDK_FREE_MEMORY_2D(self->wReal__FDK);
    954 
    955     if (self->createParams.bProcResidual) {
    956       int i;
    957 
    958       for (i = 0; i < self->createParams.maxNumResChannels; i++) {
    959         if (self->hybResidualImag__FDK != NULL)
    960           FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK[i]);
    961         if (self->hybResidualReal__FDK != NULL)
    962           FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK[i]);
    963         if (self->qmfResidualImag__FDK != NULL)
    964           FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualImag__FDK[i]);
    965         if (self->qmfResidualReal__FDK != NULL)
    966           FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualReal__FDK[i]);
    967       }
    968 
    969       FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK);
    970       FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK);
    971 
    972       FDK_FREE_MEMORY_1D(self->qmfResidualImag__FDK);
    973       FDK_FREE_MEMORY_1D(self->qmfResidualReal__FDK);
    974 
    975     } /* self->createParams.bProcResidual */
    976 
    977     FDK_FREE_MEMORY_2D(self->hybInputImag__FDK);
    978     FDK_FREE_MEMORY_2D(self->hybInputReal__FDK);
    979 
    980     FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputImag__FDK);
    981     FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputReal__FDK);
    982 
    983     FDK_FREE_MEMORY_3D(self->M2ImagPrev__FDK);
    984 
    985     FDK_FREE_MEMORY_3D(self->M2RealPrev__FDK);
    986 
    987     FDK_FREE_MEMORY_3D(self->M2Imag__FDK);
    988 
    989     FDK_FREE_MEMORY_3D(self->M2Real__FDK);
    990 
    991     FDK_FREE_MEMORY_1D(self->arbdmxAlphaPrev__FDK);
    992     FDK_FREE_MEMORY_1D(self->arbdmxAlpha__FDK);
    993 
    994     FDK_FREE_MEMORY_3D(self->arbdmxGain__FDK);
    995 
    996     FDK_FREE_MEMORY_3D(self->ottIPD__FDK);
    997     FDK_FREE_MEMORY_3D(self->ottICC__FDK);
    998     FDK_FREE_MEMORY_3D(self->ottCLD__FDK);
    999 
   1000     /* Last parameters from prev frame */
   1001     FDK_FREE_MEMORY_2D(self->ottCLDidxPrev);
   1002     FDK_FREE_MEMORY_2D(self->ottICCidxPrev);
   1003     FDK_FREE_MEMORY_3D(self->ottICCdiffidx);
   1004     FDK_FREE_MEMORY_2D(self->ottIPDidxPrev);
   1005     FDK_FREE_MEMORY_2D(self->arbdmxGainIdxPrev);
   1006 
   1007     FDK_FREE_MEMORY_2D(self->cmpOttCLDidxPrev);
   1008     FDK_FREE_MEMORY_2D(self->cmpOttICCidxPrev);
   1009     FDK_FREE_MEMORY_3D(self->outIdxData);
   1010     FDK_FREE_MEMORY_2D(self->cmpOttIPDidxPrev);
   1011     FDK_FREE_MEMORY_2D(self->cmpArbdmxGainIdxPrev);
   1012 
   1013     FDK_FREE_MEMORY_2D(self->smgData);
   1014     FDK_FREE_MEMORY_1D(self->smgTime);
   1015 
   1016     FDK_FREE_MEMORY_1D(self->numOttBands);
   1017 
   1018     FDK_FREE_MEMORY_1D(self->param2hyb);
   1019 
   1020     FDK_FREE_MEMORY_1D(self);
   1021   }
   1022 
   1023   return;
   1024 }
   1025 
   1026 /**
   1027  * \brief Apply Surround bypass buffer copies
   1028  * \param self spatialDec handle
   1029  * \param hybInputReal
   1030  * \param hybInputImag
   1031  * \param hybOutputReal
   1032  * \param hybOutputImag
   1033  * \param numInputChannels amount if input channels available in hybInputReal
   1034  * and hybInputImag, which may differ from self->numInputChannels.
   1035  */
   1036 static void SpatialDecApplyBypass(spatialDec *self, FIXP_DBL **hybInputReal,
   1037                                   FIXP_DBL **hybInputImag,
   1038                                   FIXP_DBL **hybOutputReal,
   1039                                   FIXP_DBL **hybOutputImag,
   1040                                   const int numInputChannels) {
   1041   int complexHybBands;
   1042 
   1043   complexHybBands = self->hybridBands;
   1044 
   1045   {
   1046     int ch;
   1047     int rf = -1, lf = -1, cf = -1; /* Right Front, Left Front, Center Front */
   1048 
   1049     /* Determine output channel indices according to tree config */
   1050     switch (self->treeConfig) {
   1051       case TREE_212: /* 212  */
   1052         lf = 0;
   1053         rf = 1;
   1054         break;
   1055       default:;
   1056     }
   1057 
   1058     /* Note: numInputChannels might not match the tree config ! */
   1059     switch (numInputChannels) {
   1060       case 1:
   1061         if (cf > 0) {
   1062           FDKmemcpy(hybOutputReal[cf], hybInputReal[0],
   1063                     self->hybridBands * sizeof(FIXP_DBL));
   1064           FDKmemcpy(hybOutputImag[cf], hybInputImag[0],
   1065                     complexHybBands * sizeof(FIXP_DBL));
   1066         } else {
   1067           FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
   1068                     self->hybridBands * sizeof(FIXP_DBL));
   1069           FDKmemcpy(hybOutputReal[rf], hybInputReal[0],
   1070                     self->hybridBands * sizeof(FIXP_DBL));
   1071           FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
   1072                     complexHybBands * sizeof(FIXP_DBL));
   1073           FDKmemcpy(hybOutputImag[rf], hybInputImag[0],
   1074                     complexHybBands * sizeof(FIXP_DBL));
   1075         }
   1076         break;
   1077       case 2:
   1078         FDK_ASSERT(lf != -1);
   1079         FDK_ASSERT(rf != -1);
   1080         FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
   1081                   self->hybridBands * sizeof(FIXP_DBL));
   1082         FDKmemcpy(hybOutputReal[rf], hybInputReal[1],
   1083                   self->hybridBands * sizeof(FIXP_DBL));
   1084         FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
   1085                   complexHybBands * sizeof(FIXP_DBL));
   1086         FDKmemcpy(hybOutputImag[rf], hybInputImag[1],
   1087                   complexHybBands * sizeof(FIXP_DBL));
   1088         break;
   1089     }
   1090     for (ch = 0; ch < self->numOutputChannelsAT; ch++) {
   1091       if (ch == lf || ch == rf || ch == cf) {
   1092         continue; /* Skip bypassed channels */
   1093       }
   1094       FDKmemclear(hybOutputReal[ch], self->hybridBands * sizeof(FIXP_DBL));
   1095       FDKmemclear(hybOutputImag[ch], complexHybBands * sizeof(FIXP_DBL));
   1096     }
   1097   }
   1098 }
   1099 
   1100 /*******************************************************************************
   1101  Functionname: SpatialDecApplyParameterSets
   1102  *******************************************************************************
   1103 
   1104  Description:
   1105 
   1106  Arguments:
   1107 
   1108  Return:
   1109 
   1110 *******************************************************************************/
   1111 static SACDEC_ERROR SpatialDecApplyParameterSets(
   1112     spatialDec *self, const SPATIAL_BS_FRAME *frame, SPATIALDEC_INPUT_MODE mode,
   1113     PCM_MPS *inData,          /* Time domain input  */
   1114     FIXP_DBL **qmfInDataReal, /* QMF domain data l/r */
   1115     FIXP_DBL **qmfInDataImag, /* QMF domain data l/r */
   1116     UINT nSamples, UINT controlFlags, int numInputChannels,
   1117     const FDK_channelMapDescr *const mapDescr) {
   1118   SACDEC_ERROR err = MPS_OK;
   1119 
   1120   FIXP_SGL alpha;
   1121 
   1122   int ts;
   1123   int ch;
   1124   int hyb;
   1125 
   1126   int prevSlot = self->prevTimeSlot;
   1127   int ps = self->curPs;
   1128   int ts_io = 0; /* i/o dependent slot */
   1129   int bypassMode = (controlFlags & MPEGS_BYPASSMODE) ? 1 : 0;
   1130 
   1131   /* Bypass can be triggered by the upmixType, too. */
   1132   bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);
   1133 
   1134   /*
   1135    * Decode available slots
   1136    */
   1137   for (ts = self->curTimeSlot;
   1138        ts <= fixMin(self->curTimeSlot + (int)nSamples / self->qmfBands - 1,
   1139                     self->timeSlots - 1);
   1140        ts++, ts_io++) {
   1141     int currSlot = frame->paramSlot[ps];
   1142 
   1143     /*
   1144      * Get new parameter set
   1145      */
   1146     if (ts == prevSlot + 1) {
   1147       err = SpatialDecCalculateM1andM2(self, ps,
   1148                                        frame); /* input: ottCLD, ottICC, ... */
   1149       /* output: M1param(Real/Imag), M2(Real/Imag) */
   1150       if (err != MPS_OK) {
   1151         bypassMode = 1;
   1152         if (self->errInt == MPS_OK) {
   1153           /* store internal error befor it gets overwritten */
   1154           self->errInt = err;
   1155         }
   1156         err = MPS_OK;
   1157       }
   1158 
   1159       if ((ps == 0) && (self->bOverwriteM1M2prev != 0)) {
   1160         /* copy matrix entries of M1/M2 of the first parameter set to the
   1161            previous matrices (of the last frame). This avoids the interpolation
   1162            of incompatible values. E.g. for residual bands the coefficients are
   1163            calculated differently compared to non-residual bands.
   1164          */
   1165         SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
   1166                                         /* output: M(1/2)param(Real/Imag)Prev */
   1167         self->bOverwriteM1M2prev = 0;
   1168       }
   1169 
   1170       SpatialDecSmoothM1andM2(
   1171           self, frame,
   1172           ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */
   1173                /* output: M1param(Real/Imag), M2(Real/Imag) */
   1174     }
   1175 
   1176     alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot));
   1177 
   1178     switch (mode) {
   1179       case INPUTMODE_QMF_SBR:
   1180         if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD)
   1181           self->bShareDelayWithSBR = 0; /* We got no hybrid delay */
   1182         else
   1183           self->bShareDelayWithSBR = 1;
   1184         SpatialDecFeedQMF(self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode,
   1185                           self->qmfInputReal__FDK, self->qmfInputImag__FDK,
   1186                           self->numInputChannels);
   1187         break;
   1188       case INPUTMODE_TIME:
   1189         self->bShareDelayWithSBR = 0;
   1190         SpatialDecQMFAnalysis(self, inData, ts_io, bypassMode,
   1191                               self->qmfInputReal__FDK, self->qmfInputImag__FDK,
   1192                               self->numInputChannels);
   1193         break;
   1194       default:
   1195         break;
   1196     }
   1197 
   1198     if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
   1199         self->residualCoding) {
   1200       int offset;
   1201       ch = 1;
   1202 
   1203       offset = self->pQmfDomain->globalConf.nBandsSynthesis *
   1204                self->pQmfDomain->globalConf.nQmfTimeSlots;
   1205 
   1206       {
   1207         const PCM_MPS *inSamples =
   1208             &inData[ts * self->pQmfDomain->globalConf.nBandsAnalysis];
   1209 
   1210         CalculateSpaceAnalysisQmf(
   1211             &self->pQmfDomain->QmfDomainIn[ch].fb, inSamples + (ch * offset),
   1212             self->qmfResidualReal__FDK[0][0], self->qmfResidualImag__FDK[0][0]);
   1213 
   1214         if (!isTwoChMode(self->upmixType) && !bypassMode) {
   1215           int i;
   1216           FIXP_DBL *RESTRICT self_qmfResidualReal__FDK_0_0 =
   1217               &self->qmfResidualReal__FDK[0][0][0];
   1218           FIXP_DBL *RESTRICT self_qmfResidualImag__FDK_0_0 =
   1219               &self->qmfResidualImag__FDK[0][0][0];
   1220 
   1221           if ((self->pQmfDomain->globalConf.nBandsAnalysis == 24) &&
   1222               !(self->stereoConfigIndex == 3)) {
   1223             for (i = 0; i < self->qmfBands; i++) {
   1224               self_qmfResidualReal__FDK_0_0[i] =
   1225                   fMult(self_qmfResidualReal__FDK_0_0[i] << 1,
   1226                         self->clipProtectGain__FDK);
   1227               self_qmfResidualImag__FDK_0_0[i] =
   1228                   fMult(self_qmfResidualImag__FDK_0_0[i] << 1,
   1229                         self->clipProtectGain__FDK);
   1230             }
   1231           } else {
   1232             for (i = 0; i < self->qmfBands; i++) {
   1233               self_qmfResidualReal__FDK_0_0[i] = fMult(
   1234                   self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK);
   1235               self_qmfResidualImag__FDK_0_0[i] = fMult(
   1236                   self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK);
   1237             }
   1238           }
   1239         }
   1240       }
   1241     }
   1242 
   1243     SpatialDecHybridAnalysis(
   1244         self, /* input: qmfInput(Real/Imag), qmfResidual(Real/Imag) */
   1245         self->qmfInputReal__FDK, self->qmfInputImag__FDK,
   1246         self->hybInputReal__FDK, self->hybInputImag__FDK, ts, numInputChannels);
   1247 
   1248     if (bypassMode) {
   1249       SpatialDecApplyBypass(
   1250           self, self->hybInputReal__FDK, /* input: hybInput(Real/Imag) */
   1251           self->hybInputImag__FDK,
   1252           self->hybOutputRealDry__FDK, /* output: hybOutput(Real/Imag)Dry */
   1253           self->hybOutputImagDry__FDK, numInputChannels);
   1254     } else /* !bypassMode */
   1255     {
   1256       FIXP_DBL *pxReal[MAX_NUM_XCHANNELS] = {NULL};
   1257       FIXP_DBL *pxImag[MAX_NUM_XCHANNELS] = {NULL};
   1258 
   1259       SpatialDecCreateX(self,
   1260                         self->hybInputReal__FDK, /* input: hybInput(Real/Imag),
   1261                                                     hybResidual(Real/Imag) */
   1262                         self->hybInputImag__FDK, pxReal, pxImag);
   1263 
   1264       {
   1265         SpatialDecApplyM1_CreateW_Mode212(
   1266             self, frame, pxReal, pxImag,
   1267             self->wReal__FDK, /* output: w(Real/Imag) */
   1268             self->wImag__FDK);
   1269       }
   1270       if (err != MPS_OK) goto bail;
   1271 
   1272       int applyM2Config = APPLY_M2_NONE;
   1273 
   1274       applyM2Config = APPLY_M2;
   1275       if ((self->pConfigCurrent->syntaxFlags &
   1276            (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
   1277           (self->tempShapeConfig != 1) && (self->tempShapeConfig != 2)) {
   1278         if (self->phaseCoding == 3)
   1279           applyM2Config = APPLY_M2_MODE212_Res_PhaseCoding;
   1280         else
   1281           applyM2Config = APPLY_M2_MODE212;
   1282       }
   1283 
   1284       switch (applyM2Config) {
   1285         case APPLY_M2_MODE212: {
   1286           err = SpatialDecApplyM2_Mode212(
   1287               self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
   1288               self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
   1289         } break;
   1290         case APPLY_M2_MODE212_Res_PhaseCoding:
   1291           err = SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
   1292               self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
   1293               self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
   1294           break;
   1295         case APPLY_M2:
   1296           err = SpatialDecApplyM2(
   1297               self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
   1298               self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK,
   1299               self->hybOutputRealWet__FDK, self->hybOutputImagWet__FDK);
   1300           break;
   1301         default:
   1302           err = MPS_APPLY_M2_ERROR;
   1303           goto bail;
   1304       }
   1305 
   1306       if (err != MPS_OK) goto bail;
   1307 
   1308       if ((self->tempShapeConfig == 2) && (!isTwoChMode(self->upmixType))) {
   1309         SpatialDecReshapeBBEnv(self, frame,
   1310                                ts); /* input: reshapeBBEnvState,
   1311                                        hybOutput(Real/Imag)(Dry/Wet),
   1312                                        hybInput(Real/Imag) */
   1313       }                             /* output: hybOutput(Real/Imag)Dry */
   1314 
   1315       /* Merge parts of the dry and wet QMF buffers. */
   1316       if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
   1317         for (ch = 0; ch < self->numOutputChannels; ch++) {
   1318           for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
   1319             self->hybOutputRealDry__FDK[ch][hyb] +=
   1320                 self->hybOutputRealWet__FDK[ch][hyb];
   1321             self->hybOutputImagDry__FDK[ch][hyb] +=
   1322                 self->hybOutputImagWet__FDK[ch][hyb];
   1323           } /* loop hyb */
   1324         }   /* loop ch */
   1325         err = subbandTPApply(
   1326             self, frame); /* input: hStpDec, hybOutput(Real/Imag)Dry/Wet */
   1327                           /* output: hStpDec, hybOutput(Real/Imag)Dry */
   1328         if (err != MPS_OK) goto bail;
   1329       } /* (self->tempShapeConfig == 1) */
   1330       else {
   1331         /* The wet signal is added to the dry signal in applyM2 if GES and STP
   1332          * are disabled */
   1333         if ((self->tempShapeConfig == 1) || (self->tempShapeConfig == 2)) {
   1334           int nHybBands;
   1335           nHybBands = self->hybridBands;
   1336 
   1337           for (ch = 0; ch < self->numOutputChannels; ch++) {
   1338             FIXP_DBL *RESTRICT pRealDry = self->hybOutputRealDry__FDK[ch];
   1339             FIXP_DBL *RESTRICT pImagDry = self->hybOutputImagDry__FDK[ch];
   1340             FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
   1341             FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
   1342             for (hyb = 0; hyb < nHybBands; hyb++) {
   1343               pRealDry[hyb] += pRealWet[hyb];
   1344               pImagDry[hyb] += pImagWet[hyb];
   1345             } /* loop hyb */
   1346             for (; hyb < self->hybridBands; hyb++) {
   1347               pRealDry[hyb] += pRealWet[hyb];
   1348             } /* loop hyb */
   1349           }   /* loop ch */
   1350         } /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
   1351       }   /* !self->tempShapeConfig == 1 */
   1352     }     /*  !bypassMode */
   1353 
   1354     if (self->phaseCoding == 1) {
   1355       /* only if bsPhaseCoding == 1 and bsResidualCoding == 0 */
   1356 
   1357       SpatialDecApplyPhase(
   1358           self, alpha, (ts == currSlot) /* signal the last slot of the set */
   1359       );
   1360     }
   1361 
   1362     /*
   1363      * Synthesis Filtering
   1364      */
   1365 
   1366     err = SpatialDecSynthesis(
   1367         self, ts_io,
   1368         self->hybOutputRealDry__FDK, /* input: hybOutput(Real/Imag)Dry */
   1369         self->hybOutputImagDry__FDK, self->timeOut__FDK, /* output: timeOut */
   1370         numInputChannels, mapDescr);
   1371 
   1372     if (err != MPS_OK) goto bail;
   1373 
   1374     /*
   1375      * Update parameter buffer
   1376      */
   1377     if (ts == currSlot) {
   1378       SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
   1379                                       /* output: M(1/2)param(Real/Imag)Prev */
   1380 
   1381       prevSlot = currSlot;
   1382       ps++;
   1383     } /* if (ts==currSlot) */
   1384 
   1385   } /* ts loop */
   1386 
   1387   /*
   1388    * Save parameter states
   1389    */
   1390   self->prevTimeSlot = prevSlot;
   1391   self->curTimeSlot = ts;
   1392   self->curPs = ps;
   1393 
   1394 bail:
   1395 
   1396   return err;
   1397 }
   1398 
   1399 SACDEC_ERROR SpatialDecApplyFrame(
   1400     spatialDec *self,
   1401     SPATIAL_BS_FRAME *frame, /* parsed frame data to be applied */
   1402     SPATIALDEC_INPUT_MODE inputMode, PCM_MPS *inData, /* Time domain input  */
   1403     FIXP_DBL **qmfInDataReal,                         /* QMF domain data l/r */
   1404     FIXP_DBL **qmfInDataImag,                         /* QMF domain data l/r */
   1405     PCM_MPS *pcmOutBuf, /* MAX_OUTPUT_CHANNELS*MAX_TIME_SLOTS*NUM_QMF_BANDS] */
   1406     UINT nSamples, UINT *pControlFlags, int numInputChannels,
   1407     const FDK_channelMapDescr *const mapDescr) {
   1408   SACDEC_ERROR err = MPS_OK;
   1409 
   1410   int fDecAndMapFrameData;
   1411   int controlFlags;
   1412 
   1413   FDK_ASSERT(self != NULL);
   1414   FDK_ASSERT(pControlFlags != NULL);
   1415   FDK_ASSERT(pcmOutBuf != NULL);
   1416 
   1417   self->errInt = err; /* Init internal error */
   1418 
   1419   controlFlags = *pControlFlags;
   1420 
   1421   if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
   1422       (self->stereoConfigIndex > 1)) {
   1423     numInputChannels =
   1424         1; /* Do not count residual channel as input channel. It is handled
   1425               seperately. */
   1426   }
   1427 
   1428   /* Check if input amount of channels is consistent */
   1429   if (numInputChannels != self->numInputChannels) {
   1430     controlFlags |= MPEGS_CONCEAL;
   1431     if (numInputChannels > self->createParams.maxNumInputChannels) {
   1432       return MPS_INVALID_PARAMETER;
   1433     }
   1434   }
   1435 
   1436   self->timeOut__FDK = pcmOutBuf;
   1437 
   1438   /* Determine local function control flags */
   1439   fDecAndMapFrameData = frame->newBsData;
   1440 
   1441   if (((fDecAndMapFrameData ==
   1442         0) /* assures that conceal flag will not be set for blind mode */
   1443        && (self->curTimeSlot + (int)nSamples / self->qmfBands >
   1444            self->timeSlots)) ||
   1445       (frame->numParameterSets ==
   1446        0)) { /* New input samples but missing side info */
   1447     fDecAndMapFrameData = 1;
   1448     controlFlags |= MPEGS_CONCEAL;
   1449   }
   1450 
   1451   if ((fDecAndMapFrameData == 0) &&
   1452       (frame->paramSlot[fMax(0, frame->numParameterSets - 1)] !=
   1453            (self->timeSlots - 1) ||
   1454        self->curTimeSlot >
   1455            frame->paramSlot[self->curPs])) { /* Detected faulty parameter slot
   1456                                                 data. */
   1457     fDecAndMapFrameData = 1;
   1458     controlFlags |= MPEGS_CONCEAL;
   1459   }
   1460 
   1461   /* Update concealment state machine */
   1462   SpatialDecConcealment_UpdateState(
   1463       &self->concealInfo,
   1464       (controlFlags & MPEGS_CONCEAL)
   1465           ? 0
   1466           : 1); /* convert from conceal flag to frame ok flag */
   1467 
   1468   if (fDecAndMapFrameData) {
   1469     /* Reset spatial framing control vars */
   1470     frame->newBsData = 0;
   1471     self->prevTimeSlot = -1;
   1472     self->curTimeSlot = 0;
   1473     self->curPs = 0;
   1474 
   1475     if (controlFlags & MPEGS_CONCEAL) {
   1476       /* Reset frame data to avoid misconfiguration. */
   1477       SpatialDecClearFrameData(self, frame, &self->createParams);
   1478     }
   1479 
   1480     {
   1481       err = SpatialDecDecodeFrame(self, frame); /* input: ... */
   1482       /* output: decodeAndMapFrameDATA */
   1483     }
   1484 
   1485     if (err != MPS_OK) {
   1486       /* Rescue strategy is to apply bypass mode in order
   1487          to keep at least the downmix channels continuous. */
   1488       controlFlags |= MPEGS_CONCEAL;
   1489       if (self->errInt == MPS_OK) {
   1490         /* store internal error befor it gets overwritten */
   1491         self->errInt = err;
   1492       }
   1493     }
   1494   }
   1495 
   1496   err = SpatialDecApplyParameterSets(
   1497       self, frame, inputMode, inData, qmfInDataReal, qmfInDataImag, nSamples,
   1498       controlFlags | ((err == MPS_OK) ? 0 : MPEGS_BYPASSMODE), numInputChannels,
   1499       mapDescr);
   1500   if (err != MPS_OK) {
   1501     goto bail;
   1502   }
   1503 
   1504 bail:
   1505 
   1506   *pControlFlags = controlFlags;
   1507 
   1508   return err;
   1509 }
   1510