Coverage Report

Created: 2026-01-09 06:47

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