Coverage Report

Created: 2025-10-13 06:42

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