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