Coverage Report

Created: 2026-07-25 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fdk-aac/libSACdec/src/sac_reshapeBBEnv.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 guided envelope shaping
100
101
*******************************************************************************/
102
103
#include "sac_reshapeBBEnv.h"
104
105
#include "sac_dec.h"
106
#include "sac_bitdec.h"
107
#include "sac_calcM1andM2.h"
108
#include "sac_reshapeBBEnv.h"
109
#include "sac_rom.h"
110
111
11.9M
#define INP_DRY_WET 0
112
1.19M
#define INP_DMX 1
113
114
3.32k
#define SF_SHAPE 1
115
1.19M
#define SF_DIV32 6
116
200M
#define SF_FACTOR_SLOT 5
117
118
10.7M
#define START_BB_ENV 0 /* 10 */
119
107M
#define END_BB_ENV 9   /* 18 */
120
121
2.38M
#define SF_ALPHA1 8
122
2.38M
#define SF_BETA1 4
123
124
108k
void initBBEnv(spatialDec *self, int initStatesFlag) {
125
108k
  INT ch, k;
126
127
326k
  for (ch = 0; ch < self->numOutputChannels; ch++) {
128
217k
    k = row2channelGES[self->treeConfig][ch];
129
217k
    self->row2channelDmxGES[ch] = k;
130
217k
    if (k == -1) continue;
131
132
217k
    switch (self->treeConfig) {
133
217k
      case TREE_212:
134
217k
        self->row2channelDmxGES[ch] = 0;
135
217k
        break;
136
0
      default:;
137
217k
    }
138
217k
  }
139
140
108k
  if (initStatesFlag) {
141
8.93k
    for (k = 0; k < 2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS; k++) {
142
7.44k
      self->reshapeBBEnvState->normNrgPrev__FDK[k] =
143
7.44k
          FL2FXCONST_DBL(0.5f); /* 32768.f*32768.f */
144
7.44k
      self->reshapeBBEnvState->normNrgPrevSF[k] = DFRACT_BITS - 1;
145
7.44k
      self->reshapeBBEnvState->partNrgPrevSF[k] = 0;
146
7.44k
      self->reshapeBBEnvState->partNrgPrev2SF[k] = 0;
147
7.44k
      self->reshapeBBEnvState->frameNrgPrevSF[k] = 0;
148
7.44k
    }
149
1.48k
  }
150
151
108k
  self->reshapeBBEnvState->alpha__FDK =
152
108k
      FL2FXCONST_DBL(0.99637845575f); /* FDKexp(-64 / (0.4f  * 44100)) */
153
108k
  self->reshapeBBEnvState->beta__FDK =
154
108k
      FL2FXCONST_DBL(0.96436909488f); /* FDKexp(-64 / (0.04f * 44100)) */
155
108k
}
156
157
static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
158
                                FIXP_DBL *RESTRICT pImag,
159
                                FIXP_DBL *RESTRICT slotNrg, INT maxValSF,
160
3.58M
                                INT hybBands) {
161
3.58M
  INT qs;
162
3.58M
  FIXP_DBL nrg;
163
164
  /* qs = 12, 13, 14 */
165
3.58M
  slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
166
3.58M
                (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
167
3.58M
  slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
168
3.58M
                (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
169
3.58M
  slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
170
3.58M
                (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
171
  /* qs = 15 */
172
3.58M
  slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
173
3.58M
                (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
174
  /* qs = 16, 17 */
175
3.58M
  nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
176
3.58M
         (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
177
3.58M
  slotNrg[4] =
178
3.58M
      nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
179
3.58M
             (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
180
  /* qs = 18, 19, 20 */
181
3.58M
  nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
182
3.58M
         (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
183
3.58M
  nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
184
3.58M
          (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
185
3.58M
  slotNrg[5] =
186
3.58M
      nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
187
3.58M
             (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
188
  /* qs = 21, 22 */
189
3.58M
  nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
190
3.58M
         (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
191
3.58M
  slotNrg[6] =
192
3.58M
      nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
193
3.58M
             (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
194
  /* qs = 23, 24 */
195
3.58M
  if (hybBands > 23) {
196
3.51M
    slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
197
3.51M
                   (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
198
3.51M
    slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
199
3.51M
                   (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
200
    /* qs = 25, 26, 29, 28, 29 */
201
3.51M
    nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
202
3.51M
           (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
203
3.51M
    nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
204
3.51M
            (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
205
3.51M
    nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
206
3.51M
            (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
207
3.51M
    nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
208
3.51M
            (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
209
3.51M
    slotNrg[7] =
210
3.51M
        nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
211
3.51M
               (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
212
    /* qs = 30 ... min(41,hybBands-1) */
213
3.51M
    nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
214
3.51M
           (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
215
32.8M
    for (qs = 31; qs < hybBands; qs++) {
216
29.3M
      nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
217
29.3M
              (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
218
29.3M
    }
219
3.51M
    slotNrg[8] = nrg;
220
3.51M
  } else {
221
72.7k
    slotNrg[7] = (FIXP_DBL)0;
222
72.7k
    slotNrg[8] = (FIXP_DBL)0;
223
72.7k
  }
224
3.58M
}
225
226
static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
227
                                 FIXP_DBL *RESTRICT pImag,
228
                                 FIXP_DBL *RESTRICT pHybOutputRealDry,
229
                                 FIXP_DBL *RESTRICT pHybOutputImagDry,
230
                                 FIXP_DBL *RESTRICT pHybOutputRealWet,
231
                                 FIXP_DBL *RESTRICT pHybOutputImagWet,
232
2.38M
                                 INT cplxBands, INT hybBands) {
233
2.38M
  INT qs;
234
235
66.9M
  for (qs = 12; qs < cplxBands; qs++) {
236
64.5M
    pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
237
64.5M
    pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
238
64.5M
  }
239
2.38M
  for (; qs < hybBands; qs++) {
240
0
    pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
241
0
  }
242
2.38M
}
243
244
static inline void slotAmp(
245
    FIXP_DBL *RESTRICT slotAmp_dry, INT *RESTRICT slotAmp_dry_e,
246
    FIXP_DBL *RESTRICT slotAmp_wet, INT *RESTRICT slotAmp_wet_e,
247
    FIXP_DBL *RESTRICT pHybOutputRealDry, FIXP_DBL *RESTRICT pHybOutputImagDry,
248
    FIXP_DBL *RESTRICT pHybOutputRealWet, FIXP_DBL *RESTRICT pHybOutputImagWet,
249
4.22k
    INT cplxBands, INT hybBands) {
250
4.22k
  INT qs, s1, s2, headroom_dry, headroom_wet;
251
4.22k
  FIXP_DBL dry, wet;
252
253
  /* headroom can be reduced by 1 bit due to use of fPow2Div2 */
254
4.22k
  s1 = DFRACT_BITS - 1 - CntLeadingZeros(hybBands + cplxBands);
255
4.22k
  headroom_dry = fMin(getScalefactor(pHybOutputRealDry, hybBands),
256
4.22k
                      getScalefactor(pHybOutputImagDry, cplxBands));
257
4.22k
  headroom_wet = fMin(getScalefactor(pHybOutputRealWet, hybBands),
258
4.22k
                      getScalefactor(pHybOutputImagWet, cplxBands));
259
260
4.22k
  dry = wet = FL2FXCONST_DBL(0.0f);
261
201k
  for (qs = 0; qs < cplxBands; qs++) {
262
    /* sum up dry part */
263
197k
    dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
264
197k
    dry += (fPow2Div2(pHybOutputImagDry[qs] << headroom_dry) >> s1);
265
    /* sum up wet part */
266
197k
    wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
267
197k
    wet += (fPow2Div2(pHybOutputImagWet[qs] << headroom_wet) >> s1);
268
197k
  }
269
4.22k
  for (; qs < hybBands; qs++) {
270
0
    dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
271
0
    wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
272
0
  }
273
274
  /* consider fPow2Div2() */
275
4.22k
  s1 += 1;
276
277
  /* normalize dry part, ensure that exponent is even */
278
4.22k
  s2 = fixMax(0, CntLeadingZeros(dry) - 1);
279
4.22k
  *slotAmp_dry = dry << s2;
280
4.22k
  *slotAmp_dry_e = s1 - s2 - 2 * headroom_dry;
281
4.22k
  if (*slotAmp_dry_e & 1) {
282
2.15k
    *slotAmp_dry = *slotAmp_dry >> 1;
283
2.15k
    *slotAmp_dry_e += 1;
284
2.15k
  }
285
286
  /* normalize wet part, ensure that exponent is even */
287
4.22k
  s2 = fixMax(0, CntLeadingZeros(wet) - 1);
288
4.22k
  *slotAmp_wet = wet << s2;
289
4.22k
  *slotAmp_wet_e = s1 - s2 - 2 * headroom_wet;
290
4.22k
  if (*slotAmp_wet_e & 1) {
291
2.19k
    *slotAmp_wet = *slotAmp_wet >> 1;
292
2.19k
    *slotAmp_wet_e += 1;
293
2.19k
  }
294
4.22k
}
295
296
#if defined(__aarch64__)
297
__attribute__((noinline))
298
#endif
299
static void
300
shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
301
4.22k
           FIXP_DBL dryFac, INT scale, INT cplxBands, INT hybBands) {
302
4.22k
  INT qs;
303
304
4.22k
  if (scale == 0) {
305
46.3k
    for (qs = 0; qs < cplxBands; qs++) {
306
45.2k
      pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
307
45.2k
      pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac);
308
45.2k
    }
309
1.03k
    for (; qs < hybBands; qs++) {
310
0
      pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
311
0
    }
312
3.19k
  } else {
313
155k
    for (qs = 0; qs < cplxBands; qs++) {
314
152k
      pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
315
152k
          fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
316
152k
      pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
317
152k
          fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
318
152k
    }
319
3.19k
    for (; qs < hybBands; qs++) {
320
0
      pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
321
0
          fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
322
0
    }
323
3.19k
  }
324
4.22k
}
325
326
static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
327
2.38M
                         FIXP_DBL *pEnv, const SPATIAL_BS_FRAME *frame) {
328
2.38M
  INT ch, pb, prevChOffs;
329
2.38M
  INT clz, scale, scale_min, envSF;
330
2.38M
  INT scaleCur, scalePrev, commonScale;
331
2.38M
  INT slotNrgSF, partNrgSF, frameNrgSF;
332
2.38M
  INT *pPartNrgPrevSF, *pFrameNrgPrevSF;
333
2.38M
  INT *pNormNrgPrevSF, *pPartNrgPrev2SF;
334
335
2.38M
  FIXP_DBL maxVal, env, frameNrg, normNrg;
336
2.38M
  FIXP_DBL *pReal, *pImag;
337
2.38M
  FIXP_DBL *partNrg, *partNrgPrev;
338
339
2.38M
  C_ALLOC_SCRATCH_START(pScratchBuffer, FIXP_DBL,
340
2.38M
                        (2 * 42 + MAX_PARAMETER_BANDS));
341
2.38M
  C_ALLOC_SCRATCH_START(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
342
2.38M
  C_ALLOC_SCRATCH_START(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
343
344
2.38M
  FIXP_DBL *slotNrg = pScratchBuffer + (2 * 42);
345
346
2.38M
  RESHAPE_BBENV_STATE *pBBEnvState = self->reshapeBBEnvState;
347
348
2.38M
  FIXP_DBL alpha = pBBEnvState->alpha__FDK;
349
  /*FIXP_DBL  alpha1 = (FL2FXCONST_DBL(1.0f) - alpha) << SF_ALPHA1;*/
350
2.38M
  FIXP_DBL alpha1 = ((FIXP_DBL)MAXVAL_DBL - alpha) << SF_ALPHA1;
351
2.38M
  FIXP_DBL beta = pBBEnvState->beta__FDK;
352
  /*FIXP_DBL  beta1  = (FL2FXCONST_DBL(1.0f) - beta) << SF_BETA1;*/
353
2.38M
  FIXP_DBL beta1 = ((FIXP_DBL)MAXVAL_DBL - beta) << SF_BETA1;
354
355
2.38M
  INT shapeActiv = 1;
356
2.38M
  INT hybBands = fixMin(42, self->hybridBands);
357
2.38M
  INT staticScale = self->staticDecScale + (1);
358
2.38M
  INT cplxBands;
359
2.38M
  cplxBands = fixMin(42, self->hybridBands);
360
361
5.97M
  for (ch = start; ch < channels; ch++) {
362
3.58M
    if (inp == INP_DRY_WET) {
363
2.38M
      INT ch2 = row2channelGES[self->treeConfig][ch];
364
2.38M
      if (ch2 == -1) {
365
0
        continue;
366
2.38M
      } else {
367
2.38M
        if (frame->tempShapeEnableChannelGES[ch2]) {
368
4.22k
          shapeActiv = 1;
369
2.38M
        } else {
370
2.38M
          shapeActiv = 0;
371
2.38M
        }
372
2.38M
      }
373
2.38M
      prevChOffs = ch;
374
2.38M
      pReal = pScratchBuffer;
375
2.38M
      pImag = pScratchBuffer + 42;
376
2.38M
      combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
377
2.38M
                    self->hybOutputImagDry__FDK[ch],
378
2.38M
                    self->hybOutputRealWet__FDK[ch],
379
2.38M
                    self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
380
2.38M
      clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
381
2.38M
                 getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
382
2.38M
    } else {
383
1.19M
      prevChOffs = ch + self->numOutputChannels;
384
1.19M
      pReal = self->hybInputReal__FDK[ch];
385
1.19M
      pImag = self->hybInputImag__FDK[ch];
386
1.19M
      clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
387
1.19M
                 getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
388
1.19M
    }
389
390
3.58M
    partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
391
3.58M
    pPartNrgPrevSF = &pBBEnvState->partNrgPrevSF[prevChOffs];
392
3.58M
    pFrameNrgPrevSF = &pBBEnvState->frameNrgPrevSF[prevChOffs];
393
3.58M
    pNormNrgPrevSF = &pBBEnvState->normNrgPrevSF[prevChOffs];
394
3.58M
    pPartNrgPrev2SF = &pBBEnvState->partNrgPrev2SF[prevChOffs];
395
396
    /* calculate slot energy */
397
3.58M
    {
398
3.58M
      getSlotNrgHQ(&pReal[12], &pImag[12], slotNrg, clz,
399
3.58M
                   fixMin(42, self->hybridBands)); /* scale slotNrg:
400
                                                      2*(staticScale-clz) +
401
                                                      SF_FACTOR_SLOT */
402
3.58M
    }
403
404
3.58M
    slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
405
3.58M
                SF_FACTOR_SLOT;
406
3.58M
    frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
407
3.58M
                 SF_FACTOR_SLOT;
408
409
3.58M
    partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
410
3.58M
                       pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
411
3.58M
    scalePrev = fixMax(fixMin(partNrgSF - pPartNrgPrevSF[0], DFRACT_BITS - 1),
412
3.58M
                       -(DFRACT_BITS - 1));
413
3.58M
    scaleCur =
414
3.58M
        fixMax(fixMin(partNrgSF - slotNrgSF + SF_ALPHA1, DFRACT_BITS - 1),
415
3.58M
               -(DFRACT_BITS - 1));
416
417
3.58M
    maxVal = FL2FXCONST_DBL(0.0f);
418
3.58M
    frameNrg = FL2FXCONST_DBL(0.0f);
419
3.58M
    if ((scaleCur < 0) && (scalePrev < 0)) {
420
0
      scaleCur = -scaleCur;
421
0
      scalePrev = -scalePrev;
422
0
      for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
423
0
        partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
424
0
                       (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
425
0
                      << 1;
426
0
        maxVal |= partNrg[pb];
427
0
        frameNrg += slotNrg[pb] >> 3;
428
0
      }
429
3.58M
    } else if ((scaleCur >= 0) && (scalePrev >= 0)) {
430
35.6M
      for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
431
32.0M
        partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
432
32.0M
                       (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
433
32.0M
                      << 1;
434
32.0M
        maxVal |= partNrg[pb];
435
32.0M
        frameNrg += slotNrg[pb] >> 3;
436
32.0M
      }
437
3.56M
    } else if ((scaleCur < 0) && (scalePrev >= 0)) {
438
0
      scaleCur = -scaleCur;
439
0
      for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
440
0
        partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
441
0
                       (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
442
0
                      << 1;
443
0
        maxVal |= partNrg[pb];
444
0
        frameNrg += slotNrg[pb] >> 3;
445
0
      }
446
20.2k
    } else { /* if ( (scaleCur >= 0) && (scalePrev < 0) ) */
447
20.2k
      scalePrev = -scalePrev;
448
202k
      for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
449
182k
        partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
450
182k
                       (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
451
182k
                      << 1;
452
182k
        maxVal |= partNrg[pb];
453
182k
        frameNrg += slotNrg[pb] >> 3;
454
182k
      }
455
20.2k
    }
456
457
    /* frameNrg /= (END_BB_ENV - START_BB_ENV); 0.88888888888f =
458
     * (1/(END_BB_ENV-START_BB_ENV)<<3; shift with 3 is compensated in loop
459
     * above */
460
3.58M
    frameNrg = fMult(frameNrg, FL2FXCONST_DBL(0.88888888888f));
461
462
    /* store scalefactor and headroom for part nrg prev */
463
3.58M
    pPartNrgPrevSF[0] = partNrgSF;
464
3.58M
    pPartNrgPrev2SF[0] = fixMax(0, CntLeadingZeros(maxVal) - 1);
465
466
3.58M
    commonScale = fixMax(frameNrgSF - SF_ALPHA1 + 1, pFrameNrgPrevSF[0] + 1);
467
3.58M
    scalePrev = fixMin(commonScale - pFrameNrgPrevSF[0], DFRACT_BITS - 1);
468
3.58M
    scaleCur = fixMin(commonScale - frameNrgSF + SF_ALPHA1, DFRACT_BITS - 1);
469
3.58M
    frameNrgSF = commonScale;
470
471
3.58M
    frameNrg = ((fMultDiv2(alpha1, frameNrg) >> scaleCur) +
472
3.58M
                (fMultDiv2(alpha, pBBEnvState->frameNrgPrev__FDK[prevChOffs]) >>
473
3.58M
                 scalePrev))
474
3.58M
               << 1;
475
476
3.58M
    clz = fixMax(0, CntLeadingZeros(frameNrg) - 1);
477
3.58M
    pBBEnvState->frameNrgPrev__FDK[prevChOffs] = frameNrg << clz;
478
3.58M
    pFrameNrgPrevSF[0] = frameNrgSF - clz;
479
480
3.58M
    env = FL2FXCONST_DBL(0.0f);
481
3.58M
    scale = clz + partNrgSF - frameNrgSF;
482
3.58M
    scale_min = DFRACT_BITS - 1;
483
35.8M
    for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
484
32.2M
      if ((partNrg[pb] | slotNrg[pb]) != FL2FXCONST_DBL(0.0f)) {
485
31.4M
        INT s;
486
31.4M
        INT sc = 0;
487
31.4M
        INT sn = fixMax(0, CntLeadingZeros(slotNrg[pb]) - 1);
488
31.4M
        FIXP_DBL inv_sqrt = invSqrtNorm2(partNrg[pb], &sc);
489
31.4M
        FIXP_DBL res = fMult(slotNrg[pb] << sn, fPow2(inv_sqrt));
490
491
31.4M
        s = fixMax(0, CntLeadingZeros(res) - 1);
492
31.4M
        res = res << s;
493
494
31.4M
        sc = scale - (2 * sc - sn - s);
495
31.4M
        scale_min = fixMin(scale_min, sc);
496
497
31.4M
        resPb[pb] = res;
498
31.4M
        resPbSF[pb] = sc;
499
31.4M
      } else {
500
823k
        resPb[pb] = (FIXP_DBL)0;
501
823k
        resPbSF[pb] = 0;
502
823k
      }
503
32.2M
    }
504
505
3.58M
    scale_min = 4 - scale_min;
506
507
35.8M
    for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
508
32.2M
      INT sc = fixMax(fixMin(resPbSF[pb] + scale_min, DFRACT_BITS - 1),
509
32.2M
                      -(DFRACT_BITS - 1));
510
511
32.2M
      if (sc < 0) {
512
731k
        env += resPb[pb] << (-sc);
513
31.5M
      } else {
514
31.5M
        env += resPb[pb] >> (sc);
515
31.5M
      }
516
32.2M
    }
517
518
3.58M
    env = fMultDiv2(env, pBBEnvState->frameNrgPrev__FDK[prevChOffs]);
519
3.58M
    envSF = slotNrgSF + scale_min + 1;
520
521
3.58M
    commonScale = fixMax(envSF - SF_BETA1 + 1, pNormNrgPrevSF[0] + 1);
522
3.58M
    scalePrev = fixMin(commonScale - pNormNrgPrevSF[0], DFRACT_BITS - 1);
523
3.58M
    scaleCur = fixMin(commonScale - envSF + SF_BETA1, DFRACT_BITS - 1);
524
525
3.58M
    normNrg = ((fMultDiv2(beta1, env) >> scaleCur) +
526
3.58M
               (fMultDiv2(beta, pBBEnvState->normNrgPrev__FDK[prevChOffs]) >>
527
3.58M
                scalePrev))
528
3.58M
              << 1;
529
530
3.58M
    clz = fixMax(0, CntLeadingZeros(normNrg) - 1);
531
3.58M
    pBBEnvState->normNrgPrev__FDK[prevChOffs] = normNrg << clz;
532
3.58M
    pNormNrgPrevSF[0] = commonScale - clz;
533
534
3.58M
    if (shapeActiv) {
535
1.19M
      if ((env | normNrg) != FL2FXCONST_DBL(0.0f)) {
536
1.19M
        INT sc, se, sn;
537
1.19M
        se = fixMax(0, CntLeadingZeros(env) - 1);
538
1.19M
        sc = commonScale + SF_DIV32 - envSF + se;
539
1.19M
        env = fMult(sqrtFixp((env << se) >> (sc & 0x1)),
540
1.19M
                    invSqrtNorm2(normNrg, &sn));
541
542
1.19M
        sc = fixMin((sc >> 1) - sn, DFRACT_BITS - 1);
543
1.19M
        if (sc < 0) {
544
135
          env <<= (-sc);
545
1.19M
        } else {
546
1.19M
          env >>= (sc);
547
1.19M
        }
548
1.19M
      }
549
      /* env is scaled by SF_DIV32/2 bits */
550
1.19M
    }
551
3.58M
    pEnv[ch] = env;
552
3.58M
  }
553
554
2.38M
  C_ALLOC_SCRATCH_END(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
555
2.38M
  C_ALLOC_SCRATCH_END(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
556
2.38M
  C_ALLOC_SCRATCH_END(pScratchBuffer, FIXP_DBL, (2 * 42 + MAX_PARAMETER_BANDS));
557
2.38M
}
558
559
void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
560
1.19M
                            INT ts) {
561
1.19M
  INT ch, scale;
562
1.19M
  INT dryFacSF, slotAmpSF;
563
1.19M
  INT slotAmp_dry_e, slotAmp_wet_e;
564
1.19M
  FIXP_DBL tmp, dryFac, envShape;
565
1.19M
  FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
566
1.19M
  FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
567
568
1.19M
  INT cplxBands;
569
1.19M
  INT hybBands = self->hybridBands - 6;
570
571
1.19M
  cplxBands = self->hybridBands - 6;
572
573
  /* extract downmix envelope(s) */
574
1.19M
  switch (self->treeConfig) {
575
1.19M
    default:
576
1.19M
      extractBBEnv(self, INP_DMX, 0, fMin(self->numInputChannels, 2), envDmx,
577
1.19M
                   frame);
578
1.19M
  }
579
580
  /* extract dry and wet envelopes */
581
1.19M
  extractBBEnv(self, INP_DRY_WET, 0, self->numOutputChannels, envDry, frame);
582
583
3.58M
  for (ch = 0; ch < self->numOutputChannels; ch++) {
584
2.38M
    INT ch2;
585
586
2.38M
    ch2 = row2channelGES[self->treeConfig][ch];
587
588
2.38M
    if (ch2 == -1) continue;
589
590
2.38M
    if (frame->tempShapeEnableChannelGES[ch2]) {
591
4.22k
      INT sc;
592
593
      /* reshape dry and wet signals according to transmitted envelope */
594
595
      /* De-quantize GES data */
596
4.22k
      FDK_ASSERT((frame->bsEnvShapeData[ch2][ts] >= 0) &&
597
4.22k
                 (frame->bsEnvShapeData[ch2][ts] <= 4));
598
4.22k
      FDK_ASSERT((self->envQuantMode == 0) || (self->envQuantMode == 1));
599
4.22k
      envShape =
600
4.22k
          FX_CFG2FX_DBL(envShapeDataTable__FDK[frame->bsEnvShapeData[ch2][ts]]
601
4.22k
                                              [self->envQuantMode]);
602
603
      /* get downmix channel */
604
4.22k
      ch2 = self->row2channelDmxGES[ch];
605
606
      /* multiply ratio with dmx envelope; tmp is scaled by SF_DIV32/2+SF_SHAPE
607
       * bits */
608
4.22k
      if (ch2 == 2) {
609
0
        tmp = fMultDiv2(envShape, envDmx[0]) + fMultDiv2(envShape, envDmx[1]);
610
4.22k
      } else {
611
4.22k
        tmp = fMult(envShape, envDmx[ch2]);
612
4.22k
      }
613
614
      /* weighting factors */
615
4.22k
      dryFacSF = slotAmpSF = 0;
616
4.22k
      dryFac = slotAmp_ratio = FL2FXCONST_DBL(0.0f);
617
618
      /* dryFac will be scaled by dryFacSF bits */
619
4.22k
      if (envDry[ch] != FL2FXCONST_DBL(0.0f)) {
620
3.32k
        envDry[ch] = invSqrtNorm2(envDry[ch], &dryFacSF);
621
3.32k
        dryFac = fMultDiv2(tmp, fPow2Div2(envDry[ch])) << 2;
622
3.32k
        dryFacSF = SF_SHAPE + 2 * dryFacSF;
623
3.32k
      }
624
625
4.22k
      slotAmp_dry_e = slotAmp_wet_e = 0;
626
627
      /* calculate slotAmp_dry and slotAmp_wet */
628
4.22k
      slotAmp(&slotAmp_dry, &slotAmp_dry_e, &slotAmp_wet, &slotAmp_wet_e,
629
4.22k
              &self->hybOutputRealDry__FDK[ch][6],
630
4.22k
              &self->hybOutputImagDry__FDK[ch][6],
631
4.22k
              &self->hybOutputRealWet__FDK[ch][6],
632
4.22k
              &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
633
634
      /* exponents must be even due to subsequent square root calculation */
635
4.22k
      FDK_ASSERT(((slotAmp_dry_e & 1) == 0) && ((slotAmp_wet_e & 1) == 0));
636
637
      /* slotAmp_ratio will be scaled by slotAmpSF bits */
638
4.22k
      if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
639
3.39k
        slotAmp_wet = sqrtFixp(slotAmp_wet);
640
3.39k
        slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
641
642
3.39k
        slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
643
3.39k
        slotAmpSF = slotAmpSF + (slotAmp_wet_e >> 1) - (slotAmp_dry_e >> 1);
644
3.39k
      }
645
646
      /* calculate common scale factor */
647
4.22k
      scale =
648
4.22k
          fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
649
                                                     bits to avoid overflows
650
                                                     when calculating dryFac  */
651
4.22k
      dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
652
4.22k
      slotAmp_ratio =
653
4.22k
          slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
654
655
      /* limit dryFac */
656
4.22k
      dryFac = fixMax(
657
4.22k
          FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
658
4.22k
          fMult(dryFac, slotAmp_ratio) -
659
4.22k
              (slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
660
4.22k
              (dryFac >> fixMin(scale, DFRACT_BITS - 1)));
661
4.22k
      dryFac = fixMin(
662
4.22k
          FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
663
4.22k
          dryFac); /* reduce shift bits by 3, because upper
664
                      limit 4.0 is scaled with 3 bits */
665
4.22k
      scale = 2 * scale + 1;
666
667
      /* improve precision for dryFac */
668
4.22k
      sc = fixMax(0, CntLeadingZeros(dryFac) - 1);
669
4.22k
      dryFac = dryFac << (INT)fixMin(scale, sc);
670
4.22k
      scale = scale - fixMin(scale, sc);
671
672
      /* shaping */
673
4.22k
      shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
674
4.22k
                 &self->hybOutputImagDry__FDK[ch][6], dryFac,
675
4.22k
                 fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
676
4.22k
    }
677
2.38M
  }
678
1.19M
}