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