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