Coverage Report

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