Coverage Report

Created: 2023-06-17 06:21

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