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 /**************************** SBR encoder library ******************************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 #include "env_est.h"
    104 #include "tran_det.h"
    105 
    106 #include "qmf.h"
    107 
    108 #include "fram_gen.h"
    109 #include "bit_sbr.h"
    110 #include "cmondata.h"
    111 #include "sbrenc_ram.h"
    112 
    113 #include "genericStds.h"
    114 
    115 #define QUANT_ERROR_THRES 200
    116 #define Y_NRG_SCALE 5 /* noCols = 32 -> shift(5) */
    117 #define MAX_NRG_SLOTS_LD 16
    118 
    119 static const UCHAR panTable[2][10] = {{0, 2, 4, 6, 8, 12, 16, 20, 24},
    120                                       {0, 2, 4, 8, 12, 0, 0, 0, 0}};
    121 static const UCHAR maxIndex[2] = {9, 5};
    122 
    123 /******************************************************************************
    124  Functionname:  FDKsbrEnc_GetTonality
    125 ******************************************************************************/
    126 /***************************************************************************/
    127 /*!
    128 
    129   \brief      Calculates complete energy per band from the energy values
    130               of the QMF subsamples.
    131 
    132   \brief      quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas()
    133   \brief      noEstPerFrame - number of estimations per frame
    134   \brief      startIndex - start index for the quota matrix
    135   \brief      Energies - energy matrix
    136   \brief      startBand - start band
    137   \brief      stopBand - number of QMF bands
    138   \brief      numberCols - number of QMF subsamples
    139 
    140   \return     mean tonality of the 5 bands with the highest energy
    141               scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT
    142 
    143 ****************************************************************************/
    144 static FIXP_DBL FDKsbrEnc_GetTonality(const FIXP_DBL *const *quotaMatrix,
    145                                       const INT noEstPerFrame,
    146                                       const INT startIndex,
    147                                       const FIXP_DBL *const *Energies,
    148                                       const UCHAR startBand, const INT stopBand,
    149                                       const INT numberCols) {
    150   UCHAR b, e, k;
    151   INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = {-1, -1, -1, -1, -1};
    152   FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = {
    153       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f),
    154       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)};
    155   FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */
    156   UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */
    157   FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = {
    158       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f),
    159       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)};
    160   FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f);
    161   FIXP_DBL energyBand[64];
    162   INT maxNEnergyValues; /* max. number of max. energy values */
    163 
    164   /*** Sum up energies for each band ***/
    165   FDK_ASSERT(numberCols == 15 || numberCols == 16);
    166   /* numberCols is always 15 or 16 for ELD. In case of 16 bands, the
    167       energyBands are initialized with the [15]th column.
    168       The rest of the column energies are added in the next step.   */
    169   if (numberCols == 15) {
    170     for (b = startBand; b < stopBand; b++) {
    171       energyBand[b] = FL2FXCONST_DBL(0.0f);
    172     }
    173   } else {
    174     for (b = startBand; b < stopBand; b++) {
    175       energyBand[b] = Energies[15][b] >> 4;
    176     }
    177   }
    178 
    179   for (k = 0; k < 15; k++) {
    180     for (b = startBand; b < stopBand; b++) {
    181       energyBand[b] += Energies[k][b] >> 4;
    182     }
    183   }
    184 
    185   /*** Determine 5 highest band-energies ***/
    186   maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand - startBand);
    187 
    188   /* Get min. value in energyMax array */
    189   energyMaxMin = energyMax[0] = energyBand[startBand];
    190   no_enMaxBand[0] = startBand;
    191   posEnergyMaxMin = 0;
    192   for (k = 1; k < maxNEnergyValues; k++) {
    193     energyMax[k] = energyBand[startBand + k];
    194     no_enMaxBand[k] = startBand + k;
    195     if (energyMaxMin > energyMax[k]) {
    196       energyMaxMin = energyMax[k];
    197       posEnergyMaxMin = k;
    198     }
    199   }
    200 
    201   for (b = startBand + maxNEnergyValues; b < stopBand; b++) {
    202     if (energyBand[b] > energyMaxMin) {
    203       energyMax[posEnergyMaxMin] = energyBand[b];
    204       no_enMaxBand[posEnergyMaxMin] = b;
    205 
    206       /* Again, get min. value in energyMax array */
    207       energyMaxMin = energyMax[0];
    208       posEnergyMaxMin = 0;
    209       for (k = 1; k < maxNEnergyValues; k++) {
    210         if (energyMaxMin > energyMax[k]) {
    211           energyMaxMin = energyMax[k];
    212           posEnergyMaxMin = k;
    213         }
    214       }
    215     }
    216   }
    217   /*** End determine 5 highest band-energies ***/
    218 
    219   /* Get tonality values for 5 highest energies */
    220   for (e = 0; e < maxNEnergyValues; e++) {
    221     tonalityBand[e] = FL2FXCONST_DBL(0.0f);
    222     for (k = 0; k < noEstPerFrame; k++) {
    223       tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1;
    224     }
    225     globalTonality +=
    226         tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */
    227   }
    228 
    229   return globalTonality;
    230 }
    231 
    232 /***************************************************************************/
    233 /*!
    234 
    235   \brief      Calculates energy form real and imaginary part of
    236               the QMF subsamples
    237 
    238   \return     none
    239 
    240 ****************************************************************************/
    241 LNK_SECTION_CODE_L1
    242 static void FDKsbrEnc_getEnergyFromCplxQmfData(
    243     FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */
    244     FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
    245     FIXP_DBL **RESTRICT
    246         imagValues,   /*!< the imaginary part of the QMF subsamples */
    247     INT numberBands,  /*!< number of QMF bands */
    248     INT numberCols,   /*!< number of QMF subsamples */
    249     INT *qmfScale,    /*!< sclefactor of QMF subsamples */
    250     INT *energyScale) /*!< scalefactor of energies */
    251 {
    252   int j, k;
    253   int scale;
    254   FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
    255 
    256   /* Get Scratch buffer */
    257   C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, 32 * 64 / 2)
    258 
    259   /* Get max possible scaling of QMF data */
    260   scale = DFRACT_BITS;
    261   for (k = 0; k < numberCols; k++) {
    262     scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
    263                                  getScalefactor(imagValues[k], numberBands)));
    264   }
    265 
    266   /* Tweak scaling stability for zero signal to non-zero signal transitions */
    267   if (scale >= DFRACT_BITS - 1) {
    268     scale = (FRACT_BITS - 1 - *qmfScale);
    269   }
    270   /* prevent scaling of QMF values to -1.f */
    271   scale = fixMax(0, scale - 1);
    272 
    273   /* Update QMF scale */
    274   *qmfScale += scale;
    275 
    276   /*
    277      Calculate energy of each time slot pair, max energy
    278      and shift QMF values as far as possible to the left.
    279    */
    280   {
    281     FIXP_DBL *nrgValues = tmpNrg;
    282     for (k = 0; k < numberCols; k += 2) {
    283       /* Load band vector addresses of 2 consecutive timeslots */
    284       FIXP_DBL *RESTRICT r0 = realValues[k];
    285       FIXP_DBL *RESTRICT i0 = imagValues[k];
    286       FIXP_DBL *RESTRICT r1 = realValues[k + 1];
    287       FIXP_DBL *RESTRICT i1 = imagValues[k + 1];
    288       for (j = 0; j < numberBands; j++) {
    289         FIXP_DBL energy;
    290         FIXP_DBL tr0, tr1, ti0, ti1;
    291 
    292         /* Read QMF values of 2 timeslots */
    293         tr0 = r0[j];
    294         tr1 = r1[j];
    295         ti0 = i0[j];
    296         ti1 = i1[j];
    297 
    298         /* Scale QMF Values and Calc Energy average of both timeslots */
    299         tr0 <<= scale;
    300         ti0 <<= scale;
    301         energy = fPow2AddDiv2(fPow2Div2(tr0), ti0) >> 1;
    302 
    303         tr1 <<= scale;
    304         ti1 <<= scale;
    305         energy += fPow2AddDiv2(fPow2Div2(tr1), ti1) >> 1;
    306 
    307         /* Write timeslot pair energy to scratch */
    308         *nrgValues++ = energy;
    309         max_val = fixMax(max_val, energy);
    310 
    311         /* Write back scaled QMF values */
    312         r0[j] = tr0;
    313         r1[j] = tr1;
    314         i0[j] = ti0;
    315         i1[j] = ti1;
    316       }
    317     }
    318   }
    319   /* energyScale: scalefactor energies of current frame */
    320   *energyScale =
    321       2 * (*qmfScale) -
    322       1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
    323 
    324   /* Scale timeslot pair energies and write to output buffer */
    325   scale = CountLeadingBits(max_val);
    326   {
    327     FIXP_DBL *nrgValues = tmpNrg;
    328     for (k = 0; k<numberCols>> 1; k++) {
    329       scaleValues(energyValues[k], nrgValues, numberBands, scale);
    330       nrgValues += numberBands;
    331     }
    332     *energyScale += scale;
    333   }
    334 
    335   /* Free Scratch buffer */
    336   C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, 32 * 64 / 2)
    337 }
    338 
    339 LNK_SECTION_CODE_L1
    340 static void FDKsbrEnc_getEnergyFromCplxQmfDataFull(
    341     FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */
    342     FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
    343     FIXP_DBL **RESTRICT
    344         imagValues,   /*!< the imaginary part of the QMF subsamples */
    345     int numberBands,  /*!< number of QMF bands */
    346     int numberCols,   /*!< number of QMF subsamples */
    347     int *qmfScale,    /*!< scalefactor of QMF subsamples */
    348     int *energyScale) /*!< scalefactor of energies */
    349 {
    350   int j, k;
    351   int scale;
    352   FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
    353 
    354   /* Get Scratch buffer */
    355   C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
    356 
    357   FDK_ASSERT(numberCols <= MAX_NRG_SLOTS_LD);
    358   FDK_ASSERT(numberBands <= 64);
    359 
    360   /* Get max possible scaling of QMF data */
    361   scale = DFRACT_BITS;
    362   for (k = 0; k < numberCols; k++) {
    363     scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
    364                                  getScalefactor(imagValues[k], numberBands)));
    365   }
    366 
    367   /* Tweak scaling stability for zero signal to non-zero signal transitions */
    368   if (scale >= DFRACT_BITS - 1) {
    369     scale = (FRACT_BITS - 1 - *qmfScale);
    370   }
    371   /* prevent scaling of QFM values to -1.f */
    372   scale = fixMax(0, scale - 1);
    373 
    374   /* Update QMF scale */
    375   *qmfScale += scale;
    376 
    377   /*
    378      Calculate energy of each time slot pair, max energy
    379      and shift QMF values as far as possible to the left.
    380    */
    381   {
    382     FIXP_DBL *nrgValues = tmpNrg;
    383     for (k = 0; k < numberCols; k++) {
    384       /* Load band vector addresses of 1 timeslot */
    385       FIXP_DBL *RESTRICT r0 = realValues[k];
    386       FIXP_DBL *RESTRICT i0 = imagValues[k];
    387       for (j = 0; j < numberBands; j++) {
    388         FIXP_DBL energy;
    389         FIXP_DBL tr0, ti0;
    390 
    391         /* Read QMF values of 1 timeslot */
    392         tr0 = r0[j];
    393         ti0 = i0[j];
    394 
    395         /* Scale QMF Values and Calc Energy */
    396         tr0 <<= scale;
    397         ti0 <<= scale;
    398         energy = fPow2AddDiv2(fPow2Div2(tr0), ti0);
    399         *nrgValues++ = energy;
    400 
    401         max_val = fixMax(max_val, energy);
    402 
    403         /* Write back scaled QMF values */
    404         r0[j] = tr0;
    405         i0[j] = ti0;
    406       }
    407     }
    408   }
    409   /* energyScale: scalefactor energies of current frame */
    410   *energyScale =
    411       2 * (*qmfScale) -
    412       1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
    413 
    414   /* Scale timeslot pair energies and write to output buffer */
    415   scale = CountLeadingBits(max_val);
    416   {
    417     FIXP_DBL *nrgValues = tmpNrg;
    418     for (k = 0; k < numberCols; k++) {
    419       scaleValues(energyValues[k], nrgValues, numberBands, scale);
    420       nrgValues += numberBands;
    421     }
    422     *energyScale += scale;
    423   }
    424 
    425   /* Free Scratch buffer */
    426   C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
    427 }
    428 
    429 /***************************************************************************/
    430 /*!
    431 
    432   \brief  Quantisation of the panorama value (balance)
    433 
    434   \return the quantized pan value
    435 
    436 ****************************************************************************/
    437 static INT mapPanorama(INT nrgVal,     /*! integer value of the energy */
    438                        INT ampRes,     /*! amplitude resolution [1.5/3dB] */
    439                        INT *quantError /*! quantization error of energy val*/
    440 ) {
    441   int i;
    442   INT min_val, val;
    443   UCHAR panIndex;
    444   INT sign;
    445 
    446   sign = nrgVal > 0 ? 1 : -1;
    447 
    448   nrgVal *= sign;
    449 
    450   min_val = FDK_INT_MAX;
    451   panIndex = 0;
    452   for (i = 0; i < maxIndex[ampRes]; i++) {
    453     val = fixp_abs((nrgVal - (INT)panTable[ampRes][i]));
    454 
    455     if (val < min_val) {
    456       min_val = val;
    457       panIndex = i;
    458     }
    459   }
    460 
    461   *quantError = min_val;
    462 
    463   return panTable[ampRes][maxIndex[ampRes] - 1] +
    464          sign * panTable[ampRes][panIndex];
    465 }
    466 
    467 /***************************************************************************/
    468 /*!
    469 
    470   \brief  Quantisation of the noise floor levels
    471 
    472   \return void
    473 
    474 ****************************************************************************/
    475 static void sbrNoiseFloorLevelsQuantisation(
    476     SCHAR *RESTRICT iNoiseLevels, /*! quantized noise levels */
    477     FIXP_DBL *RESTRICT
    478         NoiseLevels, /*! the noise levels. Exponent = LD_DATA_SHIFT  */
    479     INT coupling     /*! the coupling flag */
    480 ) {
    481   INT i;
    482   INT tmp, dummy;
    483 
    484   /* Quantisation, similar to sfb quant... */
    485   for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
    486     /* tmp = NoiseLevels[i] > (PFLOAT)30.0f ? 30: (INT) (NoiseLevels[i] +
    487      * (PFLOAT)0.5); */
    488     /* 30>>LD_DATA_SHIFT = 0.46875 */
    489     if ((FIXP_DBL)NoiseLevels[i] > FL2FXCONST_DBL(0.46875f)) {
    490       tmp = 30;
    491     } else {
    492       /* tmp = (INT)((FIXP_DBL)NoiseLevels[i] + (FL2FXCONST_DBL(0.5f)>>(*/
    493       /* FRACT_BITS+ */                                 /* 6-1)));*/
    494       /* tmp = tmp >> (DFRACT_BITS-1-LD_DATA_SHIFT); */ /* conversion to integer
    495                                                            happens here */
    496       /* rounding is done by shifting one bit less than necessary to the right,
    497        * adding '1' and then shifting the final bit */
    498       tmp = ((((INT)NoiseLevels[i]) >>
    499               (DFRACT_BITS - 1 - LD_DATA_SHIFT))); /* conversion to integer */
    500       if (tmp != 0) tmp += 1;
    501     }
    502 
    503     if (coupling) {
    504       tmp = tmp < -30 ? -30 : tmp;
    505       tmp = mapPanorama(tmp, 1, &dummy);
    506     }
    507     iNoiseLevels[i] = tmp;
    508   }
    509 }
    510 
    511 /***************************************************************************/
    512 /*!
    513 
    514   \brief  Calculation of noise floor for coupling
    515 
    516   \return void
    517 
    518 ****************************************************************************/
    519 static void coupleNoiseFloor(
    520     FIXP_DBL *RESTRICT noise_level_left, /*! noise level left  (modified)*/
    521     FIXP_DBL *RESTRICT noise_level_right /*! noise level right (modified)*/
    522 ) {
    523   FIXP_DBL cmpValLeft, cmpValRight;
    524   INT i;
    525   FIXP_DBL temp1, temp2;
    526 
    527   for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
    528     /* Calculation of the power function using ld64:
    529        z  = x^y;
    530        z' = CalcLd64(z) = y*CalcLd64(x)/64;
    531        z  = CalcInvLd64(z');
    532     */
    533     cmpValLeft = NOISE_FLOOR_OFFSET_64 - noise_level_left[i];
    534     cmpValRight = NOISE_FLOOR_OFFSET_64 - noise_level_right[i];
    535 
    536     if (cmpValRight < FL2FXCONST_DBL(0.0f)) {
    537       temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
    538     } else {
    539       temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
    540       temp1 = temp1 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
    541                         1); /* INT to fract conversion of result, if input of
    542                                CalcInvLdData is positiv */
    543     }
    544 
    545     if (cmpValLeft < FL2FXCONST_DBL(0.0f)) {
    546       temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
    547     } else {
    548       temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
    549       temp2 = temp2 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
    550                         1); /* INT to fract conversion of result, if input of
    551                                CalcInvLdData is positiv */
    552     }
    553 
    554     if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
    555         (cmpValRight < FL2FXCONST_DBL(0.0f))) {
    556       noise_level_left[i] =
    557           NOISE_FLOOR_OFFSET_64 -
    558           (CalcLdData(
    559               ((temp1 >> 1) +
    560                (temp2 >> 1)))); /* no scaling needed! both values are dfract */
    561       noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
    562     }
    563 
    564     if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
    565         (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
    566       noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
    567                             (CalcLdData(((temp1 >> 1) + (temp2 >> 1))) +
    568                              FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
    569       noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
    570     }
    571 
    572     if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
    573         (cmpValRight < FL2FXCONST_DBL(0.0f))) {
    574       noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
    575                             (CalcLdData(((temp1 >> (7 + 1)) + (temp2 >> 1))) +
    576                              FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
    577       noise_level_right[i] =
    578           (CalcLdData(temp2) + FL2FXCONST_DBL(0.109375f)) - CalcLdData(temp1);
    579     }
    580 
    581     if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
    582         (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
    583       noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
    584                             (CalcLdData(((temp1 >> 1) + (temp2 >> (7 + 1)))) +
    585                              FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
    586       noise_level_right[i] = CalcLdData(temp2) -
    587                              (CalcLdData(temp1) +
    588                               FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
    589     }
    590   }
    591 }
    592 
    593 /***************************************************************************/
    594 /*!
    595 
    596   \brief  Calculation of energy starting in lower band (li) up to upper band
    597 (ui) over slots (start_pos) to (stop_pos)
    598 
    599   \return void
    600 
    601 ****************************************************************************/
    602 
    603 static FIXP_DBL getEnvSfbEnergy(
    604     INT li,             /*! lower band */
    605     INT ui,             /*! upper band */
    606     INT start_pos,      /*! start slot */
    607     INT stop_pos,       /*! stop slot */
    608     INT border_pos,     /*! slots scaling border */
    609     FIXP_DBL **YBuffer, /*! sfb energy buffer */
    610     INT YBufferSzShift, /*! Energy buffer index scale */
    611     INT scaleNrg0,      /*! scaling of lower slots */
    612     INT scaleNrg1)      /*! scaling of upper slots */
    613 {
    614   /* use dynamic scaling for outer energy loop;
    615      energies are critical and every bit is important */
    616   int sc0, sc1, k, l;
    617 
    618   FIXP_DBL nrgSum, nrg1, nrg2, accu1, accu2;
    619   INT dynScale, dynScale1, dynScale2;
    620   if (ui - li == 0)
    621     dynScale = DFRACT_BITS - 1;
    622   else
    623     dynScale = CalcLdInt(ui - li) >> (DFRACT_BITS - 1 - LD_DATA_SHIFT);
    624 
    625   sc0 = fixMin(scaleNrg0, Y_NRG_SCALE);
    626   sc1 = fixMin(scaleNrg1, Y_NRG_SCALE);
    627   /* dynScale{1,2} is set such that the right shift below is positive */
    628   dynScale1 = fixMin((scaleNrg0 - sc0), dynScale);
    629   dynScale2 = fixMin((scaleNrg1 - sc1), dynScale);
    630   nrgSum = accu1 = accu2 = (FIXP_DBL)0;
    631 
    632   for (k = li; k < ui; k++) {
    633     nrg1 = nrg2 = (FIXP_DBL)0;
    634     for (l = start_pos; l < border_pos; l++) {
    635       nrg1 += YBuffer[l >> YBufferSzShift][k] >> sc0;
    636     }
    637     for (; l < stop_pos; l++) {
    638       nrg2 += YBuffer[l >> YBufferSzShift][k] >> sc1;
    639     }
    640     accu1 += (nrg1 >> dynScale1);
    641     accu2 += (nrg2 >> dynScale2);
    642   }
    643   /* This shift factor is always positive. See comment above. */
    644   nrgSum +=
    645       (accu1 >> fixMin((scaleNrg0 - sc0 - dynScale1), (DFRACT_BITS - 1))) +
    646       (accu2 >> fixMin((scaleNrg1 - sc1 - dynScale2), (DFRACT_BITS - 1)));
    647 
    648   return nrgSum;
    649 }
    650 
    651 /***************************************************************************/
    652 /*!
    653 
    654   \brief  Energy compensation in missing harmonic mode
    655 
    656   \return void
    657 
    658 ****************************************************************************/
    659 static FIXP_DBL mhLoweringEnergy(FIXP_DBL nrg, INT M) {
    660   /*
    661      Compensating for the fact that we in the decoder map the "average energy to
    662      every QMF band, and use this when we calculate the boost-factor. Since the
    663      mapped energy isn't the average energy but the maximum energy in case of
    664      missing harmonic creation, we will in the boost function calculate that too
    665      much limiting has been applied and hence we will boost the signal although
    666      it isn't called for. Hence we need to compensate for this by lowering the
    667      transmitted energy values for the sines so they will get the correct level
    668      after the boost is applied.
    669   */
    670   if (M > 2) {
    671     INT tmpScale;
    672     tmpScale = CountLeadingBits(nrg);
    673     nrg <<= tmpScale;
    674     nrg = fMult(nrg, FL2FXCONST_DBL(0.398107267f)); /* The maximum boost
    675                                                        is 1.584893, so the
    676                                                        maximum attenuation
    677                                                        should be
    678                                                        square(1/1.584893) =
    679                                                        0.398107267 */
    680     nrg >>= tmpScale;
    681   } else {
    682     if (M > 1) {
    683       nrg >>= 1;
    684     }
    685   }
    686 
    687   return nrg;
    688 }
    689 
    690 /***************************************************************************/
    691 /*!
    692 
    693   \brief  Energy compensation in none missing harmonic mode
    694 
    695   \return void
    696 
    697 ****************************************************************************/
    698 static FIXP_DBL nmhLoweringEnergy(FIXP_DBL nrg, const FIXP_DBL nrgSum,
    699                                   const INT nrgSum_scale, const INT M) {
    700   if (nrg > FL2FXCONST_DBL(0)) {
    701     int sc = 0;
    702     /* gain = nrgSum / (nrg*(M+1)) */
    703     FIXP_DBL gain = fMult(fDivNorm(nrgSum, nrg, &sc), GetInvInt(M + 1));
    704     sc += nrgSum_scale;
    705 
    706     /* reduce nrg if gain smaller 1.f */
    707     if (!((sc >= 0) && (gain > ((FIXP_DBL)MAXVAL_DBL >> sc)))) {
    708       nrg = fMult(scaleValue(gain, sc), nrg);
    709     }
    710   }
    711   return nrg;
    712 }
    713 
    714 /***************************************************************************/
    715 /*!
    716 
    717   \brief  calculates the envelope values from the energies, depending on
    718           framing and stereo mode
    719 
    720   \return void
    721 
    722 ****************************************************************************/
    723 static void calculateSbrEnvelope(
    724     FIXP_DBL **RESTRICT YBufferLeft,  /*! energy buffer left */
    725     FIXP_DBL **RESTRICT YBufferRight, /*! energy buffer right */
    726     int *RESTRICT YBufferScaleLeft,   /*! scale energy buffer left */
    727     int *RESTRICT YBufferScaleRight,  /*! scale energy buffer right */
    728     const SBR_FRAME_INFO *frame_info, /*! frame info vector */
    729     SCHAR *RESTRICT sfb_nrgLeft,      /*! sfb energy buffer left */
    730     SCHAR *RESTRICT sfb_nrgRight,     /*! sfb energy buffer right */
    731     HANDLE_SBR_CONFIG_DATA h_con,     /*! handle to config data   */
    732     HANDLE_ENV_CHANNEL h_sbr,         /*! envelope channel handle */
    733     SBR_STEREO_MODE stereoMode,       /*! stereo coding mode */
    734     INT *maxQuantError, /*! maximum quantization error, for panorama. */
    735     int YBufferSzShift) /*! Energy buffer index scale */
    736 
    737 {
    738   int env, j, m = 0;
    739   INT no_of_bands, start_pos, stop_pos, li, ui;
    740   FREQ_RES freq_res;
    741 
    742   INT ca = 2 - h_sbr->encEnvData.init_sbr_amp_res;
    743   INT oneBitLess = 0;
    744   if (ca == 2)
    745     oneBitLess =
    746         1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */
    747 
    748   INT quantError;
    749   INT nEnvelopes = frame_info->nEnvelopes;
    750   INT short_env = frame_info->shortEnv - 1;
    751   INT timeStep = h_sbr->sbrExtractEnvelope.time_step;
    752   INT commonScale, scaleLeft0, scaleLeft1;
    753   INT scaleRight0 = 0, scaleRight1 = 0;
    754 
    755   commonScale = fixMin(YBufferScaleLeft[0], YBufferScaleLeft[1]);
    756 
    757   if (stereoMode == SBR_COUPLING) {
    758     commonScale = fixMin(commonScale, YBufferScaleRight[0]);
    759     commonScale = fixMin(commonScale, YBufferScaleRight[1]);
    760   }
    761 
    762   commonScale = commonScale - 7;
    763 
    764   scaleLeft0 = YBufferScaleLeft[0] - commonScale;
    765   scaleLeft1 = YBufferScaleLeft[1] - commonScale;
    766   FDK_ASSERT((scaleLeft0 >= 0) && (scaleLeft1 >= 0));
    767 
    768   if (stereoMode == SBR_COUPLING) {
    769     scaleRight0 = YBufferScaleRight[0] - commonScale;
    770     scaleRight1 = YBufferScaleRight[1] - commonScale;
    771     FDK_ASSERT((scaleRight0 >= 0) && (scaleRight1 >= 0));
    772     *maxQuantError = 0;
    773   }
    774 
    775   for (env = 0; env < nEnvelopes; env++) {
    776     FIXP_DBL pNrgLeft[32];
    777     FIXP_DBL pNrgRight[32];
    778     int envNrg_scale;
    779     FIXP_DBL envNrgLeft = FL2FXCONST_DBL(0.0f);
    780     FIXP_DBL envNrgRight = FL2FXCONST_DBL(0.0f);
    781     int missingHarmonic[32];
    782     int count[32];
    783 
    784     start_pos = timeStep * frame_info->borders[env];
    785     stop_pos = timeStep * frame_info->borders[env + 1];
    786     freq_res = frame_info->freqRes[env];
    787     no_of_bands = h_con->nSfb[freq_res];
    788     envNrg_scale = DFRACT_BITS - fNormz((FIXP_DBL)no_of_bands);
    789     if (env == short_env) {
    790       j = fMax(2, timeStep); /* consider at least 2 QMF slots less for short
    791                                 envelopes (envelopes just before transients) */
    792       if ((stop_pos - start_pos - j) > 0) {
    793         stop_pos = stop_pos - j;
    794       }
    795     }
    796     for (j = 0; j < no_of_bands; j++) {
    797       FIXP_DBL nrgLeft = FL2FXCONST_DBL(0.0f);
    798       FIXP_DBL nrgRight = FL2FXCONST_DBL(0.0f);
    799 
    800       li = h_con->freqBandTable[freq_res][j];
    801       ui = h_con->freqBandTable[freq_res][j + 1];
    802 
    803       if (freq_res == FREQ_RES_HIGH) {
    804         if (j == 0 && ui - li > 1) {
    805           li++;
    806         }
    807       } else {
    808         if (j == 0 && ui - li > 2) {
    809           li++;
    810         }
    811       }
    812 
    813       /*
    814         Find out whether a sine will be missing in the scale-factor
    815         band that we're currently processing.
    816       */
    817       missingHarmonic[j] = 0;
    818 
    819       if (h_sbr->encEnvData.addHarmonicFlag) {
    820         if (freq_res == FREQ_RES_HIGH) {
    821           if (h_sbr->encEnvData
    822                   .addHarmonic[j]) { /*A missing sine in the current band*/
    823             missingHarmonic[j] = 1;
    824           }
    825         } else {
    826           INT i;
    827           INT startBandHigh = 0;
    828           INT stopBandHigh = 0;
    829 
    830           while (h_con->freqBandTable[FREQ_RES_HIGH][startBandHigh] <
    831                  h_con->freqBandTable[FREQ_RES_LOW][j])
    832             startBandHigh++;
    833           while (h_con->freqBandTable[FREQ_RES_HIGH][stopBandHigh] <
    834                  h_con->freqBandTable[FREQ_RES_LOW][j + 1])
    835             stopBandHigh++;
    836 
    837           for (i = startBandHigh; i < stopBandHigh; i++) {
    838             if (h_sbr->encEnvData.addHarmonic[i]) {
    839               missingHarmonic[j] = 1;
    840             }
    841           }
    842         }
    843       }
    844 
    845       /*
    846         If a sine is missing in a scalefactorband, with more than one qmf
    847         channel use the nrg from the channel with the largest nrg rather than
    848         the mean. Compensate for the boost calculation in the decdoder.
    849       */
    850       int border_pos =
    851           fixMin(stop_pos, h_sbr->sbrExtractEnvelope.YBufferWriteOffset
    852                                << YBufferSzShift);
    853 
    854       if (missingHarmonic[j]) {
    855         int k;
    856         count[j] = stop_pos - start_pos;
    857         nrgLeft = FL2FXCONST_DBL(0.0f);
    858 
    859         for (k = li; k < ui; k++) {
    860           FIXP_DBL tmpNrg;
    861           tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
    862                                    YBufferLeft, YBufferSzShift, scaleLeft0,
    863                                    scaleLeft1);
    864 
    865           nrgLeft = fixMax(nrgLeft, tmpNrg);
    866         }
    867 
    868         /* Energy lowering compensation */
    869         nrgLeft = mhLoweringEnergy(nrgLeft, ui - li);
    870 
    871         if (stereoMode == SBR_COUPLING) {
    872           nrgRight = FL2FXCONST_DBL(0.0f);
    873 
    874           for (k = li; k < ui; k++) {
    875             FIXP_DBL tmpNrg;
    876             tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
    877                                      YBufferRight, YBufferSzShift, scaleRight0,
    878                                      scaleRight1);
    879 
    880             nrgRight = fixMax(nrgRight, tmpNrg);
    881           }
    882 
    883           /* Energy lowering compensation */
    884           nrgRight = mhLoweringEnergy(nrgRight, ui - li);
    885         }
    886       } /* end missingHarmonic */
    887       else {
    888         count[j] = (stop_pos - start_pos) * (ui - li);
    889 
    890         nrgLeft = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
    891                                   YBufferLeft, YBufferSzShift, scaleLeft0,
    892                                   scaleLeft1);
    893 
    894         if (stereoMode == SBR_COUPLING) {
    895           nrgRight = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
    896                                      YBufferRight, YBufferSzShift, scaleRight0,
    897                                      scaleRight1);
    898         }
    899       } /* !missingHarmonic */
    900 
    901       /* save energies */
    902       pNrgLeft[j] = nrgLeft;
    903       pNrgRight[j] = nrgRight;
    904       envNrgLeft += (nrgLeft >> envNrg_scale);
    905       envNrgRight += (nrgRight >> envNrg_scale);
    906     } /* j */
    907 
    908     for (j = 0; j < no_of_bands; j++) {
    909       FIXP_DBL nrgLeft2 = FL2FXCONST_DBL(0.0f);
    910       FIXP_DBL nrgLeft = pNrgLeft[j];
    911       FIXP_DBL nrgRight = pNrgRight[j];
    912 
    913       /* None missing harmonic Energy lowering compensation */
    914       if (!missingHarmonic[j] && h_sbr->fLevelProtect) {
    915         /* in case of missing energy in base band,
    916            reduce reference energy to prevent overflows in decoder output */
    917         nrgLeft =
    918             nmhLoweringEnergy(nrgLeft, envNrgLeft, envNrg_scale, no_of_bands);
    919         if (stereoMode == SBR_COUPLING) {
    920           nrgRight = nmhLoweringEnergy(nrgRight, envNrgRight, envNrg_scale,
    921                                        no_of_bands);
    922         }
    923       }
    924 
    925       if (stereoMode == SBR_COUPLING) {
    926         /* calc operation later with log */
    927         nrgLeft2 = nrgLeft;
    928         nrgLeft = (nrgRight + nrgLeft) >> 1;
    929       }
    930 
    931       /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * 64))+(PFLOAT)44; */
    932       /* If nrgLeft == 0 then the Log calculations below do fail. */
    933       if (nrgLeft > FL2FXCONST_DBL(0.0f)) {
    934         FIXP_DBL tmp0, tmp1, tmp2, tmp3;
    935         INT tmpScale;
    936 
    937         tmpScale = CountLeadingBits(nrgLeft);
    938         nrgLeft = nrgLeft << tmpScale;
    939 
    940         tmp0 = CalcLdData(nrgLeft); /* scaled by 1/64 */
    941         tmp1 = ((FIXP_DBL)(commonScale + tmpScale))
    942                << (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1); /* scaled by 1/64 */
    943         tmp2 = ((FIXP_DBL)(count[j] * 64)) << (DFRACT_BITS - 1 - 14 - 1);
    944         tmp2 = CalcLdData(tmp2); /* scaled by 1/64 */
    945         tmp3 = FL2FXCONST_DBL(0.6875f - 0.21875f - 0.015625f) >>
    946                1; /* scaled by 1/64 */
    947 
    948         nrgLeft = ((tmp0 - tmp2) >> 1) + (tmp3 - tmp1);
    949       } else {
    950         nrgLeft = FL2FXCONST_DBL(-1.0f);
    951       }
    952 
    953       /* ld64 to integer conversion */
    954       nrgLeft = fixMin(fixMax(nrgLeft, FL2FXCONST_DBL(0.0f)),
    955                        (FL2FXCONST_DBL(0.5f) >> oneBitLess));
    956       nrgLeft = (FIXP_DBL)(LONG)nrgLeft >>
    957                 (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess - 1);
    958       sfb_nrgLeft[m] = ((INT)nrgLeft + 1) >> 1; /* rounding */
    959 
    960       if (stereoMode == SBR_COUPLING) {
    961         FIXP_DBL scaleFract;
    962         int sc0, sc1;
    963 
    964         nrgLeft2 = fixMax((FIXP_DBL)0x1, nrgLeft2);
    965         nrgRight = fixMax((FIXP_DBL)0x1, nrgRight);
    966 
    967         sc0 = CountLeadingBits(nrgLeft2);
    968         sc1 = CountLeadingBits(nrgRight);
    969 
    970         scaleFract =
    971             ((FIXP_DBL)(sc0 - sc1))
    972             << (DFRACT_BITS - 1 -
    973                 LD_DATA_SHIFT); /* scale value in ld64 representation */
    974         nrgRight = CalcLdData(nrgLeft2 << sc0) - CalcLdData(nrgRight << sc1) -
    975                    scaleFract;
    976 
    977         /* ld64 to integer conversion */
    978         nrgRight = (FIXP_DBL)(LONG)(nrgRight) >>
    979                    (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess);
    980         nrgRight = (nrgRight + (FIXP_DBL)1) >> 1; /* rounding */
    981 
    982         sfb_nrgRight[m] = mapPanorama(
    983             nrgRight, h_sbr->encEnvData.init_sbr_amp_res, &quantError);
    984 
    985         *maxQuantError = fixMax(quantError, *maxQuantError);
    986       }
    987 
    988       m++;
    989     } /* j */
    990 
    991     /* Do energy compensation for sines that are present in two
    992         QMF-bands in the original, but will only occur in one band in
    993         the decoder due to the synthetic sine coding.*/
    994     if (h_con->useParametricCoding) {
    995       m -= no_of_bands;
    996       for (j = 0; j < no_of_bands; j++) {
    997         if (freq_res == FREQ_RES_HIGH &&
    998             h_sbr->sbrExtractEnvelope.envelopeCompensation[j]) {
    999           sfb_nrgLeft[m] -=
   1000               (ca *
   1001                fixp_abs(
   1002                    (INT)h_sbr->sbrExtractEnvelope.envelopeCompensation[j]));
   1003         }
   1004         sfb_nrgLeft[m] = fixMax(0, sfb_nrgLeft[m]);
   1005         m++;
   1006       }
   1007     } /* useParametricCoding */
   1008 
   1009   } /* env loop */
   1010 }
   1011 
   1012 /***************************************************************************/
   1013 /*!
   1014 
   1015   \brief  calculates the noise floor and the envelope values from the
   1016           energies, depending on framing and stereo mode
   1017 
   1018   FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
   1019   envelope and the noise floor. The function includes the following processes:
   1020 
   1021   -Analysis subband filtering.
   1022   -Encoding SA and pan parameters (if enabled).
   1023   -Transient detection.
   1024 
   1025 ****************************************************************************/
   1026 
   1027 LNK_SECTION_CODE_L1
   1028 void FDKsbrEnc_extractSbrEnvelope1(
   1029     HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data   */
   1030     HANDLE_SBR_HEADER_DATA sbrHeaderData,
   1031     HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL hEnvChan,
   1032     HANDLE_COMMON_DATA hCmonData, SBR_ENV_TEMP_DATA *eData,
   1033     SBR_FRAME_TEMP_DATA *fData) {
   1034   HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
   1035 
   1036   if (sbrExtrEnv->YBufferSzShift == 0)
   1037     FDKsbrEnc_getEnergyFromCplxQmfDataFull(
   1038         &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
   1039         sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
   1040         sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
   1041         sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]);
   1042   else
   1043     FDKsbrEnc_getEnergyFromCplxQmfData(
   1044         &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
   1045         sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
   1046         sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
   1047         sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]);
   1048 
   1049   /* Energie values =
   1050    * sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset][x].floatVal *
   1051    * (1<<2*7-sbrExtrEnv->YBufferScale[1]) */
   1052 
   1053   /*
   1054     Precalculation of Tonality Quotas  COEFF Transform OK
   1055   */
   1056   FDKsbrEnc_CalculateTonalityQuotas(
   1057       &hEnvChan->TonCorr, sbrExtrEnv->rBuffer, sbrExtrEnv->iBuffer,
   1058       h_con->freqBandTable[HI][h_con->nSfb[HI]], hEnvChan->qmfScale);
   1059 
   1060   if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
   1061     FIXP_DBL tonality = FDKsbrEnc_GetTonality(
   1062         hEnvChan->TonCorr.quotaMatrix,
   1063         hEnvChan->TonCorr.numberOfEstimatesPerFrame,
   1064         hEnvChan->TonCorr.startIndexMatrix,
   1065         sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset,
   1066         h_con->freqBandTable[HI][0] + 1, h_con->noQmfBands,
   1067         sbrExtrEnv->no_cols);
   1068 
   1069     hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0];
   1070     hEnvChan->encEnvData.ton_HF[0] = tonality;
   1071 
   1072     /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
   1073     hEnvChan->encEnvData.global_tonality =
   1074         (hEnvChan->encEnvData.ton_HF[0] >> 1) +
   1075         (hEnvChan->encEnvData.ton_HF[1] >> 1);
   1076   }
   1077 
   1078   /*
   1079     Transient detection COEFF Transform OK
   1080   */
   1081 
   1082   if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
   1083     FDKsbrEnc_fastTransientDetect(&hEnvChan->sbrFastTransientDetector,
   1084                                   sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale,
   1085                                   sbrExtrEnv->YBufferWriteOffset,
   1086                                   eData->transient_info);
   1087 
   1088   } else {
   1089     FDKsbrEnc_transientDetect(
   1090         &hEnvChan->sbrTransientDetector, sbrExtrEnv->YBuffer,
   1091         sbrExtrEnv->YBufferScale, eData->transient_info,
   1092         sbrExtrEnv->YBufferWriteOffset, sbrExtrEnv->YBufferSzShift,
   1093         sbrExtrEnv->time_step, hEnvChan->SbrEnvFrame.frameMiddleSlot);
   1094   }
   1095 
   1096   /*
   1097     Generate flags for 2 env in a FIXFIX-frame.
   1098     Remove this function to get always 1 env per FIXFIX-frame.
   1099   */
   1100 
   1101   /*
   1102     frame Splitter COEFF Transform OK
   1103   */
   1104   FDKsbrEnc_frameSplitter(
   1105       sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale,
   1106       &hEnvChan->sbrTransientDetector, h_con->freqBandTable[1],
   1107       eData->transient_info, sbrExtrEnv->YBufferWriteOffset,
   1108       sbrExtrEnv->YBufferSzShift, h_con->nSfb[1], sbrExtrEnv->time_step,
   1109       sbrExtrEnv->no_cols, &hEnvChan->encEnvData.global_tonality);
   1110 }
   1111 
   1112 /***************************************************************************/
   1113 /*!
   1114 
   1115   \brief  calculates the noise floor and the envelope values from the
   1116           energies, depending on framing and stereo mode
   1117 
   1118   FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
   1119   envelope and the noise floor. The function includes the following processes:
   1120 
   1121   -Determine time/frequency division of current granule.
   1122   -Sending transient info to bitstream.
   1123   -Set amp_res to 1.5 dB if the current frame contains only one envelope.
   1124   -Lock dynamic bandwidth frequency change if the next envelope not starts on a
   1125   frame boundary.
   1126   -MDCT transposer (needed to detect where harmonics will be missing).
   1127   -Spectrum Estimation (used for pulse train and missing harmonics detection).
   1128   -Pulse train detection.
   1129   -Inverse Filtering detection.
   1130   -Waveform Coding.
   1131   -Missing Harmonics detection.
   1132   -Extract envelope of current frame.
   1133   -Noise floor estimation.
   1134   -Noise floor quantisation and coding.
   1135   -Encode envelope of current frame.
   1136   -Send the encoded data to the bitstream.
   1137   -Write to bitstream.
   1138 
   1139 ****************************************************************************/
   1140 
   1141 LNK_SECTION_CODE_L1
   1142 void FDKsbrEnc_extractSbrEnvelope2(
   1143     HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data   */
   1144     HANDLE_SBR_HEADER_DATA sbrHeaderData,
   1145     HANDLE_PARAMETRIC_STEREO hParametricStereo,
   1146     HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL h_envChan0,
   1147     HANDLE_ENV_CHANNEL h_envChan1, HANDLE_COMMON_DATA hCmonData,
   1148     SBR_ENV_TEMP_DATA *eData, SBR_FRAME_TEMP_DATA *fData, int clearOutput) {
   1149   HANDLE_ENV_CHANNEL h_envChan[MAX_NUM_CHANNELS] = {h_envChan0, h_envChan1};
   1150   int ch, i, j, c, YSzShift = h_envChan[0]->sbrExtractEnvelope.YBufferSzShift;
   1151 
   1152   SBR_STEREO_MODE stereoMode = h_con->stereoMode;
   1153   int nChannels = h_con->nChannels;
   1154   const int *v_tuning;
   1155   static const int v_tuningHEAAC[6] = {0, 2, 4, 0, 0, 0};
   1156 
   1157   static const int v_tuningELD[6] = {0, 2, 3, 0, 0, 0};
   1158 
   1159   if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
   1160     v_tuning = v_tuningELD;
   1161   else
   1162     v_tuning = v_tuningHEAAC;
   1163 
   1164   /*
   1165     Select stereo mode.
   1166   */
   1167   if (stereoMode == SBR_COUPLING) {
   1168     if (eData[0].transient_info[1] && eData[1].transient_info[1]) {
   1169       eData[0].transient_info[0] =
   1170           fixMin(eData[1].transient_info[0], eData[0].transient_info[0]);
   1171       eData[1].transient_info[0] = eData[0].transient_info[0];
   1172     } else {
   1173       if (eData[0].transient_info[1] && !eData[1].transient_info[1]) {
   1174         eData[1].transient_info[0] = eData[0].transient_info[0];
   1175       } else {
   1176         if (!eData[0].transient_info[1] && eData[1].transient_info[1])
   1177           eData[0].transient_info[0] = eData[1].transient_info[0];
   1178         else {
   1179           eData[0].transient_info[0] =
   1180               fixMax(eData[1].transient_info[0], eData[0].transient_info[0]);
   1181           eData[1].transient_info[0] = eData[0].transient_info[0];
   1182         }
   1183       }
   1184     }
   1185   }
   1186 
   1187   /*
   1188     Determine time/frequency division of current granule
   1189   */
   1190   eData[0].frame_info = FDKsbrEnc_frameInfoGenerator(
   1191       &h_envChan[0]->SbrEnvFrame, eData[0].transient_info,
   1192       sbrBitstreamData->rightBorderFIX,
   1193       h_envChan[0]->sbrExtractEnvelope.pre_transient_info,
   1194       h_envChan[0]->encEnvData.ldGrid, v_tuning);
   1195 
   1196   h_envChan[0]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
   1197 
   1198   /* AAC LD patch for transient prediction */
   1199   if (h_envChan[0]->encEnvData.ldGrid && eData[0].transient_info[2]) {
   1200     /* if next frame will start with transient, set shortEnv to
   1201      * numEnvelopes(shortend Envelope = shortEnv-1)*/
   1202     h_envChan[0]->SbrEnvFrame.SbrFrameInfo.shortEnv =
   1203         h_envChan[0]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
   1204   }
   1205 
   1206   switch (stereoMode) {
   1207     case SBR_LEFT_RIGHT:
   1208     case SBR_SWITCH_LRC:
   1209       eData[1].frame_info = FDKsbrEnc_frameInfoGenerator(
   1210           &h_envChan[1]->SbrEnvFrame, eData[1].transient_info,
   1211           sbrBitstreamData->rightBorderFIX,
   1212           h_envChan[1]->sbrExtractEnvelope.pre_transient_info,
   1213           h_envChan[1]->encEnvData.ldGrid, v_tuning);
   1214 
   1215       h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[1]->SbrEnvFrame.SbrGrid;
   1216 
   1217       if (h_envChan[1]->encEnvData.ldGrid && eData[1].transient_info[2]) {
   1218         /* if next frame will start with transient, set shortEnv to
   1219          * numEnvelopes(shortend Envelope = shortEnv-1)*/
   1220         h_envChan[1]->SbrEnvFrame.SbrFrameInfo.shortEnv =
   1221             h_envChan[1]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
   1222       }
   1223 
   1224       /* compare left and right frame_infos */
   1225       if (eData[0].frame_info->nEnvelopes != eData[1].frame_info->nEnvelopes) {
   1226         stereoMode = SBR_LEFT_RIGHT;
   1227       } else {
   1228         for (i = 0; i < eData[0].frame_info->nEnvelopes + 1; i++) {
   1229           if (eData[0].frame_info->borders[i] !=
   1230               eData[1].frame_info->borders[i]) {
   1231             stereoMode = SBR_LEFT_RIGHT;
   1232             break;
   1233           }
   1234         }
   1235         for (i = 0; i < eData[0].frame_info->nEnvelopes; i++) {
   1236           if (eData[0].frame_info->freqRes[i] !=
   1237               eData[1].frame_info->freqRes[i]) {
   1238             stereoMode = SBR_LEFT_RIGHT;
   1239             break;
   1240           }
   1241         }
   1242         if (eData[0].frame_info->shortEnv != eData[1].frame_info->shortEnv) {
   1243           stereoMode = SBR_LEFT_RIGHT;
   1244         }
   1245       }
   1246       break;
   1247     case SBR_COUPLING:
   1248       eData[1].frame_info = eData[0].frame_info;
   1249       h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
   1250       break;
   1251     case SBR_MONO:
   1252       /* nothing to do */
   1253       break;
   1254     default:
   1255       FDK_ASSERT(0);
   1256   }
   1257 
   1258   for (ch = 0; ch < nChannels; ch++) {
   1259     HANDLE_ENV_CHANNEL hEnvChan = h_envChan[ch];
   1260     HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
   1261     SBR_ENV_TEMP_DATA *ed = &eData[ch];
   1262 
   1263     /*
   1264        Send transient info to bitstream and store for next call
   1265     */
   1266     sbrExtrEnv->pre_transient_info[0] = ed->transient_info[0]; /* tran_pos */
   1267     sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */
   1268     hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes =
   1269         ed->frame_info->nEnvelopes; /* number of envelopes of current frame */
   1270 
   1271     /*
   1272       Check if the current frame is divided into one envelope only. If so, set
   1273       the amplitude resolution to 1.5 dB, otherwise may set back to chosen value
   1274     */
   1275     if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) &&
   1276         (ed->nEnvelopes == 1)) {
   1277       if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
   1278         /* Note: global_tonaliy_float_value ==
   1279            ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
   1280                  threshold_float_value ==
   1281            ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0)));
   1282          */
   1283         /* decision of SBR_AMP_RES */
   1284         if (fIsLessThan(/* global_tonality > threshold ? */
   1285                         h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
   1286                         hEnvChan->encEnvData.global_tonality,
   1287                         RELAXATION_SHIFT + 2)) {
   1288           hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
   1289         } else {
   1290           hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
   1291         }
   1292       } else
   1293         hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
   1294 
   1295       if (hEnvChan->encEnvData.currentAmpResFF !=
   1296           hEnvChan->encEnvData.init_sbr_amp_res) {
   1297         FDKsbrEnc_InitSbrHuffmanTables(
   1298             &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
   1299             &hEnvChan->sbrCodeNoiseFloor, hEnvChan->encEnvData.currentAmpResFF);
   1300       }
   1301     } else {
   1302       if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) {
   1303         FDKsbrEnc_InitSbrHuffmanTables(
   1304             &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
   1305             &hEnvChan->sbrCodeNoiseFloor, sbrHeaderData->sbr_amp_res);
   1306       }
   1307     }
   1308 
   1309     if (!clearOutput) {
   1310       /*
   1311         Tonality correction parameter extraction (inverse filtering level, noise
   1312         floor additional sines).
   1313       */
   1314       FDKsbrEnc_TonCorrParamExtr(
   1315           &hEnvChan->TonCorr, hEnvChan->encEnvData.sbr_invf_mode_vec,
   1316           ed->noiseFloor, &hEnvChan->encEnvData.addHarmonicFlag,
   1317           hEnvChan->encEnvData.addHarmonic, sbrExtrEnv->envelopeCompensation,
   1318           ed->frame_info, ed->transient_info, h_con->freqBandTable[HI],
   1319           h_con->nSfb[HI], hEnvChan->encEnvData.sbr_xpos_mode,
   1320           h_con->sbrSyntaxFlags);
   1321     }
   1322 
   1323     /* Low energy in low band fix */
   1324     if (hEnvChan->sbrTransientDetector.prevLowBandEnergy <
   1325             hEnvChan->sbrTransientDetector.prevHighBandEnergy &&
   1326         hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
   1327         /* The fix needs the non-fast transient detector running.
   1328            It sets prevLowBandEnergy and prevHighBandEnergy.      */
   1329         && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) {
   1330       hEnvChan->fLevelProtect = 1;
   1331 
   1332       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
   1333         hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL;
   1334     } else {
   1335       hEnvChan->fLevelProtect = 0;
   1336     }
   1337 
   1338     hEnvChan->encEnvData.sbr_invf_mode =
   1339         hEnvChan->encEnvData.sbr_invf_mode_vec[0];
   1340 
   1341     hEnvChan->encEnvData.noOfnoisebands =
   1342         hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
   1343 
   1344   } /* ch */
   1345 
   1346   /*
   1347      Save number of scf bands per envelope
   1348    */
   1349   for (ch = 0; ch < nChannels; ch++) {
   1350     for (i = 0; i < eData[ch].nEnvelopes; i++) {
   1351       h_envChan[ch]->encEnvData.noScfBands[i] =
   1352           (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH
   1353                ? h_con->nSfb[FREQ_RES_HIGH]
   1354                : h_con->nSfb[FREQ_RES_LOW]);
   1355     }
   1356   }
   1357 
   1358   /*
   1359     Extract envelope of current frame.
   1360   */
   1361   switch (stereoMode) {
   1362     case SBR_MONO:
   1363       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
   1364                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
   1365                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
   1366                            h_envChan[0], SBR_MONO, NULL, YSzShift);
   1367       break;
   1368     case SBR_LEFT_RIGHT:
   1369       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
   1370                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
   1371                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
   1372                            h_envChan[0], SBR_MONO, NULL, YSzShift);
   1373       calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
   1374                            h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
   1375                            eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
   1376                            h_envChan[1], SBR_MONO, NULL, YSzShift);
   1377       break;
   1378     case SBR_COUPLING:
   1379       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
   1380                            h_envChan[1]->sbrExtractEnvelope.YBuffer,
   1381                            h_envChan[0]->sbrExtractEnvelope.YBufferScale,
   1382                            h_envChan[1]->sbrExtractEnvelope.YBufferScale,
   1383                            eData[0].frame_info, eData[0].sfb_nrg,
   1384                            eData[1].sfb_nrg, h_con, h_envChan[0], SBR_COUPLING,
   1385                            &fData->maxQuantError, YSzShift);
   1386       break;
   1387     case SBR_SWITCH_LRC:
   1388       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
   1389                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
   1390                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
   1391                            h_envChan[0], SBR_MONO, NULL, YSzShift);
   1392       calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
   1393                            h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
   1394                            eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
   1395                            h_envChan[1], SBR_MONO, NULL, YSzShift);
   1396       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
   1397                            h_envChan[1]->sbrExtractEnvelope.YBuffer,
   1398                            h_envChan[0]->sbrExtractEnvelope.YBufferScale,
   1399                            h_envChan[1]->sbrExtractEnvelope.YBufferScale,
   1400                            eData[0].frame_info, eData[0].sfb_nrg_coupling,
   1401                            eData[1].sfb_nrg_coupling, h_con, h_envChan[0],
   1402                            SBR_COUPLING, &fData->maxQuantError, YSzShift);
   1403       break;
   1404   }
   1405 
   1406   /*
   1407     Noise floor quantisation and coding.
   1408   */
   1409 
   1410   switch (stereoMode) {
   1411     case SBR_MONO:
   1412       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
   1413                                       0);
   1414 
   1415       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
   1416                              &h_envChan[0]->sbrCodeNoiseFloor,
   1417                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
   1418                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
   1419                              sbrBitstreamData->HeaderActive);
   1420 
   1421       break;
   1422     case SBR_LEFT_RIGHT:
   1423       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
   1424                                       0);
   1425 
   1426       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
   1427                              &h_envChan[0]->sbrCodeNoiseFloor,
   1428                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
   1429                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
   1430                              sbrBitstreamData->HeaderActive);
   1431 
   1432       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
   1433                                       0);
   1434 
   1435       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
   1436                              &h_envChan[1]->sbrCodeNoiseFloor,
   1437                              h_envChan[1]->encEnvData.domain_vec_noise, 0,
   1438                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
   1439                              sbrBitstreamData->HeaderActive);
   1440 
   1441       break;
   1442 
   1443     case SBR_COUPLING:
   1444       coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
   1445 
   1446       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
   1447                                       0);
   1448 
   1449       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
   1450                              &h_envChan[0]->sbrCodeNoiseFloor,
   1451                              h_envChan[0]->encEnvData.domain_vec_noise, 1,
   1452                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
   1453                              sbrBitstreamData->HeaderActive);
   1454 
   1455       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
   1456                                       1);
   1457 
   1458       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
   1459                              &h_envChan[1]->sbrCodeNoiseFloor,
   1460                              h_envChan[1]->encEnvData.domain_vec_noise, 1,
   1461                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
   1462                              sbrBitstreamData->HeaderActive);
   1463 
   1464       break;
   1465     case SBR_SWITCH_LRC:
   1466       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
   1467                                       0);
   1468       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
   1469                                       0);
   1470       coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
   1471       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling,
   1472                                       eData[0].noiseFloor, 0);
   1473       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling,
   1474                                       eData[1].noiseFloor, 1);
   1475       break;
   1476   }
   1477 
   1478   /*
   1479     Encode envelope of current frame.
   1480   */
   1481   switch (stereoMode) {
   1482     case SBR_MONO:
   1483       sbrHeaderData->coupling = 0;
   1484       h_envChan[0]->encEnvData.balance = 0;
   1485       FDKsbrEnc_codeEnvelope(
   1486           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
   1487           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
   1488           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
   1489           sbrBitstreamData->HeaderActive);
   1490       break;
   1491     case SBR_LEFT_RIGHT:
   1492       sbrHeaderData->coupling = 0;
   1493 
   1494       h_envChan[0]->encEnvData.balance = 0;
   1495       h_envChan[1]->encEnvData.balance = 0;
   1496 
   1497       FDKsbrEnc_codeEnvelope(
   1498           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
   1499           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
   1500           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
   1501           sbrBitstreamData->HeaderActive);
   1502       FDKsbrEnc_codeEnvelope(
   1503           eData[1].sfb_nrg, eData[1].frame_info->freqRes,
   1504           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
   1505           sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 0,
   1506           sbrBitstreamData->HeaderActive);
   1507       break;
   1508     case SBR_COUPLING:
   1509       sbrHeaderData->coupling = 1;
   1510       h_envChan[0]->encEnvData.balance = 0;
   1511       h_envChan[1]->encEnvData.balance = 1;
   1512 
   1513       FDKsbrEnc_codeEnvelope(
   1514           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
   1515           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
   1516           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
   1517           sbrBitstreamData->HeaderActive);
   1518       FDKsbrEnc_codeEnvelope(
   1519           eData[1].sfb_nrg, eData[1].frame_info->freqRes,
   1520           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
   1521           sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 1,
   1522           sbrBitstreamData->HeaderActive);
   1523       break;
   1524     case SBR_SWITCH_LRC: {
   1525       INT payloadbitsLR;
   1526       INT payloadbitsCOUPLING;
   1527 
   1528       SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS];
   1529       SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS];
   1530       INT upDateNrgTemp[MAX_NUM_CHANNELS];
   1531       INT upDateNoiseTemp[MAX_NUM_CHANNELS];
   1532       INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
   1533       INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
   1534 
   1535       INT tempFlagRight = 0;
   1536       INT tempFlagLeft = 0;
   1537 
   1538       /*
   1539          Store previous values, in order to be able to "undo" what is being
   1540          done.
   1541       */
   1542 
   1543       for (ch = 0; ch < nChannels; ch++) {
   1544         FDKmemcpy(sfbNrgPrevTemp[ch],
   1545                   h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
   1546                   MAX_FREQ_COEFFS * sizeof(SCHAR));
   1547 
   1548         FDKmemcpy(noisePrevTemp[ch],
   1549                   h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
   1550                   MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
   1551 
   1552         upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate;
   1553         upDateNoiseTemp[ch] = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
   1554 
   1555         /*
   1556           forbid time coding in the first envelope in case of a different
   1557           previous stereomode
   1558         */
   1559         if (sbrHeaderData->prev_coupling) {
   1560           h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
   1561           h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
   1562         }
   1563       } /* ch */
   1564 
   1565       /*
   1566          Code ordinary Left/Right stereo
   1567       */
   1568       FDKsbrEnc_codeEnvelope(eData[0].sfb_nrg, eData[0].frame_info->freqRes,
   1569                              &h_envChan[0]->sbrCodeEnvelope,
   1570                              h_envChan[0]->encEnvData.domain_vec, 0,
   1571                              eData[0].frame_info->nEnvelopes, 0,
   1572                              sbrBitstreamData->HeaderActive);
   1573       FDKsbrEnc_codeEnvelope(eData[1].sfb_nrg, eData[1].frame_info->freqRes,
   1574                              &h_envChan[1]->sbrCodeEnvelope,
   1575                              h_envChan[1]->encEnvData.domain_vec, 0,
   1576                              eData[1].frame_info->nEnvelopes, 0,
   1577                              sbrBitstreamData->HeaderActive);
   1578 
   1579       c = 0;
   1580       for (i = 0; i < eData[0].nEnvelopes; i++) {
   1581         for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
   1582           h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c];
   1583           h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c];
   1584           c++;
   1585         }
   1586       }
   1587 
   1588       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
   1589                              &h_envChan[0]->sbrCodeNoiseFloor,
   1590                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
   1591                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
   1592                              sbrBitstreamData->HeaderActive);
   1593 
   1594       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
   1595         h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i];
   1596 
   1597       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
   1598                              &h_envChan[1]->sbrCodeNoiseFloor,
   1599                              h_envChan[1]->encEnvData.domain_vec_noise, 0,
   1600                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
   1601                              sbrBitstreamData->HeaderActive);
   1602 
   1603       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
   1604         h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i];
   1605 
   1606       sbrHeaderData->coupling = 0;
   1607       h_envChan[0]->encEnvData.balance = 0;
   1608       h_envChan[1]->encEnvData.balance = 0;
   1609 
   1610       payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement(
   1611           sbrHeaderData, hParametricStereo, sbrBitstreamData,
   1612           &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
   1613           h_con->sbrSyntaxFlags);
   1614 
   1615       /*
   1616         swap saved stored with current values
   1617       */
   1618       for (ch = 0; ch < nChannels; ch++) {
   1619         INT itmp;
   1620         for (i = 0; i < MAX_FREQ_COEFFS; i++) {
   1621           /*
   1622             swap sfb energies
   1623           */
   1624           itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i];
   1625           h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i] =
   1626               sfbNrgPrevTemp[ch][i];
   1627           sfbNrgPrevTemp[ch][i] = itmp;
   1628         }
   1629         for (i = 0; i < MAX_NUM_NOISE_COEFFS; i++) {
   1630           /*
   1631             swap noise energies
   1632           */
   1633           itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i];
   1634           h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i] =
   1635               noisePrevTemp[ch][i];
   1636           noisePrevTemp[ch][i] = itmp;
   1637         }
   1638         /* swap update flags */
   1639         itmp = h_envChan[ch]->sbrCodeEnvelope.upDate;
   1640         h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
   1641         upDateNrgTemp[ch] = itmp;
   1642 
   1643         itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
   1644         h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
   1645         upDateNoiseTemp[ch] = itmp;
   1646 
   1647         /*
   1648             save domain vecs
   1649         */
   1650         FDKmemcpy(domainVecTemp[ch], h_envChan[ch]->encEnvData.domain_vec,
   1651                   sizeof(INT) * MAX_ENVELOPES);
   1652         FDKmemcpy(domainVecNoiseTemp[ch],
   1653                   h_envChan[ch]->encEnvData.domain_vec_noise,
   1654                   sizeof(INT) * MAX_ENVELOPES);
   1655 
   1656         /*
   1657           forbid time coding in the first envelope in case of a different
   1658           previous stereomode
   1659         */
   1660 
   1661         if (!sbrHeaderData->prev_coupling) {
   1662           h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
   1663           h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
   1664         }
   1665       } /* ch */
   1666 
   1667       /*
   1668          Coupling
   1669        */
   1670 
   1671       FDKsbrEnc_codeEnvelope(
   1672           eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes,
   1673           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
   1674           1, eData[0].frame_info->nEnvelopes, 0,
   1675           sbrBitstreamData->HeaderActive);
   1676 
   1677       FDKsbrEnc_codeEnvelope(
   1678           eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes,
   1679           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
   1680           1, eData[1].frame_info->nEnvelopes, 1,
   1681           sbrBitstreamData->HeaderActive);
   1682 
   1683       c = 0;
   1684       for (i = 0; i < eData[0].nEnvelopes; i++) {
   1685         for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
   1686           h_envChan[0]->encEnvData.ienvelope[i][j] =
   1687               eData[0].sfb_nrg_coupling[c];
   1688           h_envChan[1]->encEnvData.ienvelope[i][j] =
   1689               eData[1].sfb_nrg_coupling[c];
   1690           c++;
   1691         }
   1692       }
   1693 
   1694       FDKsbrEnc_codeEnvelope(eData[0].noise_level_coupling, fData->res,
   1695                              &h_envChan[0]->sbrCodeNoiseFloor,
   1696                              h_envChan[0]->encEnvData.domain_vec_noise, 1,
   1697                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
   1698                              sbrBitstreamData->HeaderActive);
   1699 
   1700       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
   1701         h_envChan[0]->encEnvData.sbr_noise_levels[i] =
   1702             eData[0].noise_level_coupling[i];
   1703 
   1704       FDKsbrEnc_codeEnvelope(eData[1].noise_level_coupling, fData->res,
   1705                              &h_envChan[1]->sbrCodeNoiseFloor,
   1706                              h_envChan[1]->encEnvData.domain_vec_noise, 1,
   1707                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
   1708                              sbrBitstreamData->HeaderActive);
   1709 
   1710       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
   1711         h_envChan[1]->encEnvData.sbr_noise_levels[i] =
   1712             eData[1].noise_level_coupling[i];
   1713 
   1714       sbrHeaderData->coupling = 1;
   1715 
   1716       h_envChan[0]->encEnvData.balance = 0;
   1717       h_envChan[1]->encEnvData.balance = 1;
   1718 
   1719       tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag;
   1720       tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag;
   1721 
   1722       payloadbitsCOUPLING = FDKsbrEnc_CountSbrChannelPairElement(
   1723           sbrHeaderData, hParametricStereo, sbrBitstreamData,
   1724           &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
   1725           h_con->sbrSyntaxFlags);
   1726 
   1727       h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft;
   1728       h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight;
   1729 
   1730       if (payloadbitsCOUPLING < payloadbitsLR) {
   1731         /*
   1732           copy coded coupling envelope and noise data to l/r
   1733         */
   1734         for (ch = 0; ch < nChannels; ch++) {
   1735           SBR_ENV_TEMP_DATA *ed = &eData[ch];
   1736           FDKmemcpy(ed->sfb_nrg, ed->sfb_nrg_coupling,
   1737                     MAX_NUM_ENVELOPE_VALUES * sizeof(SCHAR));
   1738           FDKmemcpy(ed->noise_level, ed->noise_level_coupling,
   1739                     MAX_NUM_NOISE_VALUES * sizeof(SCHAR));
   1740         }
   1741 
   1742         sbrHeaderData->coupling = 1;
   1743         h_envChan[0]->encEnvData.balance = 0;
   1744         h_envChan[1]->encEnvData.balance = 1;
   1745       } else {
   1746         /*
   1747           restore saved l/r items
   1748         */
   1749         for (ch = 0; ch < nChannels; ch++) {
   1750           FDKmemcpy(h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
   1751                     sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof(SCHAR));
   1752 
   1753           h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
   1754 
   1755           FDKmemcpy(h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
   1756                     noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
   1757 
   1758           FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec, domainVecTemp[ch],
   1759                     sizeof(INT) * MAX_ENVELOPES);
   1760           FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec_noise,
   1761                     domainVecNoiseTemp[ch], sizeof(INT) * MAX_ENVELOPES);
   1762 
   1763           h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
   1764         }
   1765 
   1766         sbrHeaderData->coupling = 0;
   1767         h_envChan[0]->encEnvData.balance = 0;
   1768         h_envChan[1]->encEnvData.balance = 0;
   1769       }
   1770     } break;
   1771   } /* switch */
   1772 
   1773   /* tell the envelope encoders how long it has been, since we last sent
   1774      a frame starting with a dF-coded envelope */
   1775   if (stereoMode == SBR_MONO) {
   1776     if (h_envChan[0]->encEnvData.domain_vec[0] == TIME)
   1777       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
   1778     else
   1779       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
   1780   } else {
   1781     if (h_envChan[0]->encEnvData.domain_vec[0] == TIME ||
   1782         h_envChan[1]->encEnvData.domain_vec[0] == TIME) {
   1783       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
   1784       h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++;
   1785     } else {
   1786       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
   1787       h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
   1788     }
   1789   }
   1790 
   1791   /*
   1792     Send the encoded data to the bitstream
   1793   */
   1794   for (ch = 0; ch < nChannels; ch++) {
   1795     SBR_ENV_TEMP_DATA *ed = &eData[ch];
   1796     c = 0;
   1797     for (i = 0; i < ed->nEnvelopes; i++) {
   1798       for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) {
   1799         h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c];
   1800 
   1801         c++;
   1802       }
   1803     }
   1804     for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
   1805       h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i];
   1806     }
   1807   } /* ch */
   1808 
   1809   /*
   1810     Write bitstream
   1811   */
   1812   if (nChannels == 2) {
   1813     FDKsbrEnc_WriteEnvChannelPairElement(
   1814         sbrHeaderData, hParametricStereo, sbrBitstreamData,
   1815         &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
   1816         h_con->sbrSyntaxFlags);
   1817   } else {
   1818     FDKsbrEnc_WriteEnvSingleChannelElement(
   1819         sbrHeaderData, hParametricStereo, sbrBitstreamData,
   1820         &h_envChan[0]->encEnvData, hCmonData, h_con->sbrSyntaxFlags);
   1821   }
   1822 
   1823   /*
   1824    * Update buffers.
   1825    */
   1826   for (ch = 0; ch < nChannels; ch++) {
   1827     int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >>
   1828                         h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift;
   1829     for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) {
   1830       FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i],
   1831                 h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength],
   1832                 sizeof(FIXP_DBL) * 64);
   1833     }
   1834     h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] =
   1835         h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1];
   1836   }
   1837 
   1838   sbrHeaderData->prev_coupling = sbrHeaderData->coupling;
   1839 }
   1840 
   1841 /***************************************************************************/
   1842 /*!
   1843 
   1844   \brief  creates an envelope extractor handle
   1845 
   1846   \return error status
   1847 
   1848 ****************************************************************************/
   1849 INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
   1850                                        INT channel, INT chInEl,
   1851                                        UCHAR *dynamic_RAM) {
   1852   INT i;
   1853   FIXP_DBL *rBuffer, *iBuffer;
   1854   INT n;
   1855   FIXP_DBL *YBufferDyn;
   1856 
   1857   FDKmemclear(hSbrCut, sizeof(SBR_EXTRACT_ENVELOPE));
   1858 
   1859   if (NULL == (hSbrCut->p_YBuffer = GetRam_Sbr_envYBuffer(channel))) {
   1860     goto bail;
   1861   }
   1862 
   1863   for (i = 0; i < (32 >> 1); i++) {
   1864     hSbrCut->YBuffer[i] = hSbrCut->p_YBuffer + (i * 64);
   1865   }
   1866   YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
   1867   for (n = 0; i < 32; i++, n++) {
   1868     hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
   1869   }
   1870 
   1871   rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM);
   1872   iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM);
   1873 
   1874   for (i = 0; i < 32; i++) {
   1875     hSbrCut->rBuffer[i] = rBuffer + (i * 64);
   1876     hSbrCut->iBuffer[i] = iBuffer + (i * 64);
   1877   }
   1878 
   1879   return 0;
   1880 
   1881 bail:
   1882   FDKsbrEnc_deleteExtractSbrEnvelope(hSbrCut);
   1883 
   1884   return -1;
   1885 }
   1886 
   1887 /***************************************************************************/
   1888 /*!
   1889 
   1890   \brief  Initialize an envelope extractor instance.
   1891 
   1892   \return error status
   1893 
   1894 ****************************************************************************/
   1895 INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
   1896                                      int no_cols, int no_rows, int start_index,
   1897                                      int time_slots, int time_step,
   1898                                      int tran_off, ULONG statesInitFlag,
   1899                                      int chInEl, UCHAR *dynamic_RAM,
   1900                                      UINT sbrSyntaxFlags) {
   1901   int YBufferLength, rBufferLength;
   1902   int i;
   1903 
   1904   if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
   1905     int off = TRANSIENT_OFFSET_LD;
   1906     hSbrCut->YBufferWriteOffset = (no_cols >> 1) + off * time_step;
   1907   } else {
   1908     hSbrCut->YBufferWriteOffset = tran_off * time_step;
   1909   }
   1910   hSbrCut->rBufferReadOffset = 0;
   1911 
   1912   YBufferLength = hSbrCut->YBufferWriteOffset + no_cols;
   1913   rBufferLength = no_cols;
   1914 
   1915   hSbrCut->pre_transient_info[0] = 0;
   1916   hSbrCut->pre_transient_info[1] = 0;
   1917 
   1918   hSbrCut->no_cols = no_cols;
   1919   hSbrCut->no_rows = no_rows;
   1920   hSbrCut->start_index = start_index;
   1921 
   1922   hSbrCut->time_slots = time_slots;
   1923   hSbrCut->time_step = time_step;
   1924 
   1925   FDK_ASSERT(no_rows <= 64);
   1926 
   1927   /* Use half the Energy values if time step is 2 or greater */
   1928   if (time_step >= 2)
   1929     hSbrCut->YBufferSzShift = 1;
   1930   else
   1931     hSbrCut->YBufferSzShift = 0;
   1932 
   1933   YBufferLength >>= hSbrCut->YBufferSzShift;
   1934   hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift;
   1935 
   1936   FDK_ASSERT(YBufferLength <= 32);
   1937 
   1938   FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
   1939   INT n = 0;
   1940   for (i = (32 >> 1); i < 32; i++, n++) {
   1941     hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
   1942   }
   1943 
   1944   if (statesInitFlag) {
   1945     for (i = 0; i < YBufferLength; i++) {
   1946       FDKmemclear(hSbrCut->YBuffer[i], 64 * sizeof(FIXP_DBL));
   1947     }
   1948   }
   1949 
   1950   for (i = 0; i < rBufferLength; i++) {
   1951     FDKmemclear(hSbrCut->rBuffer[i], 64 * sizeof(FIXP_DBL));
   1952     FDKmemclear(hSbrCut->iBuffer[i], 64 * sizeof(FIXP_DBL));
   1953   }
   1954 
   1955   FDKmemclear(hSbrCut->envelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS);
   1956 
   1957   if (statesInitFlag) {
   1958     hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS - 1;
   1959   }
   1960 
   1961   return (0);
   1962 }
   1963 
   1964 /***************************************************************************/
   1965 /*!
   1966 
   1967   \brief  deinitializes an envelope extractor handle
   1968 
   1969   \return void
   1970 
   1971 ****************************************************************************/
   1972 
   1973 void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) {
   1974   if (hSbrCut) {
   1975     FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer);
   1976   }
   1977 }
   1978 
   1979 INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) {
   1980   return hSbr->no_rows *
   1981          ((hSbr->YBufferWriteOffset) *
   1982               2 /* mult 2 because nrg's are grouped half */
   1983           - hSbr->rBufferReadOffset); /* in reference hold half spec and calc
   1984                                          nrg's on overlapped spec */
   1985 }
   1986