• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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,INT * RESTRICT slotAmp_dry_e,FIXP_DBL * RESTRICT slotAmp_wet,INT * RESTRICT slotAmp_wet_e,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(
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     INT cplxBands, INT hybBands) {
250   INT qs, s1, s2, headroom_dry, headroom_wet;
251   FIXP_DBL dry, wet;
252 
253   /* headroom can be reduced by 1 bit due to use of fPow2Div2 */
254   s1 = DFRACT_BITS - 1 - CntLeadingZeros(hybBands + cplxBands);
255   headroom_dry = fMin(getScalefactor(pHybOutputRealDry, hybBands),
256                       getScalefactor(pHybOutputImagDry, cplxBands));
257   headroom_wet = fMin(getScalefactor(pHybOutputRealWet, hybBands),
258                       getScalefactor(pHybOutputImagWet, cplxBands));
259 
260   dry = wet = FL2FXCONST_DBL(0.0f);
261   for (qs = 0; qs < cplxBands; qs++) {
262     /* sum up dry part */
263     dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
264     dry += (fPow2Div2(pHybOutputImagDry[qs] << headroom_dry) >> s1);
265     /* sum up wet part */
266     wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
267     wet += (fPow2Div2(pHybOutputImagWet[qs] << headroom_wet) >> s1);
268   }
269   for (; qs < hybBands; qs++) {
270     dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
271     wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
272   }
273 
274   /* consider fPow2Div2() */
275   s1 += 1;
276 
277   /* normalize dry part, ensure that exponent is even */
278   s2 = fixMax(0, CntLeadingZeros(dry) - 1);
279   *slotAmp_dry = dry << s2;
280   *slotAmp_dry_e = s1 - s2 - 2 * headroom_dry;
281   if (*slotAmp_dry_e & 1) {
282     *slotAmp_dry = *slotAmp_dry >> 1;
283     *slotAmp_dry_e += 1;
284   }
285 
286   /* normalize wet part, ensure that exponent is even */
287   s2 = fixMax(0, CntLeadingZeros(wet) - 1);
288   *slotAmp_wet = wet << s2;
289   *slotAmp_wet_e = s1 - s2 - 2 * headroom_wet;
290   if (*slotAmp_wet_e & 1) {
291     *slotAmp_wet = *slotAmp_wet >> 1;
292     *slotAmp_wet_e += 1;
293   }
294 }
295 
296 #if defined(__aarch64__)
297 __attribute__((noinline))
298 #endif
299 static void
shapeBBEnv(FIXP_DBL * pHybOutputRealDry,FIXP_DBL * pHybOutputImagDry,FIXP_DBL dryFac,INT scale,INT cplxBands,INT hybBands)300 shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
301            FIXP_DBL dryFac, INT scale, INT cplxBands, INT hybBands) {
302   INT qs;
303 
304   if (scale == 0) {
305     for (qs = 0; qs < cplxBands; qs++) {
306       pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
307       pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac);
308     }
309     for (; qs < hybBands; qs++) {
310       pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
311     }
312   } else {
313     for (qs = 0; qs < cplxBands; qs++) {
314       pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
315           fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
316       pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
317           fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
318     }
319     for (; qs < hybBands; qs++) {
320       pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
321           fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
322     }
323   }
324 }
325 
extractBBEnv(spatialDec * self,INT inp,INT start,INT channels,FIXP_DBL * pEnv,const SPATIAL_BS_FRAME * frame)326 static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
327                          FIXP_DBL *pEnv, const SPATIAL_BS_FRAME *frame) {
328   INT ch, pb, prevChOffs;
329   INT clz, scale, scale_min, envSF;
330   INT scaleCur, scalePrev, commonScale;
331   INT slotNrgSF, partNrgSF, frameNrgSF;
332   INT *pPartNrgPrevSF, *pFrameNrgPrevSF;
333   INT *pNormNrgPrevSF, *pPartNrgPrev2SF;
334 
335   FIXP_DBL maxVal, env, frameNrg, normNrg;
336   FIXP_DBL *pReal, *pImag;
337   FIXP_DBL *partNrg, *partNrgPrev;
338 
339   C_ALLOC_SCRATCH_START(pScratchBuffer, FIXP_DBL,
340                         (2 * 42 + MAX_PARAMETER_BANDS));
341   C_ALLOC_SCRATCH_START(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
342   C_ALLOC_SCRATCH_START(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
343 
344   FIXP_DBL *slotNrg = pScratchBuffer + (2 * 42);
345 
346   RESHAPE_BBENV_STATE *pBBEnvState = self->reshapeBBEnvState;
347 
348   FIXP_DBL alpha = pBBEnvState->alpha__FDK;
349   /*FIXP_DBL  alpha1 = (FL2FXCONST_DBL(1.0f) - alpha) << SF_ALPHA1;*/
350   FIXP_DBL alpha1 = ((FIXP_DBL)MAXVAL_DBL - alpha) << SF_ALPHA1;
351   FIXP_DBL beta = pBBEnvState->beta__FDK;
352   /*FIXP_DBL  beta1  = (FL2FXCONST_DBL(1.0f) - beta) << SF_BETA1;*/
353   FIXP_DBL beta1 = ((FIXP_DBL)MAXVAL_DBL - beta) << SF_BETA1;
354 
355   INT shapeActiv = 1;
356   INT hybBands = fixMin(42, self->hybridBands);
357   INT staticScale = self->staticDecScale + (1);
358   INT cplxBands;
359   cplxBands = fixMin(42, self->hybridBands);
360 
361   for (ch = start; ch < channels; ch++) {
362     if (inp == INP_DRY_WET) {
363       INT ch2 = row2channelGES[self->treeConfig][ch];
364       if (ch2 == -1) {
365         continue;
366       } else {
367         if (frame->tempShapeEnableChannelGES[ch2]) {
368           shapeActiv = 1;
369         } else {
370           shapeActiv = 0;
371         }
372       }
373       prevChOffs = ch;
374       pReal = pScratchBuffer;
375       pImag = pScratchBuffer + 42;
376       combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
377                     self->hybOutputImagDry__FDK[ch],
378                     self->hybOutputRealWet__FDK[ch],
379                     self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
380       clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
381                  getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
382     } else {
383       prevChOffs = ch + self->numOutputChannels;
384       pReal = self->hybInputReal__FDK[ch];
385       pImag = self->hybInputImag__FDK[ch];
386       clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
387                  getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
388     }
389 
390     partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
391     pPartNrgPrevSF = &pBBEnvState->partNrgPrevSF[prevChOffs];
392     pFrameNrgPrevSF = &pBBEnvState->frameNrgPrevSF[prevChOffs];
393     pNormNrgPrevSF = &pBBEnvState->normNrgPrevSF[prevChOffs];
394     pPartNrgPrev2SF = &pBBEnvState->partNrgPrev2SF[prevChOffs];
395 
396     /* calculate slot energy */
397     {
398       getSlotNrgHQ(&pReal[12], &pImag[12], slotNrg, clz,
399                    fixMin(42, self->hybridBands)); /* scale slotNrg:
400                                                       2*(staticScale-clz) +
401                                                       SF_FACTOR_SLOT */
402     }
403 
404     slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
405                 SF_FACTOR_SLOT;
406     frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
407                  SF_FACTOR_SLOT;
408 
409     partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
410                        pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
411     scalePrev = fixMax(fixMin(partNrgSF - pPartNrgPrevSF[0], DFRACT_BITS - 1),
412                        -(DFRACT_BITS - 1));
413     scaleCur =
414         fixMax(fixMin(partNrgSF - slotNrgSF + SF_ALPHA1, DFRACT_BITS - 1),
415                -(DFRACT_BITS - 1));
416 
417     maxVal = FL2FXCONST_DBL(0.0f);
418     frameNrg = FL2FXCONST_DBL(0.0f);
419     if ((scaleCur < 0) && (scalePrev < 0)) {
420       scaleCur = -scaleCur;
421       scalePrev = -scalePrev;
422       for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
423         partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
424                        (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
425                       << 1;
426         maxVal |= partNrg[pb];
427         frameNrg += slotNrg[pb] >> 3;
428       }
429     } else if ((scaleCur >= 0) && (scalePrev >= 0)) {
430       for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
431         partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
432                        (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
433                       << 1;
434         maxVal |= partNrg[pb];
435         frameNrg += slotNrg[pb] >> 3;
436       }
437     } else if ((scaleCur < 0) && (scalePrev >= 0)) {
438       scaleCur = -scaleCur;
439       for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
440         partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
441                        (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
442                       << 1;
443         maxVal |= partNrg[pb];
444         frameNrg += slotNrg[pb] >> 3;
445       }
446     } else { /* if ( (scaleCur >= 0) && (scalePrev < 0) ) */
447       scalePrev = -scalePrev;
448       for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
449         partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
450                        (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
451                       << 1;
452         maxVal |= partNrg[pb];
453         frameNrg += slotNrg[pb] >> 3;
454       }
455     }
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     frameNrg = fMult(frameNrg, FL2FXCONST_DBL(0.88888888888f));
461 
462     /* store scalefactor and headroom for part nrg prev */
463     pPartNrgPrevSF[0] = partNrgSF;
464     pPartNrgPrev2SF[0] = fixMax(0, CntLeadingZeros(maxVal) - 1);
465 
466     commonScale = fixMax(frameNrgSF - SF_ALPHA1 + 1, pFrameNrgPrevSF[0] + 1);
467     scalePrev = fixMin(commonScale - pFrameNrgPrevSF[0], DFRACT_BITS - 1);
468     scaleCur = fixMin(commonScale - frameNrgSF + SF_ALPHA1, DFRACT_BITS - 1);
469     frameNrgSF = commonScale;
470 
471     frameNrg = ((fMultDiv2(alpha1, frameNrg) >> scaleCur) +
472                 (fMultDiv2(alpha, pBBEnvState->frameNrgPrev__FDK[prevChOffs]) >>
473                  scalePrev))
474                << 1;
475 
476     clz = fixMax(0, CntLeadingZeros(frameNrg) - 1);
477     pBBEnvState->frameNrgPrev__FDK[prevChOffs] = frameNrg << clz;
478     pFrameNrgPrevSF[0] = frameNrgSF - clz;
479 
480     env = FL2FXCONST_DBL(0.0f);
481     scale = clz + partNrgSF - frameNrgSF;
482     scale_min = DFRACT_BITS - 1;
483     for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
484       if ((partNrg[pb] | slotNrg[pb]) != FL2FXCONST_DBL(0.0f)) {
485         INT s;
486         INT sc = 0;
487         INT sn = fixMax(0, CntLeadingZeros(slotNrg[pb]) - 1);
488         FIXP_DBL inv_sqrt = invSqrtNorm2(partNrg[pb], &sc);
489         FIXP_DBL res = fMult(slotNrg[pb] << sn, fPow2(inv_sqrt));
490 
491         s = fixMax(0, CntLeadingZeros(res) - 1);
492         res = res << s;
493 
494         sc = scale - (2 * sc - sn - s);
495         scale_min = fixMin(scale_min, sc);
496 
497         resPb[pb] = res;
498         resPbSF[pb] = sc;
499       } else {
500         resPb[pb] = (FIXP_DBL)0;
501         resPbSF[pb] = 0;
502       }
503     }
504 
505     scale_min = 4 - scale_min;
506 
507     for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
508       INT sc = fixMax(fixMin(resPbSF[pb] + scale_min, DFRACT_BITS - 1),
509                       -(DFRACT_BITS - 1));
510 
511       if (sc < 0) {
512         env += resPb[pb] << (-sc);
513       } else {
514         env += resPb[pb] >> (sc);
515       }
516     }
517 
518     env = fMultDiv2(env, pBBEnvState->frameNrgPrev__FDK[prevChOffs]);
519     envSF = slotNrgSF + scale_min + 1;
520 
521     commonScale = fixMax(envSF - SF_BETA1 + 1, pNormNrgPrevSF[0] + 1);
522     scalePrev = fixMin(commonScale - pNormNrgPrevSF[0], DFRACT_BITS - 1);
523     scaleCur = fixMin(commonScale - envSF + SF_BETA1, DFRACT_BITS - 1);
524 
525     normNrg = ((fMultDiv2(beta1, env) >> scaleCur) +
526                (fMultDiv2(beta, pBBEnvState->normNrgPrev__FDK[prevChOffs]) >>
527                 scalePrev))
528               << 1;
529 
530     clz = fixMax(0, CntLeadingZeros(normNrg) - 1);
531     pBBEnvState->normNrgPrev__FDK[prevChOffs] = normNrg << clz;
532     pNormNrgPrevSF[0] = commonScale - clz;
533 
534     if (shapeActiv) {
535       if ((env | normNrg) != FL2FXCONST_DBL(0.0f)) {
536         INT sc, se, sn;
537         se = fixMax(0, CntLeadingZeros(env) - 1);
538         sc = commonScale + SF_DIV32 - envSF + se;
539         env = fMult(sqrtFixp((env << se) >> (sc & 0x1)),
540                     invSqrtNorm2(normNrg, &sn));
541 
542         sc = fixMin((sc >> 1) - sn, DFRACT_BITS - 1);
543         if (sc < 0) {
544           env <<= (-sc);
545         } else {
546           env >>= (sc);
547         }
548       }
549       /* env is scaled by SF_DIV32/2 bits */
550     }
551     pEnv[ch] = env;
552   }
553 
554   C_ALLOC_SCRATCH_END(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
555   C_ALLOC_SCRATCH_END(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
556   C_ALLOC_SCRATCH_END(pScratchBuffer, FIXP_DBL, (2 * 42 + MAX_PARAMETER_BANDS));
557 }
558 
SpatialDecReshapeBBEnv(spatialDec * self,const SPATIAL_BS_FRAME * frame,INT ts)559 void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
560                             INT ts) {
561   INT ch, scale;
562   INT dryFacSF, slotAmpSF;
563   INT slotAmp_dry_e, slotAmp_wet_e;
564   FIXP_DBL tmp, dryFac, envShape;
565   FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
566   FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
567 
568   INT cplxBands;
569   INT hybBands = self->hybridBands - 6;
570 
571   cplxBands = self->hybridBands - 6;
572 
573   /* extract downmix envelope(s) */
574   switch (self->treeConfig) {
575     default:
576       extractBBEnv(self, INP_DMX, 0, fMin(self->numInputChannels, 2), envDmx,
577                    frame);
578   }
579 
580   /* extract dry and wet envelopes */
581   extractBBEnv(self, INP_DRY_WET, 0, self->numOutputChannels, envDry, frame);
582 
583   for (ch = 0; ch < self->numOutputChannels; ch++) {
584     INT ch2;
585 
586     ch2 = row2channelGES[self->treeConfig][ch];
587 
588     if (ch2 == -1) continue;
589 
590     if (frame->tempShapeEnableChannelGES[ch2]) {
591       INT sc;
592 
593       /* reshape dry and wet signals according to transmitted envelope */
594 
595       /* De-quantize GES data */
596       FDK_ASSERT((frame->bsEnvShapeData[ch2][ts] >= 0) &&
597                  (frame->bsEnvShapeData[ch2][ts] <= 4));
598       FDK_ASSERT((self->envQuantMode == 0) || (self->envQuantMode == 1));
599       envShape =
600           FX_CFG2FX_DBL(envShapeDataTable__FDK[frame->bsEnvShapeData[ch2][ts]]
601                                               [self->envQuantMode]);
602 
603       /* get downmix channel */
604       ch2 = self->row2channelDmxGES[ch];
605 
606       /* multiply ratio with dmx envelope; tmp is scaled by SF_DIV32/2+SF_SHAPE
607        * bits */
608       if (ch2 == 2) {
609         tmp = fMultDiv2(envShape, envDmx[0]) + fMultDiv2(envShape, envDmx[1]);
610       } else {
611         tmp = fMult(envShape, envDmx[ch2]);
612       }
613 
614       /* weighting factors */
615       dryFacSF = slotAmpSF = 0;
616       dryFac = slotAmp_ratio = FL2FXCONST_DBL(0.0f);
617 
618       /* dryFac will be scaled by dryFacSF bits */
619       if (envDry[ch] != FL2FXCONST_DBL(0.0f)) {
620         envDry[ch] = invSqrtNorm2(envDry[ch], &dryFacSF);
621         dryFac = fMultDiv2(tmp, fPow2Div2(envDry[ch])) << 2;
622         dryFacSF = SF_SHAPE + 2 * dryFacSF;
623       }
624 
625       slotAmp_dry_e = slotAmp_wet_e = 0;
626 
627       /* calculate slotAmp_dry and slotAmp_wet */
628       slotAmp(&slotAmp_dry, &slotAmp_dry_e, &slotAmp_wet, &slotAmp_wet_e,
629               &self->hybOutputRealDry__FDK[ch][6],
630               &self->hybOutputImagDry__FDK[ch][6],
631               &self->hybOutputRealWet__FDK[ch][6],
632               &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
633 
634       /* exponents must be even due to subsequent square root calculation */
635       FDK_ASSERT(((slotAmp_dry_e & 1) == 0) && ((slotAmp_wet_e & 1) == 0));
636 
637       /* slotAmp_ratio will be scaled by slotAmpSF bits */
638       if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
639         slotAmp_wet = sqrtFixp(slotAmp_wet);
640         slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
641 
642         slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
643         slotAmpSF = slotAmpSF + (slotAmp_wet_e >> 1) - (slotAmp_dry_e >> 1);
644       }
645 
646       /* calculate common scale factor */
647       scale =
648           fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
649                                                      bits to avoid overflows
650                                                      when calculating dryFac  */
651       dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
652       slotAmp_ratio =
653           slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
654 
655       /* limit dryFac */
656       dryFac = fixMax(
657           FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
658           fMult(dryFac, slotAmp_ratio) -
659               (slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
660               (dryFac >> fixMin(scale, DFRACT_BITS - 1)));
661       dryFac = fixMin(
662           FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
663           dryFac); /* reduce shift bits by 3, because upper
664                       limit 4.0 is scaled with 3 bits */
665       scale = 2 * scale + 1;
666 
667       /* improve precision for dryFac */
668       sc = fixMax(0, CntLeadingZeros(dryFac) - 1);
669       dryFac = dryFac << (INT)fixMin(scale, sc);
670       scale = scale - fixMin(scale, sc);
671 
672       /* shaping */
673       shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
674                  &self->hybOutputImagDry__FDK[ch][6], dryFac,
675                  fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
676     }
677   }
678 }
679