Coverage Report

Created: 2025-08-26 06:47

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