Coverage Report

Created: 2025-12-31 06:47

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