Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 
    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 
    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 
    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 
    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 
    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
    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 
    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 
    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