Coverage Report

Created: 2025-11-16 06:35

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