Coverage Report

Created: 2026-09-07 07:09

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