• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 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 
204   /* reset residual data */
205   {
206     int resQmfBands, resTimeSlots = (1);
207 
208     resQmfBands = setup->maxNumQmfBands;
209 
210     for (i = 0; i < setup->bProcResidual
211                     ? fMin(setup->maxNumResChannels,
212                            setup->maxNumOttBoxes + setup->maxNumInputChannels)
213                     : 0;
214          i += 1) {
215       for (int j = 0; j < resTimeSlots; j += 1) {
216         for (int k = 0; k < resQmfBands; k += 1) {
217           self->qmfResidualReal__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
218           self->qmfResidualImag__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
219         }
220       }
221     }
222   }
223 
224   return;
225 }
226 
227 /*******************************************************************************
228  Functionname: FDK_SpatialDecOpen
229  *******************************************************************************
230 
231  Description:
232 
233  Arguments:
234 
235  Return:
236 
237 *******************************************************************************/
FDK_SpatialDecOpen(const SPATIAL_DEC_CONFIG * config,int stereoConfigIndex)238 spatialDec *FDK_SpatialDecOpen(const SPATIAL_DEC_CONFIG *config,
239                                int stereoConfigIndex) {
240   int i;
241   int lfSize, hfSize;
242   spatialDec *self = NULL;
243   SACDEC_CREATION_PARAMS setup;
244 
245   switch (config->decoderLevel) {
246     case DECODER_LEVEL_0: /* 212 maxNumOutputChannels== 2 */
247       setup.maxNumInputChannels = 1;
248       setup.maxNumOutputChannels = 2;
249       setup.maxNumQmfBands = 64;
250       setup.maxNumXChannels = 2;
251       setup.maxNumVChannels = 2;
252       setup.maxNumDecorChannels = 1;
253       setup.bProcResidual = 1;
254       setup.maxNumResidualChannels = 0;
255       setup.maxNumOttBoxes = 1;
256       setup.maxNumParams = setup.maxNumInputChannels + setup.maxNumOttBoxes;
257       break;
258     default:
259       return NULL;
260   }
261 
262   setup.maxNumResChannels = 1;
263 
264   {
265     switch (config->maxNumOutputChannels) {
266       case OUTPUT_CHANNELS_2_0:
267         setup.maxNumOutputChannels = fMin(setup.maxNumOutputChannels, 2);
268         break;
269       case OUTPUT_CHANNELS_DEFAULT:
270       default:
271         break;
272     }
273   }
274 
275   setup.maxNumHybridBands = SacGetHybridSubbands(setup.maxNumQmfBands);
276 
277   switch (config->decoderMode) {
278     case EXT_HQ_ONLY:
279       setup.maxNumCmplxQmfBands = setup.maxNumQmfBands;
280       setup.maxNumCmplxHybBands = setup.maxNumHybridBands;
281       break;
282     default:
283       setup.maxNumCmplxQmfBands = fixMax(PC_NUM_BANDS, setup.maxNumQmfBands);
284       setup.maxNumCmplxHybBands =
285           fixMax(PC_NUM_HYB_BANDS, setup.maxNumHybridBands);
286       break;
287   } /* switch config->decoderMode */
288 
289   FDK_ALLOCATE_MEMORY_1D_INT(self, 1, spatialDec, SECT_DATA_L2)
290 
291   self->createParams = setup;
292 
293   FDK_ALLOCATE_MEMORY_1D(self->param2hyb, MAX_PARAMETER_BANDS + 1, int)
294 
295   FDK_ALLOCATE_MEMORY_1D(self->numOttBands, setup.maxNumOttBoxes, int)
296 
297   /* allocate arrays */
298 
299   FDK_ALLOCATE_MEMORY_1D(self->smgTime, MAX_PARAMETER_SETS, int)
300   FDK_ALLOCATE_MEMORY_2D(self->smgData, MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS,
301                          UCHAR)
302 
303   FDK_ALLOCATE_MEMORY_3D(self->ottCLD__FDK, setup.maxNumOttBoxes,
304                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
305   FDK_ALLOCATE_MEMORY_3D(self->ottICC__FDK, setup.maxNumOttBoxes,
306                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
307   FDK_ALLOCATE_MEMORY_3D(self->ottIPD__FDK, setup.maxNumOttBoxes,
308                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
309 
310   /* Last parameters from prev frame */
311   FDK_ALLOCATE_MEMORY_2D(self->ottCLDidxPrev, setup.maxNumOttBoxes,
312                          MAX_PARAMETER_BANDS, SCHAR)
313   FDK_ALLOCATE_MEMORY_2D(self->ottICCidxPrev, setup.maxNumOttBoxes,
314                          MAX_PARAMETER_BANDS, SCHAR)
315   FDK_ALLOCATE_MEMORY_3D(self->ottICCdiffidx, setup.maxNumOttBoxes,
316                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
317   FDK_ALLOCATE_MEMORY_2D(self->ottIPDidxPrev, setup.maxNumOttBoxes,
318                          MAX_PARAMETER_BANDS, SCHAR)
319   FDK_ALLOCATE_MEMORY_2D(self->arbdmxGainIdxPrev, setup.maxNumInputChannels,
320                          MAX_PARAMETER_BANDS, SCHAR)
321   FDK_ALLOCATE_MEMORY_2D(self->cmpOttCLDidxPrev, setup.maxNumOttBoxes,
322                          MAX_PARAMETER_BANDS, SCHAR)
323   FDK_ALLOCATE_MEMORY_2D(self->cmpOttICCidxPrev, setup.maxNumOttBoxes,
324                          MAX_PARAMETER_BANDS, SCHAR)
325   FDK_ALLOCATE_MEMORY_3D(self->outIdxData, setup.maxNumOttBoxes,
326                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
327 
328   FDK_ALLOCATE_MEMORY_3D(self->arbdmxGain__FDK, setup.maxNumInputChannels,
329                          MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
330   FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlpha__FDK, setup.maxNumInputChannels,
331                          FIXP_DBL)
332   FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlphaPrev__FDK, setup.maxNumInputChannels,
333                          FIXP_DBL)
334   FDK_ALLOCATE_MEMORY_2D(self->cmpArbdmxGainIdxPrev, setup.maxNumInputChannels,
335                          MAX_PARAMETER_BANDS, SCHAR)
336 
337   FDK_ALLOCATE_MEMORY_2D(self->cmpOttIPDidxPrev, setup.maxNumOttBoxes,
338                          MAX_PARAMETER_BANDS, SCHAR)
339 
340   FDK_ALLOCATE_MEMORY_3D_INT(self->M2Real__FDK, setup.maxNumOutputChannels,
341                              setup.maxNumVChannels, MAX_PARAMETER_BANDS,
342                              FIXP_DBL, SECT_DATA_L2)
343   FDK_ALLOCATE_MEMORY_3D(self->M2Imag__FDK, setup.maxNumOutputChannels,
344                          setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)
345 
346   FDK_ALLOCATE_MEMORY_3D_INT(self->M2RealPrev__FDK, setup.maxNumOutputChannels,
347                              setup.maxNumVChannels, MAX_PARAMETER_BANDS,
348                              FIXP_DBL, SECT_DATA_L2)
349   FDK_ALLOCATE_MEMORY_3D(self->M2ImagPrev__FDK, setup.maxNumOutputChannels,
350                          setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)
351 
352   FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
353       self->qmfInputReal__FDK, setup.maxNumInputChannels, setup.maxNumQmfBands,
354       FIXP_DBL, SECT_DATA_L2)
355   FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
356       self->qmfInputImag__FDK, setup.maxNumInputChannels,
357       setup.maxNumCmplxQmfBands, FIXP_DBL, SECT_DATA_L2)
358 
359   FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputReal__FDK, setup.maxNumInputChannels,
360                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
361   FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputImag__FDK, setup.maxNumInputChannels,
362                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
363 
364   if (setup.bProcResidual) {
365     FDK_ALLOCATE_MEMORY_1D(self->qmfResidualReal__FDK, setup.maxNumResChannels,
366                            FIXP_DBL **)
367     FDK_ALLOCATE_MEMORY_1D(self->qmfResidualImag__FDK, setup.maxNumResChannels,
368                            FIXP_DBL **)
369 
370     FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK, setup.maxNumResChannels,
371                            FIXP_DBL *)
372     FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK, setup.maxNumResChannels,
373                            FIXP_DBL *)
374 
375     for (i = 0; i < setup.maxNumResChannels; i++) {
376       int resQmfBands = (config->decoderMode == EXT_LP_ONLY)
377                             ? PC_NUM_BANDS
378                             : setup.maxNumQmfBands;
379       int resHybBands = (config->decoderMode == EXT_LP_ONLY)
380                             ? PC_NUM_HYB_BANDS
381                             : setup.maxNumHybridBands;
382       /* Alignment is needed for USAC residuals because QMF analysis directly
383        * writes to this buffer. */
384       FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualReal__FDK[i], (1),
385                                          resQmfBands, FIXP_DBL, SECT_DATA_L1)
386       FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualImag__FDK[i], (1),
387                                          resQmfBands, FIXP_DBL, SECT_DATA_L1)
388 
389       FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK[i],
390                              setup.maxNumHybridBands, FIXP_DBL)
391       FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK[i], resHybBands,
392                              FIXP_DBL)
393     }
394   } /* if (setup.bProcResidual) */
395 
396   FDK_ALLOCATE_MEMORY_2D_INT(self->wReal__FDK, setup.maxNumVChannels,
397                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
398   FDK_ALLOCATE_MEMORY_2D_INT(self->wImag__FDK, setup.maxNumVChannels,
399                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
400 
401   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealDry__FDK,
402                              setup.maxNumOutputChannels,
403                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
404   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagDry__FDK,
405                              setup.maxNumOutputChannels,
406                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
407 
408   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealWet__FDK,
409                              setup.maxNumOutputChannels,
410                              setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
411   FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagWet__FDK,
412                              setup.maxNumOutputChannels,
413                              setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
414 
415   FDK_ALLOCATE_MEMORY_1D(self->hybridSynthesis, setup.maxNumOutputChannels,
416                          FDK_SYN_HYB_FILTER)
417 
418   FDK_ALLOCATE_MEMORY_1D(
419       self->hybridAnalysis,
420       setup.bProcResidual ? setup.maxNumInputChannels + setup.maxNumResChannels
421                           : setup.maxNumInputChannels,
422       FDK_ANA_HYB_FILTER)
423 
424   lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
425   {
426     hfSize =
427         BUFFER_LEN_HF * ((setup.maxNumQmfBands - MAX_QMF_BANDS_TO_HYBRID) +
428                          (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));
429   }
430 
431   FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFdmx,
432                              setup.maxNumInputChannels, lfSize, FIXP_DBL,
433                              SECT_DATA_L2) {
434     FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFdmx,
435                            setup.maxNumInputChannels, hfSize, FIXP_DBL)
436   }
437 
438   for (i = 0; i < setup.maxNumInputChannels; i++) {
439     FIXP_DBL *pHybridAnaStatesHFdmx;
440 
441     pHybridAnaStatesHFdmx = self->pHybridAnaStatesHFdmx[i];
442 
443     FDKhybridAnalysisOpen(&self->hybridAnalysis[i],
444                           self->pHybridAnaStatesLFdmx[i],
445                           lfSize * sizeof(FIXP_DBL), pHybridAnaStatesHFdmx,
446                           hfSize * sizeof(FIXP_DBL));
447   }
448   if (setup.bProcResidual) {
449     lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
450     hfSize = BUFFER_LEN_HF *
451              ((((config->decoderMode == EXT_LP_ONLY) ? PC_NUM_BANDS
452                                                      : setup.maxNumQmfBands) -
453                MAX_QMF_BANDS_TO_HYBRID) +
454               (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));
455 
456     FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFres,
457                                setup.maxNumResChannels, lfSize, FIXP_DBL,
458                                SECT_DATA_L2)
459     FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFres, setup.maxNumResChannels,
460                            hfSize, FIXP_DBL)
461 
462     for (i = setup.maxNumInputChannels;
463          i < (setup.maxNumInputChannels + setup.maxNumResChannels); i++) {
464       FDKhybridAnalysisOpen(
465           &self->hybridAnalysis[i],
466           self->pHybridAnaStatesLFres[i - setup.maxNumInputChannels],
467           lfSize * sizeof(FIXP_DBL),
468           self->pHybridAnaStatesHFres[i - setup.maxNumInputChannels],
469           hfSize * sizeof(FIXP_DBL));
470     }
471   }
472 
473   FDK_ALLOCATE_MEMORY_1D(self->smoothState, 1, SMOOTHING_STATE)
474   FDK_ALLOCATE_MEMORY_1D(self->reshapeBBEnvState, 1, RESHAPE_BBENV_STATE)
475 
476   FDK_ALLOCATE_MEMORY_1D(self->apDecor, setup.maxNumDecorChannels, DECORR_DEC)
477   FDK_ALLOCATE_MEMORY_2D_INT(self->pDecorBufferCplx, setup.maxNumDecorChannels,
478                              (2 * ((825) + (373))), FIXP_DBL, SECT_DATA_L2)
479 
480   for (i = 0; i < setup.maxNumDecorChannels; i++) {
481     if (FDKdecorrelateOpen(&self->apDecor[i], self->pDecorBufferCplx[i],
482                            (2 * ((825) + (373))))) {
483       goto bail;
484     }
485   }
486 
487   if (subbandTPCreate(&self->hStpDec) != MPS_OK) {
488     goto bail;
489   }
490 
491   /* save general decoder configuration */
492   self->decoderLevel = config->decoderLevel;
493   self->decoderMode = config->decoderMode;
494   self->binauralMode = config->binauralMode;
495 
496   /* preinitialize configuration */
497   self->partiallyComplex = (config->decoderMode != EXT_HQ_ONLY) ? 1 : 0;
498 
499   /* Set to default state */
500   SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_ALL);
501 
502   /* Everything is fine so return the handle */
503   return self;
504 
505 bail:
506   /* Collector for all errors.
507      Deallocate all memory and return a invalid handle. */
508   FDK_SpatialDecClose(self);
509 
510   return NULL;
511 }
512 
513 /*******************************************************************************
514  Functionname: isValidConfig
515  *******************************************************************************
516 
517  Description: Validate if configuration is supported in present instance
518 
519  Arguments:
520 
521  Return: 1: all okay
522          0: configuration not supported
523 *******************************************************************************/
isValidConfig(spatialDec const * const self,const SPATIAL_DEC_UPMIX_TYPE upmixType,SPATIALDEC_PARAM const * const pUserParams,const AUDIO_OBJECT_TYPE coreAot)524 static int isValidConfig(spatialDec const *const self,
525                          const SPATIAL_DEC_UPMIX_TYPE upmixType,
526                          SPATIALDEC_PARAM const *const pUserParams,
527                          const AUDIO_OBJECT_TYPE coreAot) {
528   UPMIXTYPE nUpmixType;
529 
530   FDK_ASSERT(self != NULL);
531   FDK_ASSERT(pUserParams != NULL);
532 
533   nUpmixType = (UPMIXTYPE)upmixType;
534 
535   switch (nUpmixType) {
536     case UPMIXTYPE_BYPASS: /* UPMIX_TYPE_BYPASS */
537       break;
538     case UPMIXTYPE_NORMAL: /* UPMIX_TYPE_NORMAL */
539       break;
540     default:
541       return 0; /* unsupported upmixType */
542   }
543 
544   return 1; /* upmixType supported */
545 }
546 
CheckLevelTreeUpmixType(const SACDEC_CREATION_PARAMS * const pCreateParams,const SPATIAL_SPECIFIC_CONFIG * const pSsc,const int decoderLevel,const UPMIXTYPE upmixType)547 static SACDEC_ERROR CheckLevelTreeUpmixType(
548     const SACDEC_CREATION_PARAMS *const pCreateParams,
549     const SPATIAL_SPECIFIC_CONFIG *const pSsc, const int decoderLevel,
550     const UPMIXTYPE upmixType) {
551   SACDEC_ERROR err = MPS_OK;
552   int nOutputChannels, treeConfig;
553 
554   FDK_ASSERT(pCreateParams != NULL);
555   FDK_ASSERT(pSsc != NULL);
556 
557   treeConfig = pSsc->treeConfig;
558 
559   switch (decoderLevel) {
560     case 0: {
561       if (treeConfig != SPATIALDEC_MODE_RSVD7) {
562         err = MPS_INVALID_TREECONFIG;
563         goto bail;
564       }
565       break;
566     }
567     default:
568       err = MPS_INVALID_PARAMETER /* MPS_UNIMPLEMENTED */;
569       goto bail;
570   }
571 
572   switch (upmixType) {
573     case UPMIXTYPE_BYPASS:
574       nOutputChannels = pSsc->nInputChannels;
575       break;
576     default:
577       nOutputChannels = pSsc->nOutputChannels;
578       break;
579   }
580 
581   /* Is sufficient memory allocated. */
582   if ((pSsc->nInputChannels > pCreateParams->maxNumInputChannels) ||
583       (nOutputChannels > pCreateParams->maxNumOutputChannels) ||
584       (pSsc->nOttBoxes > pCreateParams->maxNumOttBoxes)) {
585     err = MPS_INVALID_PARAMETER;
586   }
587 
588 bail:
589   return err;
590 }
591 
SpatialDecInitParserContext(spatialDec * self)592 void SpatialDecInitParserContext(spatialDec *self) {
593   int i, j;
594 
595   for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
596     for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
597       self->ottCLDidxPrev[i][j] = 0;
598       self->ottICCidxPrev[i][j] = 0;
599       self->cmpOttCLDidxPrev[i][j] = 0;
600       self->cmpOttICCidxPrev[i][j] = 0;
601     }
602   }
603   for (i = 0; i < self->createParams.maxNumInputChannels; i++) {
604     for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
605       self->arbdmxGainIdxPrev[i][j] = 0;
606       self->cmpArbdmxGainIdxPrev[i][j] = 0;
607     }
608   }
609 }
610 
611 /*******************************************************************************
612  Functionname: FDK_SpatialDecInit
613  *******************************************************************************
614 
615  Description:
616 
617  Arguments:
618 
619  Return:
620 
621 *******************************************************************************/
622 
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)623 SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
624                                 SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
625                                 int nQmfBands,
626                                 SPATIAL_DEC_UPMIX_TYPE const upmixType,
627                                 SPATIALDEC_PARAM *pUserParams, UINT initFlags) {
628   SACDEC_ERROR err = MPS_OK;
629   int nCh, i, j, k;
630   int maxQmfBands;
631   int bypassMode = 0;
632 
633   self->useFDreverb = 0;
634 
635   /* check configuration parameter */
636   if (!isValidConfig(self, upmixType, pUserParams,
637                      pSpatialSpecificConfig->coreCodec)) {
638     return MPS_INVALID_PARAMETER;
639   }
640 
641   /* check tree configuration */
642   err = CheckLevelTreeUpmixType(&self->createParams, pSpatialSpecificConfig,
643                                 self->decoderLevel, (UPMIXTYPE)upmixType);
644   if (err != MPS_OK) {
645     goto bail;
646   }
647 
648   /* Store and update instance after all checks passed successfully: */
649   self->upmixType = (UPMIXTYPE)upmixType;
650 
651   if (initFlags & MPEGS_INIT_PARAMS_ERROR_CONCEALMENT) { /* At least one error
652                                                             concealment
653                                                             parameter changed */
654     err = SpatialDecConcealment_SetParam(
655         &self->concealInfo, SAC_DEC_CONCEAL_METHOD, pUserParams->concealMethod);
656     if (err != MPS_OK) {
657       goto bail;
658     }
659     err = SpatialDecConcealment_SetParam(&self->concealInfo,
660                                          SAC_DEC_CONCEAL_NUM_KEEP_FRAMES,
661                                          pUserParams->concealNumKeepFrames);
662     if (err != MPS_OK) {
663       goto bail;
664     }
665     err = SpatialDecConcealment_SetParam(
666         &self->concealInfo, SAC_DEC_CONCEAL_FADE_OUT_SLOPE_LENGTH,
667         pUserParams->concealFadeOutSlopeLength);
668     if (err != MPS_OK) {
669       goto bail;
670     }
671     err = SpatialDecConcealment_SetParam(&self->concealInfo,
672                                          SAC_DEC_CONCEAL_FADE_IN_SLOPE_LENGTH,
673                                          pUserParams->concealFadeInSlopeLength);
674     if (err != MPS_OK) {
675       goto bail;
676     }
677     err = SpatialDecConcealment_SetParam(&self->concealInfo,
678                                          SAC_DEC_CONCEAL_NUM_RELEASE_FRAMES,
679                                          pUserParams->concealNumReleaseFrames);
680     if (err != MPS_OK) {
681       goto bail;
682     }
683   }
684 
685   if (initFlags &
686       MPEGS_INIT_STATES_ERROR_CONCEALMENT) { /* Set to default state */
687     SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_STATE);
688   }
689 
690   /* determine bypass mode */
691   bypassMode |= pUserParams->bypassMode;
692   bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);
693 
694   /* static decoder scale depends on number of qmf bands */
695   switch (nQmfBands) {
696     case 16:
697     case 24:
698     case 32:
699       self->staticDecScale = 21;
700       break;
701     case 64:
702       self->staticDecScale = 22;
703       break;
704     default:
705       return MPS_INVALID_PARAMETER;
706   }
707 
708   self->numParameterSetsPrev = 1;
709 
710   self->qmfBands = nQmfBands;
711   /* self->hybridBands will be updated in SpatialDecDecodeHeader() below. */
712 
713   self->bShareDelayWithSBR = 0;
714 
715   err = SpatialDecDecodeHeader(self, pSpatialSpecificConfig);
716   if (err != MPS_OK) {
717     goto bail;
718   }
719 
720   self->stereoConfigIndex = pSpatialSpecificConfig->stereoConfigIndex;
721 
722   if (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) {
723     self->qmfInputDelayBufPos = 0;
724     self->pc_filterdelay = 1; /* Division by 0 not possible */
725   }
726 
727   maxQmfBands = self->qmfBands;
728 
729   /* init residual decoder */
730 
731   /* init tonality smoothing */
732   if (initFlags & MPEGS_INIT_STATES_PARAM) {
733     initParameterSmoothing(self);
734   }
735 
736   /* init GES */
737   initBBEnv(self, (initFlags & MPEGS_INIT_STATES_GES) ? 1 : 0);
738 
739   /* Clip protection is applied only for normal processing. */
740   if (!isTwoChMode(self->upmixType) && !bypassMode) {
741     self->staticDecScale += self->clipProtectGainSF__FDK;
742   }
743 
744   {
745     UINT flags = 0;
746     INT initStatesFlag = (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) ? 1 : 0;
747     INT useLdFilter =
748         (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) ? 1 : 0;
749 
750     flags = self->pQmfDomain->globalConf.flags_requested;
751     flags &= (~(UINT)QMF_FLAG_LP);
752 
753     if (initStatesFlag)
754       flags &= ~QMF_FLAG_KEEP_STATES;
755     else
756       flags |= QMF_FLAG_KEEP_STATES;
757 
758     if (useLdFilter)
759       flags |= QMF_FLAG_MPSLDFB;
760     else
761       flags &= ~QMF_FLAG_MPSLDFB;
762 
763     self->pQmfDomain->globalConf.flags_requested = flags;
764     FDK_QmfDomain_Configure(self->pQmfDomain);
765 
766     /* output scaling */
767     for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
768       int outputScale = 0, outputGain_e = 0, scale = 0;
769       FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);
770 
771       if (!isTwoChMode(self->upmixType) && !bypassMode) {
772         outputScale +=
773             self->clipProtectGainSF__FDK; /* consider clip protection scaling at
774                                              synthesis qmf */
775       }
776 
777       scale = outputScale;
778 
779       qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
780       qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
781                        outputGain_e);
782     }
783   }
784 
785   for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
786     FDKhybridSynthesisInit(&self->hybridSynthesis[nCh], THREE_TO_TEN,
787                            self->qmfBands, maxQmfBands);
788   }
789 
790   /* for input, residual channels and arbitrary down-mix residual channels */
791   for (nCh = 0; nCh < self->createParams.maxNumInputChannels; nCh++) {
792     FDKhybridAnalysisInit(
793         &self->hybridAnalysis[nCh], THREE_TO_TEN, self->qmfBands, maxQmfBands,
794         (initFlags & MPEGS_INIT_STATES_ANA_HYB_FILTER) ? 1 : 0);
795   }
796   for (; nCh < (self->createParams.bProcResidual
797                     ? (self->createParams.maxNumInputChannels +
798                        self->createParams.maxNumResChannels)
799                     : self->createParams.maxNumInputChannels);
800        nCh++) {
801     FDKhybridAnalysisInit(&self->hybridAnalysis[nCh], THREE_TO_TEN, maxQmfBands,
802                           maxQmfBands, 0);
803   }
804 
805   {
806     for (k = 0; k < self->numDecorSignals; k++) {
807       int errCode, idec;
808       FDK_DECORR_TYPE decorrType = DECORR_PS;
809       decorrType = DECORR_LD;
810       if (self->pConfigCurrent->syntaxFlags &
811           (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) {
812         decorrType =
813             ((self->treeConfig == TREE_212) && (self->decorrType == DECORR_PS))
814                 ? DECORR_PS
815                 : DECORR_USAC;
816       }
817       {
818         idec = k;
819         if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
820           if (self->treeConfig == TREE_212 && k == 0) {
821             idec = 2;
822           }
823         }
824       }
825       errCode = FDKdecorrelateInit(
826           &self->apDecor[k], self->hybridBands, decorrType, DUCKER_AUTOMATIC,
827           self->decorrConfig, idec, 0, /* self->partiallyComplex */
828           0, 0,                        /* isLegacyPS */
829           (initFlags & MPEGS_INIT_STATES_DECORRELATOR) ? 1 : 0);
830       if (errCode) return MPS_NOTOK;
831     }
832   } /* !self->partiallyComplex */
833 
834   err = initM1andM2(self, (initFlags & MPEGS_INIT_STATES_M1M2) ? 1 : 0,
835                     (initFlags & MPEGS_INIT_CONFIG) ? 1 : 0);
836   if (err != MPS_OK) return err;
837 
838   /* Initialization of previous frame data */
839   if (initFlags & MPEGS_INIT_STATES_PARAM) {
840     for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
841       /* reset icc diff data */
842       for (k = 0; k < MAX_PARAMETER_SETS; k += 1) {
843         for (j = 0; j < MAX_PARAMETER_BANDS; j += 1) {
844           self->ottICCdiffidx[i][k][j] = 0;
845         }
846       }
847     }
848     /* Parameter Smoothing */
849     /* robustness: init with one of the values of smgTimeTable[] = {64, 128,
850        256, 512} to avoid division by zero in calcFilterCoeff__FDK() */
851     self->smoothState->prevSmgTime = smgTimeTable[2]; /* == 256 */
852     FDKmemclear(self->smoothState->prevSmgData,
853                 MAX_PARAMETER_BANDS * sizeof(UCHAR));
854     FDKmemclear(self->smoothState->opdLeftState__FDK,
855                 MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
856     FDKmemclear(self->smoothState->opdRightState__FDK,
857                 MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
858   }
859 
860   self->prevTimeSlot = -1;
861   self->curTimeSlot =
862       MAX_TIME_SLOTS + 1; /* Initialize with a invalid value to trigger
863                              concealment if first frame has no valid data. */
864   self->curPs = 0;
865 
866   subbandTPInit(self->hStpDec);
867 
868 bail:
869   return err;
870 }
871 
SpatialDecChannelProperties(spatialDec * self,AUDIO_CHANNEL_TYPE channelType[],UCHAR channelIndices[],const FDK_channelMapDescr * const mapDescr)872 void SpatialDecChannelProperties(spatialDec *self,
873                                  AUDIO_CHANNEL_TYPE channelType[],
874                                  UCHAR channelIndices[],
875                                  const FDK_channelMapDescr *const mapDescr) {
876   if ((self == NULL) || (channelType == NULL) || (channelIndices == NULL) ||
877       (mapDescr == NULL)) {
878     return; /* no extern buffer to be filled */
879   }
880 
881   if (self->numOutputChannelsAT !=
882       treePropertyTable[self->treeConfig].numOutputChannels) {
883     int ch;
884     /* Declare all channels to be front channels: */
885     for (ch = 0; ch < self->numOutputChannelsAT; ch += 1) {
886       channelType[ch] = ACT_FRONT;
887       channelIndices[ch] = ch;
888     }
889   } else {
890     /* ISO/IEC FDIS 23003-1:2006(E), page 46, Table 40 bsTreeConfig */
891     switch (self->treeConfig) {
892       case TREE_212:
893         channelType[0] = ACT_FRONT;
894         channelIndices[0] = 0;
895         channelType[1] = ACT_FRONT;
896         channelIndices[1] = 1;
897         break;
898       default:;
899     }
900   }
901 }
902 
903 /*******************************************************************************
904  Functionname: FDK_SpatialDecClose
905  *******************************************************************************
906 
907  Description:
908 
909  Arguments:
910 
911  Return:
912 
913 *******************************************************************************/
914 
FDK_SpatialDecClose(spatialDec * self)915 void FDK_SpatialDecClose(spatialDec *self) {
916   if (self) {
917     int k;
918 
919     if (self->apDecor != NULL) {
920       for (k = 0; k < self->createParams.maxNumDecorChannels; k++) {
921         FDKdecorrelateClose(&(self->apDecor[k]));
922       }
923       FDK_FREE_MEMORY_1D(self->apDecor);
924     }
925     if (self->pDecorBufferCplx != NULL) {
926       FDK_FREE_MEMORY_2D(self->pDecorBufferCplx);
927     }
928 
929     subbandTPDestroy(&self->hStpDec);
930 
931     FDK_FREE_MEMORY_1D(self->reshapeBBEnvState);
932     FDK_FREE_MEMORY_1D(self->smoothState);
933 
934     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFdmx);
935     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFdmx);
936     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFres);
937     FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFres);
938     FDK_FREE_MEMORY_1D(self->hybridAnalysis);
939 
940     FDK_FREE_MEMORY_1D(self->hybridSynthesis);
941 
942     /* The time buffer is passed to the decoder from outside to avoid copying
943      * (zero copy). */
944     /* FDK_FREE_MEMORY_2D(self->timeOut__FDK); */
945 
946     FDK_FREE_MEMORY_2D(self->hybOutputImagWet__FDK);
947     FDK_FREE_MEMORY_2D(self->hybOutputRealWet__FDK);
948 
949     FDK_FREE_MEMORY_2D(self->hybOutputImagDry__FDK);
950     FDK_FREE_MEMORY_2D(self->hybOutputRealDry__FDK);
951 
952     FDK_FREE_MEMORY_2D(self->wImag__FDK);
953     FDK_FREE_MEMORY_2D(self->wReal__FDK);
954 
955     if (self->createParams.bProcResidual) {
956       int i;
957 
958       for (i = 0; i < self->createParams.maxNumResChannels; i++) {
959         if (self->hybResidualImag__FDK != NULL)
960           FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK[i]);
961         if (self->hybResidualReal__FDK != NULL)
962           FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK[i]);
963         if (self->qmfResidualImag__FDK != NULL)
964           FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualImag__FDK[i]);
965         if (self->qmfResidualReal__FDK != NULL)
966           FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualReal__FDK[i]);
967       }
968 
969       FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK);
970       FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK);
971 
972       FDK_FREE_MEMORY_1D(self->qmfResidualImag__FDK);
973       FDK_FREE_MEMORY_1D(self->qmfResidualReal__FDK);
974 
975     } /* self->createParams.bProcResidual */
976 
977     FDK_FREE_MEMORY_2D(self->hybInputImag__FDK);
978     FDK_FREE_MEMORY_2D(self->hybInputReal__FDK);
979 
980     FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputImag__FDK);
981     FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputReal__FDK);
982 
983     FDK_FREE_MEMORY_3D(self->M2ImagPrev__FDK);
984 
985     FDK_FREE_MEMORY_3D(self->M2RealPrev__FDK);
986 
987     FDK_FREE_MEMORY_3D(self->M2Imag__FDK);
988 
989     FDK_FREE_MEMORY_3D(self->M2Real__FDK);
990 
991     FDK_FREE_MEMORY_1D(self->arbdmxAlphaPrev__FDK);
992     FDK_FREE_MEMORY_1D(self->arbdmxAlpha__FDK);
993 
994     FDK_FREE_MEMORY_3D(self->arbdmxGain__FDK);
995 
996     FDK_FREE_MEMORY_3D(self->ottIPD__FDK);
997     FDK_FREE_MEMORY_3D(self->ottICC__FDK);
998     FDK_FREE_MEMORY_3D(self->ottCLD__FDK);
999 
1000     /* Last parameters from prev frame */
1001     FDK_FREE_MEMORY_2D(self->ottCLDidxPrev);
1002     FDK_FREE_MEMORY_2D(self->ottICCidxPrev);
1003     FDK_FREE_MEMORY_3D(self->ottICCdiffidx);
1004     FDK_FREE_MEMORY_2D(self->ottIPDidxPrev);
1005     FDK_FREE_MEMORY_2D(self->arbdmxGainIdxPrev);
1006 
1007     FDK_FREE_MEMORY_2D(self->cmpOttCLDidxPrev);
1008     FDK_FREE_MEMORY_2D(self->cmpOttICCidxPrev);
1009     FDK_FREE_MEMORY_3D(self->outIdxData);
1010     FDK_FREE_MEMORY_2D(self->cmpOttIPDidxPrev);
1011     FDK_FREE_MEMORY_2D(self->cmpArbdmxGainIdxPrev);
1012 
1013     FDK_FREE_MEMORY_2D(self->smgData);
1014     FDK_FREE_MEMORY_1D(self->smgTime);
1015 
1016     FDK_FREE_MEMORY_1D(self->numOttBands);
1017 
1018     FDK_FREE_MEMORY_1D(self->param2hyb);
1019 
1020     FDK_FREE_MEMORY_1D(self);
1021   }
1022 
1023   return;
1024 }
1025 
1026 /**
1027  * \brief Apply Surround bypass buffer copies
1028  * \param self spatialDec handle
1029  * \param hybInputReal
1030  * \param hybInputImag
1031  * \param hybOutputReal
1032  * \param hybOutputImag
1033  * \param numInputChannels amount if input channels available in hybInputReal
1034  * and hybInputImag, which may differ from self->numInputChannels.
1035  */
SpatialDecApplyBypass(spatialDec * self,FIXP_DBL ** hybInputReal,FIXP_DBL ** hybInputImag,FIXP_DBL ** hybOutputReal,FIXP_DBL ** hybOutputImag,const int numInputChannels)1036 static void SpatialDecApplyBypass(spatialDec *self, FIXP_DBL **hybInputReal,
1037                                   FIXP_DBL **hybInputImag,
1038                                   FIXP_DBL **hybOutputReal,
1039                                   FIXP_DBL **hybOutputImag,
1040                                   const int numInputChannels) {
1041   int complexHybBands;
1042 
1043   complexHybBands = self->hybridBands;
1044 
1045   {
1046     int ch;
1047     int rf = -1, lf = -1, cf = -1; /* Right Front, Left Front, Center Front */
1048 
1049     /* Determine output channel indices according to tree config */
1050     switch (self->treeConfig) {
1051       case TREE_212: /* 212  */
1052         lf = 0;
1053         rf = 1;
1054         break;
1055       default:;
1056     }
1057 
1058     /* Note: numInputChannels might not match the tree config ! */
1059     switch (numInputChannels) {
1060       case 1:
1061         if (cf > 0) {
1062           FDKmemcpy(hybOutputReal[cf], hybInputReal[0],
1063                     self->hybridBands * sizeof(FIXP_DBL));
1064           FDKmemcpy(hybOutputImag[cf], hybInputImag[0],
1065                     complexHybBands * sizeof(FIXP_DBL));
1066         } else {
1067           FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
1068                     self->hybridBands * sizeof(FIXP_DBL));
1069           FDKmemcpy(hybOutputReal[rf], hybInputReal[0],
1070                     self->hybridBands * sizeof(FIXP_DBL));
1071           FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
1072                     complexHybBands * sizeof(FIXP_DBL));
1073           FDKmemcpy(hybOutputImag[rf], hybInputImag[0],
1074                     complexHybBands * sizeof(FIXP_DBL));
1075         }
1076         break;
1077       case 2:
1078         FDK_ASSERT(lf != -1);
1079         FDK_ASSERT(rf != -1);
1080         FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
1081                   self->hybridBands * sizeof(FIXP_DBL));
1082         FDKmemcpy(hybOutputReal[rf], hybInputReal[1],
1083                   self->hybridBands * sizeof(FIXP_DBL));
1084         FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
1085                   complexHybBands * sizeof(FIXP_DBL));
1086         FDKmemcpy(hybOutputImag[rf], hybInputImag[1],
1087                   complexHybBands * sizeof(FIXP_DBL));
1088         break;
1089     }
1090     for (ch = 0; ch < self->numOutputChannelsAT; ch++) {
1091       if (ch == lf || ch == rf || ch == cf) {
1092         continue; /* Skip bypassed channels */
1093       }
1094       FDKmemclear(hybOutputReal[ch], self->hybridBands * sizeof(FIXP_DBL));
1095       FDKmemclear(hybOutputImag[ch], complexHybBands * sizeof(FIXP_DBL));
1096     }
1097   }
1098 }
1099 
1100 /*******************************************************************************
1101  Functionname: SpatialDecApplyParameterSets
1102  *******************************************************************************
1103 
1104  Description:
1105 
1106  Arguments:
1107 
1108  Return:
1109 
1110 *******************************************************************************/
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)1111 static SACDEC_ERROR SpatialDecApplyParameterSets(
1112     spatialDec *self, const SPATIAL_BS_FRAME *frame, SPATIALDEC_INPUT_MODE mode,
1113     PCM_MPS *inData,          /* Time domain input  */
1114     FIXP_DBL **qmfInDataReal, /* QMF domain data l/r */
1115     FIXP_DBL **qmfInDataImag, /* QMF domain data l/r */
1116     UINT nSamples, UINT controlFlags, int numInputChannels,
1117     const FDK_channelMapDescr *const mapDescr) {
1118   SACDEC_ERROR err = MPS_OK;
1119 
1120   FIXP_SGL alpha;
1121 
1122   int ts;
1123   int ch;
1124   int hyb;
1125 
1126   int prevSlot = self->prevTimeSlot;
1127   int ps = self->curPs;
1128   int ts_io = 0; /* i/o dependent slot */
1129   int bypassMode = (controlFlags & MPEGS_BYPASSMODE) ? 1 : 0;
1130 
1131   /* Bypass can be triggered by the upmixType, too. */
1132   bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);
1133 
1134   /*
1135    * Decode available slots
1136    */
1137   for (ts = self->curTimeSlot;
1138        ts <= fixMin(self->curTimeSlot + (int)nSamples / self->qmfBands - 1,
1139                     self->timeSlots - 1);
1140        ts++, ts_io++) {
1141     int currSlot = frame->paramSlot[ps];
1142 
1143     /*
1144      * Get new parameter set
1145      */
1146     if (ts == prevSlot + 1) {
1147       err = SpatialDecCalculateM1andM2(self, ps,
1148                                        frame); /* input: ottCLD, ottICC, ... */
1149       /* output: M1param(Real/Imag), M2(Real/Imag) */
1150       if (err != MPS_OK) {
1151         bypassMode = 1;
1152         if (self->errInt == MPS_OK) {
1153           /* store internal error befor it gets overwritten */
1154           self->errInt = err;
1155         }
1156         err = MPS_OK;
1157       }
1158 
1159       if ((ps == 0) && (self->bOverwriteM1M2prev != 0)) {
1160         /* copy matrix entries of M1/M2 of the first parameter set to the
1161            previous matrices (of the last frame). This avoids the interpolation
1162            of incompatible values. E.g. for residual bands the coefficients are
1163            calculated differently compared to non-residual bands.
1164          */
1165         SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
1166                                         /* output: M(1/2)param(Real/Imag)Prev */
1167         self->bOverwriteM1M2prev = 0;
1168       }
1169 
1170       SpatialDecSmoothM1andM2(
1171           self, frame,
1172           ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */
1173                /* output: M1param(Real/Imag), M2(Real/Imag) */
1174     }
1175 
1176     alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot));
1177 
1178     switch (mode) {
1179       case INPUTMODE_QMF_SBR:
1180         if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD)
1181           self->bShareDelayWithSBR = 0; /* We got no hybrid delay */
1182         else
1183           self->bShareDelayWithSBR = 1;
1184         SpatialDecFeedQMF(self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode,
1185                           self->qmfInputReal__FDK, self->qmfInputImag__FDK,
1186                           self->numInputChannels);
1187         break;
1188       case INPUTMODE_TIME:
1189         self->bShareDelayWithSBR = 0;
1190         SpatialDecQMFAnalysis(self, inData, ts_io, bypassMode,
1191                               self->qmfInputReal__FDK, self->qmfInputImag__FDK,
1192                               self->numInputChannels);
1193         break;
1194       default:
1195         break;
1196     }
1197 
1198     if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
1199         self->residualCoding) {
1200       int offset;
1201       ch = 1;
1202 
1203       offset = self->pQmfDomain->globalConf.nBandsSynthesis *
1204                self->pQmfDomain->globalConf.nQmfTimeSlots;
1205 
1206       {
1207         const PCM_MPS *inSamples =
1208             &inData[ts * self->pQmfDomain->globalConf.nBandsAnalysis];
1209 
1210         CalculateSpaceAnalysisQmf(
1211             &self->pQmfDomain->QmfDomainIn[ch].fb, inSamples + (ch * offset),
1212             self->qmfResidualReal__FDK[0][0], self->qmfResidualImag__FDK[0][0]);
1213 
1214         if (!isTwoChMode(self->upmixType) && !bypassMode) {
1215           int i;
1216           FIXP_DBL *RESTRICT self_qmfResidualReal__FDK_0_0 =
1217               &self->qmfResidualReal__FDK[0][0][0];
1218           FIXP_DBL *RESTRICT self_qmfResidualImag__FDK_0_0 =
1219               &self->qmfResidualImag__FDK[0][0][0];
1220 
1221           if ((self->pQmfDomain->globalConf.nBandsAnalysis == 24) &&
1222               !(self->stereoConfigIndex == 3)) {
1223             for (i = 0; i < self->qmfBands; i++) {
1224               self_qmfResidualReal__FDK_0_0[i] =
1225                   fMult(self_qmfResidualReal__FDK_0_0[i] << 1,
1226                         self->clipProtectGain__FDK);
1227               self_qmfResidualImag__FDK_0_0[i] =
1228                   fMult(self_qmfResidualImag__FDK_0_0[i] << 1,
1229                         self->clipProtectGain__FDK);
1230             }
1231           } else {
1232             for (i = 0; i < self->qmfBands; i++) {
1233               self_qmfResidualReal__FDK_0_0[i] = fMult(
1234                   self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK);
1235               self_qmfResidualImag__FDK_0_0[i] = fMult(
1236                   self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK);
1237             }
1238           }
1239         }
1240       }
1241     }
1242 
1243     SpatialDecHybridAnalysis(
1244         self, /* input: qmfInput(Real/Imag), qmfResidual(Real/Imag) */
1245         self->qmfInputReal__FDK, self->qmfInputImag__FDK,
1246         self->hybInputReal__FDK, self->hybInputImag__FDK, ts, numInputChannels);
1247 
1248     if (bypassMode) {
1249       SpatialDecApplyBypass(
1250           self, self->hybInputReal__FDK, /* input: hybInput(Real/Imag) */
1251           self->hybInputImag__FDK,
1252           self->hybOutputRealDry__FDK, /* output: hybOutput(Real/Imag)Dry */
1253           self->hybOutputImagDry__FDK, numInputChannels);
1254     } else /* !bypassMode */
1255     {
1256       FIXP_DBL *pxReal[MAX_NUM_XCHANNELS] = {NULL};
1257       FIXP_DBL *pxImag[MAX_NUM_XCHANNELS] = {NULL};
1258 
1259       SpatialDecCreateX(self,
1260                         self->hybInputReal__FDK, /* input: hybInput(Real/Imag),
1261                                                     hybResidual(Real/Imag) */
1262                         self->hybInputImag__FDK, pxReal, pxImag);
1263 
1264       {
1265         SpatialDecApplyM1_CreateW_Mode212(
1266             self, frame, pxReal, pxImag,
1267             self->wReal__FDK, /* output: w(Real/Imag) */
1268             self->wImag__FDK);
1269       }
1270       if (err != MPS_OK) goto bail;
1271 
1272       int applyM2Config = APPLY_M2_NONE;
1273 
1274       applyM2Config = APPLY_M2;
1275       if ((self->pConfigCurrent->syntaxFlags &
1276            (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
1277           (self->tempShapeConfig != 1) && (self->tempShapeConfig != 2)) {
1278         if (self->phaseCoding == 3)
1279           applyM2Config = APPLY_M2_MODE212_Res_PhaseCoding;
1280         else
1281           applyM2Config = APPLY_M2_MODE212;
1282       }
1283 
1284       switch (applyM2Config) {
1285         case APPLY_M2_MODE212: {
1286           err = SpatialDecApplyM2_Mode212(
1287               self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
1288               self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
1289         } break;
1290         case APPLY_M2_MODE212_Res_PhaseCoding:
1291           err = SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
1292               self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
1293               self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
1294           break;
1295         case APPLY_M2:
1296           err = SpatialDecApplyM2(
1297               self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
1298               self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK,
1299               self->hybOutputRealWet__FDK, self->hybOutputImagWet__FDK);
1300           break;
1301         default:
1302           err = MPS_APPLY_M2_ERROR;
1303           goto bail;
1304       }
1305 
1306       if (err != MPS_OK) goto bail;
1307 
1308       if ((self->tempShapeConfig == 2) && (!isTwoChMode(self->upmixType))) {
1309         SpatialDecReshapeBBEnv(self, frame,
1310                                ts); /* input: reshapeBBEnvState,
1311                                        hybOutput(Real/Imag)(Dry/Wet),
1312                                        hybInput(Real/Imag) */
1313       }                             /* output: hybOutput(Real/Imag)Dry */
1314 
1315       /* Merge parts of the dry and wet QMF buffers. */
1316       if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
1317         for (ch = 0; ch < self->numOutputChannels; ch++) {
1318           for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
1319             self->hybOutputRealDry__FDK[ch][hyb] +=
1320                 self->hybOutputRealWet__FDK[ch][hyb];
1321             self->hybOutputImagDry__FDK[ch][hyb] +=
1322                 self->hybOutputImagWet__FDK[ch][hyb];
1323           } /* loop hyb */
1324         }   /* loop ch */
1325         err = subbandTPApply(
1326             self, frame); /* input: hStpDec, hybOutput(Real/Imag)Dry/Wet */
1327                           /* output: hStpDec, hybOutput(Real/Imag)Dry */
1328         if (err != MPS_OK) goto bail;
1329       } /* (self->tempShapeConfig == 1) */
1330       else {
1331         /* The wet signal is added to the dry signal in applyM2 if GES and STP
1332          * are disabled */
1333         if ((self->tempShapeConfig == 1) || (self->tempShapeConfig == 2)) {
1334           int nHybBands;
1335           nHybBands = self->hybridBands;
1336 
1337           for (ch = 0; ch < self->numOutputChannels; ch++) {
1338             FIXP_DBL *RESTRICT pRealDry = self->hybOutputRealDry__FDK[ch];
1339             FIXP_DBL *RESTRICT pImagDry = self->hybOutputImagDry__FDK[ch];
1340             FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
1341             FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
1342             for (hyb = 0; hyb < nHybBands; hyb++) {
1343               pRealDry[hyb] += pRealWet[hyb];
1344               pImagDry[hyb] += pImagWet[hyb];
1345             } /* loop hyb */
1346             for (; hyb < self->hybridBands; hyb++) {
1347               pRealDry[hyb] += pRealWet[hyb];
1348             } /* loop hyb */
1349           }   /* loop ch */
1350         } /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
1351       }   /* !self->tempShapeConfig == 1 */
1352     }     /*  !bypassMode */
1353 
1354     if (self->phaseCoding == 1) {
1355       /* only if bsPhaseCoding == 1 and bsResidualCoding == 0 */
1356 
1357       SpatialDecApplyPhase(
1358           self, alpha, (ts == currSlot) /* signal the last slot of the set */
1359       );
1360     }
1361 
1362     /*
1363      * Synthesis Filtering
1364      */
1365 
1366     err = SpatialDecSynthesis(
1367         self, ts_io,
1368         self->hybOutputRealDry__FDK, /* input: hybOutput(Real/Imag)Dry */
1369         self->hybOutputImagDry__FDK, self->timeOut__FDK, /* output: timeOut */
1370         numInputChannels, mapDescr);
1371 
1372     if (err != MPS_OK) goto bail;
1373 
1374     /*
1375      * Update parameter buffer
1376      */
1377     if (ts == currSlot) {
1378       SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
1379                                       /* output: M(1/2)param(Real/Imag)Prev */
1380 
1381       prevSlot = currSlot;
1382       ps++;
1383     } /* if (ts==currSlot) */
1384 
1385   } /* ts loop */
1386 
1387   /*
1388    * Save parameter states
1389    */
1390   self->prevTimeSlot = prevSlot;
1391   self->curTimeSlot = ts;
1392   self->curPs = ps;
1393 
1394 bail:
1395 
1396   return err;
1397 }
1398 
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)1399 SACDEC_ERROR SpatialDecApplyFrame(
1400     spatialDec *self,
1401     SPATIAL_BS_FRAME *frame, /* parsed frame data to be applied */
1402     SPATIALDEC_INPUT_MODE inputMode, PCM_MPS *inData, /* Time domain input  */
1403     FIXP_DBL **qmfInDataReal,                         /* QMF domain data l/r */
1404     FIXP_DBL **qmfInDataImag,                         /* QMF domain data l/r */
1405     PCM_MPS *pcmOutBuf, /* MAX_OUTPUT_CHANNELS*MAX_TIME_SLOTS*NUM_QMF_BANDS] */
1406     UINT nSamples, UINT *pControlFlags, int numInputChannels,
1407     const FDK_channelMapDescr *const mapDescr) {
1408   SACDEC_ERROR err = MPS_OK;
1409 
1410   int fDecAndMapFrameData;
1411   int controlFlags;
1412 
1413   FDK_ASSERT(self != NULL);
1414   FDK_ASSERT(pControlFlags != NULL);
1415   FDK_ASSERT(pcmOutBuf != NULL);
1416 
1417   self->errInt = err; /* Init internal error */
1418 
1419   controlFlags = *pControlFlags;
1420 
1421   if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
1422       (self->stereoConfigIndex > 1)) {
1423     numInputChannels =
1424         1; /* Do not count residual channel as input channel. It is handled
1425               seperately. */
1426   }
1427 
1428   /* Check if input amount of channels is consistent */
1429   if (numInputChannels != self->numInputChannels) {
1430     controlFlags |= MPEGS_CONCEAL;
1431     if (numInputChannels > self->createParams.maxNumInputChannels) {
1432       return MPS_INVALID_PARAMETER;
1433     }
1434   }
1435 
1436   self->timeOut__FDK = pcmOutBuf;
1437 
1438   /* Determine local function control flags */
1439   fDecAndMapFrameData = frame->newBsData;
1440 
1441   if (((fDecAndMapFrameData ==
1442         0) /* assures that conceal flag will not be set for blind mode */
1443        && (self->curTimeSlot + (int)nSamples / self->qmfBands >
1444            self->timeSlots)) ||
1445       (frame->numParameterSets ==
1446        0)) { /* New input samples but missing side info */
1447     fDecAndMapFrameData = 1;
1448     controlFlags |= MPEGS_CONCEAL;
1449   }
1450 
1451   if ((fDecAndMapFrameData == 0) &&
1452       (frame->paramSlot[fMax(0, frame->numParameterSets - 1)] !=
1453            (self->timeSlots - 1) ||
1454        self->curTimeSlot >
1455            frame->paramSlot[self->curPs])) { /* Detected faulty parameter slot
1456                                                 data. */
1457     fDecAndMapFrameData = 1;
1458     controlFlags |= MPEGS_CONCEAL;
1459   }
1460 
1461   /* Update concealment state machine */
1462   SpatialDecConcealment_UpdateState(
1463       &self->concealInfo,
1464       (controlFlags & MPEGS_CONCEAL)
1465           ? 0
1466           : 1); /* convert from conceal flag to frame ok flag */
1467 
1468   if (fDecAndMapFrameData) {
1469     /* Reset spatial framing control vars */
1470     frame->newBsData = 0;
1471     self->prevTimeSlot = -1;
1472     self->curTimeSlot = 0;
1473     self->curPs = 0;
1474 
1475     if (controlFlags & MPEGS_CONCEAL) {
1476       /* Reset frame data to avoid misconfiguration. */
1477       SpatialDecClearFrameData(self, frame, &self->createParams);
1478     }
1479 
1480     {
1481       err = SpatialDecDecodeFrame(self, frame); /* input: ... */
1482       /* output: decodeAndMapFrameDATA */
1483     }
1484 
1485     if (err != MPS_OK) {
1486       /* Rescue strategy is to apply bypass mode in order
1487          to keep at least the downmix channels continuous. */
1488       controlFlags |= MPEGS_CONCEAL;
1489       if (self->errInt == MPS_OK) {
1490         /* store internal error befor it gets overwritten */
1491         self->errInt = err;
1492       }
1493     }
1494   }
1495 
1496   err = SpatialDecApplyParameterSets(
1497       self, frame, inputMode, inData, qmfInDataReal, qmfInDataImag, nSamples,
1498       controlFlags | ((err == MPS_OK) ? 0 : MPEGS_BYPASSMODE), numInputChannels,
1499       mapDescr);
1500   if (err != MPS_OK) {
1501     goto bail;
1502   }
1503 
1504 bail:
1505 
1506   *pControlFlags = controlFlags;
1507 
1508   return err;
1509 }
1510