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