Coverage Report

Created: 2026-01-10 06:15

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