Coverage Report

Created: 2025-10-28 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libSACdec/src/sac_stp.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2021 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 Dec subband processing
100
101
*******************************************************************************/
102
103
#include "sac_stp.h"
104
#include "sac_calcM1andM2.h"
105
#include "sac_bitdec.h"
106
#include "FDK_matrixCalloc.h"
107
#include "sac_rom.h"
108
109
2.20M
#define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
110
111
15.4M
#define BP_GF_START 6
112
733k
#define BP_GF_SIZE 25
113
55.6k
#define HP_SIZE 9
114
733k
#define STP_UPDATE_ENERGY_RATE 32
115
116
#define SF_WET 5
117
#define SF_DRY \
118
0
  3 /* SF_DRY == 2 would produce good conformance test results as well */
119
#define SF_DRY_NRG                                                           \
120
14.6M
  (4 - 1) /* 8.495f = sum(BP_GF__FDK[i])                                     \
121
             i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy        \
122
             calculation needs 4 bits headroom, headroom can be reduced by 1 \
123
             bit due to fPow2Div2() usage */
124
#define SF_WET_NRG                                                           \
125
29.3M
  (4 - 1) /* 8.495f = sum(BP_GF__FDK[i])                                     \
126
             i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy        \
127
             calculation needs 4 bits headroom, headroom can be reduced by 1 \
128
             bit due to fPow2Div2() usage */
129
#define SF_PRODUCT_BP_GF 13
130
#define SF_PRODUCT_BP_GF_GF 26
131
#define SF_SCALE 2
132
133
57.6k
#define SF_SCALE_LD64 FL2FXCONST_DBL(0.03125)      /* LD64((1<<SF_SCALE))*/
134
2.20M
#define STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.950f) /* 0.95 */
135
2.20M
#define ONE_MINUS_STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.05f) /* 1.0 - 0.95 */
136
1.46M
#define STP_LPF_COEFF2__FDK FL2FXCONST_DBL(0.450f)          /* 0.45 */
137
#define ONE_MINUS_STP_LPF_COEFF2__FDK \
138
1.46M
  FL2FXCONST_DBL(1.0f - 0.450f) /* 1.0 - 0.45 */
139
#define STP_SCALE_LIMIT__FDK \
140
1.46M
  FL2FXCONST_DBL(2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE */
141
#define ONE_DIV_STP_SCALE_LIMIT__FDK                                          \
142
2.53M
  FL2FXCONST_DBL(1.0f / 2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE \
143
                                                         */
144
#define ABS_THR__FDK       \
145
  FL2FXCONST_DBL(ABS_THR / \
146
                 ((float)(1 << (22 + 22 - 26)))) /* scaled by 18 bits */
147
#define ABS_THR2__FDK                      \
148
  FL2FXCONST_DBL(ABS_THR * 32.0f * 32.0f / \
149
                 ((float)(1 << (22 + 22 - 26)))) /* scaled by 10 bits */
150
#define STP_SCALE_LIMIT_HI \
151
338k
  FL2FXCONST_DBL(3.02222222222 / (1 << SF_SCALE)) /* see 4. below */
152
#define STP_SCALE_LIMIT_LO \
153
5.91k
  FL2FXCONST_DBL(0.28289992119 / (1 << SF_SCALE)) /* see 4. below */
154
#define STP_SCALE_LIMIT_HI_LD64                 \
155
402k
  FL2FXCONST_DBL(0.04986280452) /* see 4. below \
156
                                 */
157
#define STP_SCALE_LIMIT_LO_LD64                 \
158
63.5k
  FL2FXCONST_DBL(0.05692613500) /* see 4. below \
159
                                 */
160
161
/*  Scale factor calculation for the diffuse signal needs adapted thresholds
162
    for STP_SCALE_LIMIT and 1/STP_SCALE_LIMIT:
163
164
    1. scale = sqrt(DryNrg/WetNrg)
165
166
    2. Damping of scale factor
167
       scale2 = 0.1 + 0.9 * scale
168
169
    3. Limiting of scale factor
170
          STP_SCALE_LIMIT           >=        scale2        >= 1/STP_SCALE_LIMIT
171
       => STP_SCALE_LIMIT           >=  (0.1 + 0.9 * scale) >= 1/STP_SCALE_LIMIT
172
       => (STP_SCALE_LIMIT-0.1)/0.9 >=        scale         >=
173
   (1/STP_SCALE_LIMIT-0.1)/0.9
174
175
    3. Limiting of scale factor before sqrt calculation
176
       ((STP_SCALE_LIMIT-0.1)/0.9)^2 >= (scale^2) >=
177
   ((1/STP_SCALE_LIMIT-0.1)/0.9)^2 (STP_SCALE_LIMIT_HI)^2        >= (scale^2) >=
178
   (STP_SCALE_LIMIT_LO)^2
179
180
    4. Thresholds for limiting of scale factor
181
       STP_SCALE_LIMIT_HI      = ((2.82-0.1)/0.9)
182
       STP_SCALE_LIMIT_LO      = (((1.0/2.82)-0.1)/0.9)
183
       STP_SCALE_LIMIT_HI_LD64 = LD64(STP_SCALE_LIMIT_HI*STP_SCALE_LIMIT_HI)
184
       STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
185
*/
186
187
#define CALC_WET_SCALE(dryIdx, wetIdx)                                         \
188
402k
  if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
189
338k
    scale[wetIdx] = STP_SCALE_LIMIT_HI;                                        \
190
338k
  } else if (DryEnerLD64[dryIdx] <                                             \
191
63.5k
             (WetEnerLD64[wetIdx] - STP_SCALE_LIMIT_LO_LD64)) {                \
192
5.91k
    scale[wetIdx] = STP_SCALE_LIMIT_LO;                                        \
193
57.6k
  } else {                                                                     \
194
57.6k
    tmp = ((DryEnerLD64[dryIdx] - WetEnerLD64[wetIdx]) >> 1) - SF_SCALE_LD64;  \
195
57.6k
    scale[wetIdx] = CalcInvLdData(tmp);                                        \
196
57.6k
  }
197
198
struct STP_DEC {
199
  FIXP_DBL runDryEner[MAX_INPUT_CHANNELS];
200
  FIXP_DBL runWetEner[MAX_OUTPUT_CHANNELS];
201
  FIXP_DBL oldDryEnerLD64[MAX_INPUT_CHANNELS];
202
  FIXP_DBL oldWetEnerLD64[MAX_OUTPUT_CHANNELS];
203
  FIXP_DBL prev_tp_scale[MAX_OUTPUT_CHANNELS];
204
  const FIXP_CFG *BP;
205
  const FIXP_CFG *BP_GF;
206
  int update_old_ener;
207
};
208
209
inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
210
                              FIXP_DBL *hybOutputImagDry,
211
                              FIXP_DBL *hybOutputRealWet,
212
1.45M
                              FIXP_DBL *hybOutputImagWet, int bands) {
213
1.45M
  int n;
214
215
36.8M
  for (n = bands - 1; n >= 0; n--) {
216
35.3M
    *hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet);
217
35.3M
    *hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet);
218
35.3M
    hybOutputRealDry++, hybOutputRealWet++;
219
35.3M
    hybOutputImagDry++, hybOutputImagWet++;
220
35.3M
  }
221
1.45M
}
222
223
inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
224
                                    FIXP_DBL *hybOutputImagDry,
225
                                    FIXP_DBL *hybOutputRealWet,
226
                                    FIXP_DBL *hybOutputImagWet,
227
                                    const FIXP_CFG *pBP, FIXP_DBL scaleX,
228
9.28k
                                    int bands) {
229
9.28k
  int n;
230
9.28k
  FIXP_DBL scaleY;
231
37.1k
  for (n = bands - 1; n >= 0; n--) {
232
27.8k
    scaleY = fMult(scaleX, *pBP);
233
27.8k
    *hybOutputRealDry = SATURATE_LEFT_SHIFT(
234
27.8k
        (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleY),
235
27.8k
        SF_SCALE, DFRACT_BITS);
236
27.8k
    *hybOutputImagDry = SATURATE_LEFT_SHIFT(
237
27.8k
        (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleY),
238
27.8k
        SF_SCALE, DFRACT_BITS);
239
27.8k
    hybOutputRealDry++, hybOutputRealWet++;
240
27.8k
    hybOutputImagDry++, hybOutputImagWet++;
241
27.8k
    pBP++;
242
27.8k
  }
243
9.28k
}
244
245
inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry,
246
                                    FIXP_DBL *hybOutputImagDry,
247
                                    FIXP_DBL *hybOutputRealWet,
248
                                    FIXP_DBL *hybOutputImagWet, FIXP_DBL scaleX,
249
9.28k
                                    int bands) {
250
9.28k
  int n;
251
252
447k
  for (n = bands - 1; n >= 0; n--) {
253
438k
    *hybOutputRealDry = SATURATE_LEFT_SHIFT(
254
438k
        (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleX),
255
438k
        SF_SCALE, DFRACT_BITS);
256
438k
    *hybOutputImagDry = SATURATE_LEFT_SHIFT(
257
438k
        (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleX),
258
438k
        SF_SCALE, DFRACT_BITS);
259
438k
    hybOutputRealDry++, hybOutputRealWet++;
260
438k
    hybOutputImagDry++, hybOutputImagWet++;
261
438k
  }
262
9.28k
}
263
264
/*******************************************************************************
265
 Functionname: subbandTPCreate
266
 ******************************************************************************/
267
27.1k
SACDEC_ERROR subbandTPCreate(HANDLE_STP_DEC *hStpDec) {
268
27.1k
  HANDLE_STP_DEC self = NULL;
269
27.1k
  FDK_ALLOCATE_MEMORY_1D(self, 1, struct STP_DEC)
270
27.1k
  if (hStpDec != NULL) {
271
27.1k
    *hStpDec = self;
272
27.1k
  }
273
274
27.1k
  return MPS_OK;
275
0
bail:
276
0
  return MPS_OUTOFMEMORY;
277
27.1k
}
278
279
71.3k
SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
280
71.3k
  SACDEC_ERROR err = MPS_OK;
281
71.3k
  int ch;
282
283
214k
  for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
284
142k
    self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
285
142k
    self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
286
142k
  }
287
142k
  for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
288
71.3k
    self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
289
71.3k
  }
290
291
71.3k
  self->BP = BP__FDK;
292
71.3k
  self->BP_GF = BP_GF__FDK;
293
294
71.3k
  self->update_old_ener = 0;
295
296
71.3k
  return err;
297
71.3k
}
298
299
/*******************************************************************************
300
 Functionname: subbandTPDestroy
301
 ******************************************************************************/
302
27.1k
void subbandTPDestroy(HANDLE_STP_DEC *hStpDec) {
303
27.1k
  if (hStpDec != NULL) {
304
27.1k
    FDK_FREE_MEMORY_1D(*hStpDec);
305
27.1k
  }
306
27.1k
}
307
308
/*******************************************************************************
309
 Functionname: subbandTPApply
310
 ******************************************************************************/
311
733k
SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
312
733k
  FIXP_DBL *qmfOutputRealDry[MAX_OUTPUT_CHANNELS];
313
733k
  FIXP_DBL *qmfOutputImagDry[MAX_OUTPUT_CHANNELS];
314
733k
  FIXP_DBL *qmfOutputRealWet[MAX_OUTPUT_CHANNELS];
315
733k
  FIXP_DBL *qmfOutputImagWet[MAX_OUTPUT_CHANNELS];
316
317
733k
  FIXP_DBL DryEner[MAX_INPUT_CHANNELS];
318
733k
  FIXP_DBL scale[MAX_OUTPUT_CHANNELS];
319
320
733k
  FIXP_DBL DryEnerLD64[MAX_INPUT_CHANNELS];
321
733k
  FIXP_DBL WetEnerLD64[MAX_OUTPUT_CHANNELS];
322
323
733k
  FIXP_DBL DryEner0 = FL2FXCONST_DBL(0.0f);
324
733k
  FIXP_DBL WetEnerX, damp, tmp;
325
733k
  FIXP_DBL dmxReal0, dmxImag0;
326
733k
  int skipChannels[MAX_OUTPUT_CHANNELS];
327
733k
  int n, ch, cplxBands, cplxHybBands;
328
733k
  int dry_scale_dmx, wet_scale_dmx;
329
733k
  int i_LF, i_RF;
330
733k
  HANDLE_STP_DEC hStpDec;
331
733k
  const FIXP_CFG *pBP;
332
333
733k
  int nrgScale = (2 * self->clipProtectGainSF__FDK);
334
335
733k
  hStpDec = self->hStpDec;
336
337
  /* set scalefactor and loop counter */
338
733k
  FDK_ASSERT(SF_DRY >= 1);
339
733k
  {
340
733k
    cplxBands = BP_GF_SIZE;
341
733k
    cplxHybBands = self->hybridBands;
342
733k
    if (self->treeConfig == TREE_212) {
343
733k
      dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2()
344
                            used in energy calculation */
345
733k
    } else {
346
0
      dry_scale_dmx = (2 * SF_DRY) - 2;
347
0
    }
348
733k
    wet_scale_dmx = 2;
349
733k
  }
350
351
  /* setup pointer for forming the direct downmix signal */
352
2.20M
  for (ch = 0; ch < self->numOutputChannels; ch++) {
353
1.46M
    qmfOutputRealDry[ch] = &self->hybOutputRealDry__FDK[ch][7];
354
1.46M
    qmfOutputRealWet[ch] = &self->hybOutputRealWet__FDK[ch][7];
355
1.46M
    qmfOutputImagDry[ch] = &self->hybOutputImagDry__FDK[ch][7];
356
1.46M
    qmfOutputImagWet[ch] = &self->hybOutputImagWet__FDK[ch][7];
357
1.46M
  }
358
359
  /* clear skipping flag for all output channels */
360
733k
  FDKmemset(skipChannels, 0, self->numOutputChannels * sizeof(int));
361
362
  /* set scale values to zero */
363
733k
  FDKmemset(scale, 0, self->numOutputChannels * sizeof(FIXP_DBL));
364
365
  /* update normalisation energy with latest smoothed energy */
366
733k
  if (hStpDec->update_old_ener == STP_UPDATE_ENERGY_RATE) {
367
7.37k
    hStpDec->update_old_ener = 1;
368
14.7k
    for (ch = 0; ch < self->numInputChannels; ch++) {
369
7.37k
      hStpDec->oldDryEnerLD64[ch] =
370
7.37k
          CalcLdData(fAddSaturate(hStpDec->runDryEner[ch], ABS_THR__FDK));
371
7.37k
    }
372
22.1k
    for (ch = 0; ch < self->numOutputChannels; ch++) {
373
14.7k
      if (self->treeConfig == TREE_212)
374
14.7k
        hStpDec->oldWetEnerLD64[ch] =
375
14.7k
            CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR__FDK));
376
0
      else
377
0
        hStpDec->oldWetEnerLD64[ch] =
378
0
            CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR2__FDK));
379
14.7k
    }
380
726k
  } else {
381
726k
    hStpDec->update_old_ener++;
382
726k
  }
383
384
  /* get channel configuration */
385
733k
  switch (self->treeConfig) {
386
733k
    case TREE_212:
387
733k
      i_LF = 0;
388
733k
      i_RF = 1;
389
733k
      break;
390
0
    default:
391
0
      return MPS_WRONG_TREECONFIG;
392
733k
  }
393
394
  /* form the 'direct' downmix signal */
395
733k
  pBP = hStpDec->BP_GF - BP_GF_START;
396
733k
  switch (self->treeConfig) {
397
733k
    case TREE_212:
398
733k
      INT sMin, sNorm, sReal, sImag;
399
400
733k
      sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
401
733k
                                  cplxBands - BP_GF_START),
402
733k
                   getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
403
733k
                                  cplxBands - BP_GF_START));
404
733k
      sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
405
733k
                                  cplxBands - BP_GF_START),
406
733k
                   getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
407
733k
                                  cplxBands - BP_GF_START));
408
733k
      sMin = fMin(sReal, sImag) - 1;
409
410
14.6M
      for (n = BP_GF_START; n < cplxBands; n++) {
411
13.9M
        dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
412
13.9M
                   scaleValue(qmfOutputRealDry[i_RF][n], sMin);
413
13.9M
        dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
414
13.9M
                   scaleValue(qmfOutputImagDry[i_RF][n], sMin);
415
416
13.9M
        DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
417
13.9M
                     fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
418
13.9M
                    SF_DRY_NRG;
419
13.9M
      }
420
421
733k
      sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
422
733k
              (2 * sMin) + nrgScale;
423
733k
      DryEner0 = scaleValueSaturate(
424
733k
          DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
425
733k
      break;
426
0
    default:;
427
733k
  }
428
733k
  DryEner[0] = DryEner0;
429
430
  /* normalise the 'direct' signals */
431
1.46M
  for (ch = 0; ch < self->numInputChannels; ch++) {
432
733k
    if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
433
733k
    hStpDec->runDryEner[ch] =
434
733k
        fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
435
733k
        fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
436
733k
    if (DryEner[ch] != FL2FXCONST_DBL(0.0f)) {
437
201k
      DryEnerLD64[ch] =
438
201k
          fixMax((CalcLdData(DryEner[ch]) - hStpDec->oldDryEnerLD64[ch]),
439
201k
                 FL2FXCONST_DBL(-0.484375f));
440
532k
    } else {
441
532k
      DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
442
532k
    }
443
733k
  }
444
733k
  for (; ch < MAX_INPUT_CHANNELS; ch++) {
445
0
    DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
446
0
  }
447
448
  /* normalise the 'diffuse' signals */
449
733k
  pBP = hStpDec->BP_GF - BP_GF_START;
450
2.20M
  for (ch = 0; ch < self->numOutputChannels; ch++) {
451
1.46M
    if (skipChannels[ch]) {
452
0
      continue;
453
0
    }
454
455
1.46M
    WetEnerX = FL2FXCONST_DBL(0.0f);
456
457
1.46M
    if (self->treeConfig == TREE_212) {
458
1.46M
      INT sMin, sNorm;
459
460
1.46M
      sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START],
461
1.46M
                                 cplxBands - BP_GF_START),
462
1.46M
                  getScalefactor(&qmfOutputImagWet[ch][BP_GF_START],
463
1.46M
                                 cplxBands - BP_GF_START));
464
465
29.3M
      for (n = BP_GF_START; n < cplxBands; n++) {
466
27.8M
        WetEnerX +=
467
27.8M
            (fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)),
468
27.8M
                       pBP[n]) +
469
27.8M
             fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)),
470
27.8M
                       pBP[n])) >>
471
27.8M
            SF_WET_NRG;
472
27.8M
      }
473
1.46M
      sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx -
474
1.46M
              (2 * sMin) + nrgScale;
475
1.46M
      WetEnerX = scaleValueSaturate(
476
1.46M
          WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
477
1.46M
    } else
478
1.46M
      FDK_ASSERT(self->treeConfig == TREE_212);
479
480
1.46M
    hStpDec->runWetEner[ch] =
481
1.46M
        fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
482
1.46M
        fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
483
484
1.46M
    if (WetEnerX == FL2FXCONST_DBL(0.0f)) {
485
1.41M
      WetEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
486
1.41M
    } else {
487
48.7k
      WetEnerLD64[ch] =
488
48.7k
          fixMax((CalcLdData(WetEnerX) - hStpDec->oldWetEnerLD64[ch]),
489
48.7k
                 FL2FXCONST_DBL(-0.484375f));
490
48.7k
    }
491
1.46M
  }
492
493
  /* compute scale factor for the 'diffuse' signals */
494
733k
  switch (self->treeConfig) {
495
733k
    case TREE_212:
496
733k
      if (DryEner[0] != FL2FXCONST_DBL(0.0f)) {
497
201k
        CALC_WET_SCALE(0, i_LF);
498
201k
        CALC_WET_SCALE(0, i_RF);
499
201k
      }
500
733k
      break;
501
0
    default:;
502
733k
  }
503
504
733k
  damp = FL2FXCONST_DBL(0.1f / (1 << SF_SCALE));
505
2.20M
  for (ch = 0; ch < self->numOutputChannels; ch++) {
506
    /* damp the scaling factor */
507
1.46M
    scale[ch] = damp + fMult(FL2FXCONST_DBL(0.9f), scale[ch]);
508
509
    /* limiting the scale factor */
510
1.46M
    if (scale[ch] > STP_SCALE_LIMIT__FDK) {
511
0
      scale[ch] = STP_SCALE_LIMIT__FDK;
512
0
    }
513
1.46M
    if (scale[ch] < ONE_DIV_STP_SCALE_LIMIT__FDK) {
514
1.07M
      scale[ch] = ONE_DIV_STP_SCALE_LIMIT__FDK;
515
1.07M
    }
516
517
    /* low pass filter the scaling factor */
518
1.46M
    scale[ch] =
519
1.46M
        fMult(STP_LPF_COEFF2__FDK, scale[ch]) +
520
1.46M
        fMult(ONE_MINUS_STP_LPF_COEFF2__FDK, hStpDec->prev_tp_scale[ch]);
521
1.46M
    hStpDec->prev_tp_scale[ch] = scale[ch];
522
1.46M
  }
523
524
  /* combine 'direct' and scaled 'diffuse' signal */
525
733k
  FDK_ASSERT((HP_SIZE - 3 + 10 - 1) == PC_NUM_HYB_BANDS);
526
733k
  const SCHAR *channlIndex = row2channelSTP[self->treeConfig];
527
528
2.20M
  for (ch = 0; ch < self->numOutputChannels; ch++) {
529
1.46M
    int no_scaling;
530
531
1.46M
    no_scaling = !frame->tempShapeEnableChannelSTP[channlIndex[ch]];
532
1.46M
    if (no_scaling) {
533
1.45M
      combineSignalCplx(
534
1.45M
          &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
535
1.45M
          &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
536
1.45M
          &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
537
1.45M
          &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
538
1.45M
          cplxHybBands - self->tp_hybBandBorder);
539
540
1.45M
    } else {
541
9.28k
      FIXP_DBL scaleX;
542
9.28k
      scaleX = scale[ch];
543
9.28k
      pBP = hStpDec->BP - self->tp_hybBandBorder;
544
      /* Band[HP_SIZE-3+10-1] needs not to be processed in
545
         combineSignalCplxScale1(), because pB[HP_SIZE-3+10-1] would be 1.0 */
546
9.28k
      combineSignalCplxScale1(
547
9.28k
          &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
548
9.28k
          &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
549
9.28k
          &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
550
9.28k
          &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
551
9.28k
          &pBP[self->tp_hybBandBorder], scaleX,
552
9.28k
          (HP_SIZE - 3 + 10 - 1) - self->tp_hybBandBorder);
553
554
9.28k
      {
555
9.28k
        combineSignalCplxScale2(
556
9.28k
            &self->hybOutputRealDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
557
9.28k
            &self->hybOutputImagDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
558
9.28k
            &self->hybOutputRealWet__FDK[ch][HP_SIZE - 3 + 10 - 1],
559
9.28k
            &self->hybOutputImagWet__FDK[ch][HP_SIZE - 3 + 10 - 1], scaleX,
560
9.28k
            cplxHybBands - (HP_SIZE - 3 + 10 - 1));
561
9.28k
      }
562
9.28k
    }
563
1.46M
  }
564
565
733k
  return (SACDEC_ERROR)MPS_OK;
566
0
  ;
567
0
}