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 /**************************** AAC encoder library ******************************
     96 
     97    Author(s):   M. Werner
     98 
     99    Description: Scale factor estimation
    100 
    101 *******************************************************************************/
    102 
    103 #include "sf_estim.h"
    104 #include "aacEnc_rom.h"
    105 #include "quantize.h"
    106 #include "bit_cnt.h"
    107 
    108 #ifdef __arm__
    109 #endif
    110 
    111 #define UPCOUNT_LIMIT 1
    112 #define AS_PE_FAC_SHIFT 7
    113 #define DIST_FAC_SHIFT 3
    114 #define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT)
    115 static const INT MAX_SCF_DELTA = 60;
    116 
    117 static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(
    118     3.0f / AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */
    119 static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(
    120     1.3219281f / AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */
    121 static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */
    122 
    123 /*
    124   Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel
    125 
    126   Description: Calculates the formfactor
    127 
    128   sf: scale factor of the mdct spectrum
    129   sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) *
    130   (2^FORM_FAC_SHIFT))
    131 */
    132 static void FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
    133     FIXP_DBL *RESTRICT sfbFormFactorLdData,
    134     PSY_OUT_CHANNEL *RESTRICT psyOutChan) {
    135   INT j, sfb, sfbGrp;
    136   FIXP_DBL formFactor;
    137 
    138   int tmp0 = psyOutChan->sfbCnt;
    139   int tmp1 = psyOutChan->maxSfbPerGroup;
    140   int step = psyOutChan->sfbPerGroup;
    141   for (sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) {
    142     for (sfb = 0; sfb < tmp1; sfb++) {
    143       formFactor = FL2FXCONST_DBL(0.0f);
    144       /* calc sum of sqrt(spec) */
    145       for (j = psyOutChan->sfbOffsets[sfbGrp + sfb];
    146            j < psyOutChan->sfbOffsets[sfbGrp + sfb + 1]; j++) {
    147         formFactor +=
    148             sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j])) >> FORM_FAC_SHIFT;
    149       }
    150       sfbFormFactorLdData[sfbGrp + sfb] = CalcLdData(formFactor);
    151     }
    152     /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */
    153     for (; sfb < psyOutChan->sfbPerGroup; sfb++) {
    154       sfbFormFactorLdData[sfbGrp + sfb] = FL2FXCONST_DBL(-1.0f);
    155     }
    156   }
    157 }
    158 
    159 /*
    160   Function: FDKaacEnc_CalcFormFactor
    161 
    162   Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each
    163   channel
    164 */
    165 
    166 void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)],
    167                               PSY_OUT_CHANNEL *psyOutChannel[(2)],
    168                               const INT nChannels) {
    169   INT j;
    170   for (j = 0; j < nChannels; j++) {
    171     FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
    172         qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]);
    173   }
    174 }
    175 
    176 /*
    177   Function: FDKaacEnc_calcSfbRelevantLines
    178 
    179   Description: Calculates sfbNRelevantLines
    180 
    181   sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0)
    182 */
    183 static void FDKaacEnc_calcSfbRelevantLines(
    184     const FIXP_DBL *const sfbFormFactorLdData,
    185     const FIXP_DBL *const sfbEnergyLdData,
    186     const FIXP_DBL *const sfbThresholdLdData, const INT *const sfbOffsets,
    187     const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
    188     FIXP_DBL *sfbNRelevantLines) {
    189   INT sfbOffs, sfb;
    190   FIXP_DBL sfbWidthLdData;
    191   FIXP_DBL asPeFacLdData =
    192       FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */
    193   FIXP_DBL accu;
    194 
    195   /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 *
    196    * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) *
    197    * 64); */
    198 
    199   FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL));
    200 
    201   for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) {
    202     for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
    203       /* calc sum of sqrt(spec) */
    204       if ((FIXP_DBL)sfbEnergyLdData[sfbOffs + sfb] >
    205           (FIXP_DBL)sfbThresholdLdData[sfbOffs + sfb]) {
    206         INT sfbWidth =
    207             sfbOffsets[sfbOffs + sfb + 1] - sfbOffsets[sfbOffs + sfb];
    208 
    209         /* avgFormFactorLdData =
    210          * sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */
    211         /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] /
    212          * avgFormFactorLdData; */
    213         sfbWidthLdData =
    214             (FIXP_DBL)(sfbWidth << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
    215         sfbWidthLdData = CalcLdData(sfbWidthLdData);
    216 
    217         accu = sfbEnergyLdData[sfbOffs + sfb] - sfbWidthLdData - asPeFacLdData;
    218         accu = sfbFormFactorLdData[sfbOffs + sfb] - (accu >> 2);
    219 
    220         sfbNRelevantLines[sfbOffs + sfb] = CalcInvLdData(accu) >> 1;
    221       }
    222     }
    223   }
    224 }
    225 
    226 /*
    227   Function: FDKaacEnc_countSingleScfBits
    228 
    229   Description:
    230 
    231   scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
    232 */
    233 static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft,
    234                                              INT scfRight) {
    235   FIXP_DBL scfBitsFract;
    236 
    237   scfBitsFract = (FIXP_DBL)(FDKaacEnc_bitCountScalefactorDelta(scfLeft - scf) +
    238                             FDKaacEnc_bitCountScalefactorDelta(scf - scfRight));
    239 
    240   scfBitsFract = scfBitsFract << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT));
    241 
    242   return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
    243 }
    244 
    245 /*
    246   Function: FDKaacEnc_calcSingleSpecPe
    247 
    248   specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
    249 */
    250 static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart,
    251                                            FIXP_DBL nLines) {
    252   FIXP_DBL specPe = FL2FXCONST_DBL(0.0f);
    253   FIXP_DBL ldRatio;
    254   FIXP_DBL scfFract;
    255 
    256   scfFract = (FIXP_DBL)(scf << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
    257 
    258   ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f), scfFract);
    259 
    260   if (ldRatio >= PE_C1) {
    261     specPe = fMult(FL2FXCONST_DBL(0.7f), fMult(nLines, ldRatio));
    262   } else {
    263     specPe = fMult(FL2FXCONST_DBL(0.7f),
    264                    fMult(nLines, (PE_C2 + fMult(PE_C3, ldRatio))));
    265   }
    266 
    267   return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
    268 }
    269 
    270 /*
    271   Function: FDKaacEnc_countScfBitsDiff
    272 
    273   scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
    274 */
    275 static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, INT *scfNew, INT sfbCnt,
    276                                            INT startSfb, INT stopSfb) {
    277   FIXP_DBL scfBitsFract;
    278   INT scfBitsDiff = 0;
    279   INT sfb = 0, sfbLast;
    280   INT sfbPrev, sfbNext;
    281 
    282   /* search for first relevant sfb */
    283   sfbLast = startSfb;
    284   while ((sfbLast < stopSfb) && (scfOld[sfbLast] == FDK_INT_MIN)) sfbLast++;
    285   /* search for previous relevant sfb and count diff */
    286   sfbPrev = startSfb - 1;
    287   while ((sfbPrev >= 0) && (scfOld[sfbPrev] == FDK_INT_MIN)) sfbPrev--;
    288   if (sfbPrev >= 0)
    289     scfBitsDiff +=
    290         FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
    291         FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
    292   /* now loop through all sfbs and count diffs of relevant sfbs */
    293   for (sfb = sfbLast + 1; sfb < stopSfb; sfb++) {
    294     if (scfOld[sfb] != FDK_INT_MIN) {
    295       scfBitsDiff +=
    296           FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
    297           FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
    298       sfbLast = sfb;
    299     }
    300   }
    301   /* search for next relevant sfb and count diff */
    302   sfbNext = stopSfb;
    303   while ((sfbNext < sfbCnt) && (scfOld[sfbNext] == FDK_INT_MIN)) sfbNext++;
    304   if (sfbNext < sfbCnt)
    305     scfBitsDiff +=
    306         FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
    307         FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
    308 
    309   scfBitsFract =
    310       (FIXP_DBL)(scfBitsDiff << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT)));
    311 
    312   return scfBitsFract;
    313 }
    314 
    315 /*
    316   Function: FDKaacEnc_calcSpecPeDiff
    317 
    318   specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
    319 */
    320 static FIXP_DBL FDKaacEnc_calcSpecPeDiff(
    321     PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, INT *scfOld,
    322     INT *scfNew, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
    323     FIXP_DBL *sfbNRelevantLines, INT startSfb, INT stopSfb) {
    324   FIXP_DBL specPeDiff = FL2FXCONST_DBL(0.0f);
    325   FIXP_DBL scfFract = FL2FXCONST_DBL(0.0f);
    326   INT sfb;
    327 
    328   /* loop through all sfbs and count pe difference */
    329   for (sfb = startSfb; sfb < stopSfb; sfb++) {
    330     if (scfOld[sfb] != FDK_INT_MIN) {
    331       FIXP_DBL ldRatioOld, ldRatioNew, pOld, pNew;
    332 
    333       /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f /
    334        * sfbFormFactor[sfb]) * LOG2_1; */
    335       /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
    336        * log2 */
    337       /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
    338       if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN)
    339         sfbConstPePart[sfb] =
    340             ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] -
    341               FL2FXCONST_DBL(0.09375f)) >>
    342              1) +
    343             FL2FXCONST_DBL(0.02152255861f);
    344 
    345       scfFract = (FIXP_DBL)(scfOld[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
    346       ldRatioOld =
    347           sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
    348 
    349       scfFract = (FIXP_DBL)(scfNew[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
    350       ldRatioNew =
    351           sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
    352 
    353       if (ldRatioOld >= PE_C1)
    354         pOld = ldRatioOld;
    355       else
    356         pOld = PE_C2 + fMult(PE_C3, ldRatioOld);
    357 
    358       if (ldRatioNew >= PE_C1)
    359         pNew = ldRatioNew;
    360       else
    361         pNew = PE_C2 + fMult(PE_C3, ldRatioNew);
    362 
    363       specPeDiff += fMult(FL2FXCONST_DBL(0.7f),
    364                           fMult(sfbNRelevantLines[sfb], (pNew - pOld)));
    365     }
    366   }
    367 
    368   return specPeDiff;
    369 }
    370 
    371 /*
    372   Function: FDKaacEnc_improveScf
    373 
    374   Description: Calculate the distortion by quantization and inverse quantization
    375   of the spectrum with various scalefactors. The scalefactor which provides the
    376   best results will be used.
    377 */
    378 static INT FDKaacEnc_improveScf(const FIXP_DBL *spec, SHORT *quantSpec,
    379                                 SHORT *quantSpecTmp, INT sfbWidth,
    380                                 FIXP_DBL threshLdData, INT scf, INT minScf,
    381                                 FIXP_DBL *distLdData, INT *minScfCalculated,
    382                                 INT dZoneQuantEnable) {
    383   FIXP_DBL sfbDistLdData;
    384   INT scfBest = scf;
    385   INT k;
    386   FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */
    387 
    388   /* calc real distortion */
    389   sfbDistLdData =
    390       FDKaacEnc_calcSfbDist(spec, quantSpec, sfbWidth, scf, dZoneQuantEnable);
    391   *minScfCalculated = scf;
    392   /* nmr > 1.25 -> try to improve nmr */
    393   if (sfbDistLdData > (threshLdData - distFactorLdData)) {
    394     INT scfEstimated = scf;
    395     FIXP_DBL sfbDistBestLdData = sfbDistLdData;
    396     INT cnt;
    397     /* improve by bigger scf ? */
    398     cnt = 0;
    399 
    400     while ((sfbDistLdData > (threshLdData - distFactorLdData)) &&
    401            (cnt++ < UPCOUNT_LIMIT)) {
    402       scf++;
    403       sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
    404                                             dZoneQuantEnable);
    405 
    406       if (sfbDistLdData < sfbDistBestLdData) {
    407         scfBest = scf;
    408         sfbDistBestLdData = sfbDistLdData;
    409         for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
    410       }
    411     }
    412     /* improve by smaller scf ? */
    413     cnt = 0;
    414     scf = scfEstimated;
    415     sfbDistLdData = sfbDistBestLdData;
    416     while ((sfbDistLdData > (threshLdData - distFactorLdData)) && (cnt++ < 1) &&
    417            (scf > minScf)) {
    418       scf--;
    419       sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
    420                                             dZoneQuantEnable);
    421 
    422       if (sfbDistLdData < sfbDistBestLdData) {
    423         scfBest = scf;
    424         sfbDistBestLdData = sfbDistLdData;
    425         for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
    426       }
    427       *minScfCalculated = scf;
    428     }
    429     *distLdData = sfbDistBestLdData;
    430   } else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */
    431     FIXP_DBL sfbDistBestLdData = sfbDistLdData;
    432     FIXP_DBL sfbDistAllowedLdData =
    433         fixMin(sfbDistLdData - distFactorLdData, threshLdData);
    434     int cnt;
    435     for (cnt = 0; cnt < UPCOUNT_LIMIT; cnt++) {
    436       scf++;
    437       sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
    438                                             dZoneQuantEnable);
    439 
    440       if (sfbDistLdData < sfbDistAllowedLdData) {
    441         *minScfCalculated = scfBest + 1;
    442         scfBest = scf;
    443         sfbDistBestLdData = sfbDistLdData;
    444         for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
    445       }
    446     }
    447     *distLdData = sfbDistBestLdData;
    448   }
    449 
    450   /* return best scalefactor */
    451   return scfBest;
    452 }
    453 
    454 /*
    455   Function: FDKaacEnc_assimilateSingleScf
    456 
    457 */
    458 static void FDKaacEnc_assimilateSingleScf(
    459     const PSY_OUT_CHANNEL *psyOutChan, const QC_OUT_CHANNEL *qcOutChannel,
    460     SHORT *quantSpec, SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf,
    461     const INT *minScf, FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart,
    462     const FIXP_DBL *sfbFormFactorLdData, const FIXP_DBL *sfbNRelevantLines,
    463     INT *minScfCalculated, INT restartOnSuccess) {
    464   INT sfbLast, sfbAct, sfbNext;
    465   INT scfAct, *scfLast, *scfNext, scfMin, scfMax;
    466   INT sfbWidth, sfbOffs;
    467   FIXP_DBL enLdData;
    468   FIXP_DBL sfbPeOld, sfbPeNew;
    469   FIXP_DBL sfbDistNew;
    470   INT i, k;
    471   INT success = 0;
    472   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
    473   FIXP_DBL deltaPeNew, deltaPeTmp;
    474   INT prevScfLast[MAX_GROUPED_SFB], prevScfNext[MAX_GROUPED_SFB];
    475   FIXP_DBL deltaPeLast[MAX_GROUPED_SFB];
    476   INT updateMinScfCalculated;
    477 
    478   for (i = 0; i < psyOutChan->sfbCnt; i++) {
    479     prevScfLast[i] = FDK_INT_MAX;
    480     prevScfNext[i] = FDK_INT_MAX;
    481     deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX;
    482   }
    483 
    484   sfbLast = -1;
    485   sfbAct = -1;
    486   sfbNext = -1;
    487   scfLast = 0;
    488   scfNext = 0;
    489   scfMin = FDK_INT_MAX;
    490   scfMax = FDK_INT_MAX;
    491   do {
    492     /* search for new relevant sfb */
    493     sfbNext++;
    494     while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN))
    495       sfbNext++;
    496     if ((sfbLast >= 0) && (sfbAct >= 0) && (sfbNext < psyOutChan->sfbCnt)) {
    497       /* relevant scfs to the left and to the right */
    498       scfAct = scf[sfbAct];
    499       scfLast = scf + sfbLast;
    500       scfNext = scf + sfbNext;
    501       scfMin = fixMin(*scfLast, *scfNext);
    502       scfMax = fixMax(*scfLast, *scfNext);
    503     } else if ((sfbLast == -1) && (sfbAct >= 0) &&
    504                (sfbNext < psyOutChan->sfbCnt)) {
    505       /* first relevant scf */
    506       scfAct = scf[sfbAct];
    507       scfLast = &scfAct;
    508       scfNext = scf + sfbNext;
    509       scfMin = *scfNext;
    510       scfMax = *scfNext;
    511     } else if ((sfbLast >= 0) && (sfbAct >= 0) &&
    512                (sfbNext == psyOutChan->sfbCnt)) {
    513       /* last relevant scf */
    514       scfAct = scf[sfbAct];
    515       scfLast = scf + sfbLast;
    516       scfNext = &scfAct;
    517       scfMin = *scfLast;
    518       scfMax = *scfLast;
    519     }
    520     if (sfbAct >= 0) scfMin = fixMax(scfMin, minScf[sfbAct]);
    521 
    522     if ((sfbAct >= 0) && (sfbLast >= 0 || sfbNext < psyOutChan->sfbCnt) &&
    523         (scfAct > scfMin) && (scfAct <= scfMin + MAX_SCF_DELTA) &&
    524         (scfAct >= scfMax - MAX_SCF_DELTA) &&
    525         (scfAct <=
    526          fixMin(scfMin, fixMin(*scfLast, *scfNext)) + MAX_SCF_DELTA) &&
    527         (*scfLast != prevScfLast[sfbAct] || *scfNext != prevScfNext[sfbAct] ||
    528          deltaPe < deltaPeLast[sfbAct])) {
    529       /* bigger than neighbouring scf found, try to use smaller scf */
    530       success = 0;
    531 
    532       sfbWidth =
    533           psyOutChan->sfbOffsets[sfbAct + 1] - psyOutChan->sfbOffsets[sfbAct];
    534       sfbOffs = psyOutChan->sfbOffsets[sfbAct];
    535 
    536       /* estimate required bits for actual scf */
    537       enLdData = qcOutChannel->sfbEnergyLdData[sfbAct];
    538 
    539       /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) *
    540        * LOG2_1; */
    541       /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
    542        * log2 */
    543       /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
    544       if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) {
    545         sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] -
    546                                    FL2FXCONST_DBL(0.09375f)) >>
    547                                   1) +
    548                                  FL2FXCONST_DBL(0.02152255861f);
    549       }
    550 
    551       sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
    552                                             sfbNRelevantLines[sfbAct]) +
    553                  FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
    554 
    555       deltaPeNew = deltaPe;
    556       updateMinScfCalculated = 1;
    557 
    558       do {
    559         /* estimate required bits for smaller scf */
    560         scfAct--;
    561         /* check only if the same check was not done before */
    562         if (scfAct < minScfCalculated[sfbAct] &&
    563             scfAct >= scfMax - MAX_SCF_DELTA) {
    564           /* estimate required bits for new scf */
    565           sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
    566                                                 sfbNRelevantLines[sfbAct]) +
    567                      FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
    568 
    569           /* use new scf if no increase in pe and
    570              quantization error is smaller */
    571           deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
    572           /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
    573           if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) {
    574             /* distortion of new scf */
    575             sfbDistNew = FDKaacEnc_calcSfbDist(
    576                 qcOutChannel->mdctSpectrum + sfbOffs, quantSpecTmp + sfbOffs,
    577                 sfbWidth, scfAct, dZoneQuantEnable);
    578 
    579             if (sfbDistNew < sfbDist[sfbAct]) {
    580               /* success, replace scf by new one */
    581               scf[sfbAct] = scfAct;
    582               sfbDist[sfbAct] = sfbDistNew;
    583 
    584               for (k = 0; k < sfbWidth; k++)
    585                 quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
    586 
    587               deltaPeNew = deltaPeTmp;
    588               success = 1;
    589             }
    590             /* mark as already checked */
    591             if (updateMinScfCalculated) minScfCalculated[sfbAct] = scfAct;
    592           } else {
    593             /* from this scf value on not all new values have been checked */
    594             updateMinScfCalculated = 0;
    595           }
    596         }
    597       } while (scfAct > scfMin);
    598 
    599       deltaPe = deltaPeNew;
    600 
    601       /* save parameters to avoid multiple computations of the same sfb */
    602       prevScfLast[sfbAct] = *scfLast;
    603       prevScfNext[sfbAct] = *scfNext;
    604       deltaPeLast[sfbAct] = deltaPe;
    605     }
    606 
    607     if (success && restartOnSuccess) {
    608       /* start again at first sfb */
    609       sfbLast = -1;
    610       sfbAct = -1;
    611       sfbNext = -1;
    612       scfLast = 0;
    613       scfNext = 0;
    614       scfMin = FDK_INT_MAX;
    615       scfMax = FDK_INT_MAX;
    616       success = 0;
    617     } else {
    618       /* shift sfbs for next band */
    619       sfbLast = sfbAct;
    620       sfbAct = sfbNext;
    621     }
    622   } while (sfbNext < psyOutChan->sfbCnt);
    623 }
    624 
    625 /*
    626   Function: FDKaacEnc_assimilateMultipleScf
    627 
    628 */
    629 static void FDKaacEnc_assimilateMultipleScf(
    630     PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
    631     SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
    632     FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
    633     FIXP_DBL *sfbNRelevantLines) {
    634   INT sfb, startSfb, stopSfb;
    635   INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct;
    636   INT possibleRegionFound;
    637   INT sfbWidth, sfbOffs, i, k;
    638   FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], distOldSum, distNewSum;
    639   INT deltaScfBits;
    640   FIXP_DBL deltaSpecPe;
    641   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
    642   FIXP_DBL deltaPeNew;
    643   INT sfbCnt = psyOutChan->sfbCnt;
    644 
    645   /* calc min and max scalfactors */
    646   scfMin = FDK_INT_MAX;
    647   scfMax = FDK_INT_MIN;
    648   for (sfb = 0; sfb < sfbCnt; sfb++) {
    649     if (scf[sfb] != FDK_INT_MIN) {
    650       scfMin = fixMin(scfMin, scf[sfb]);
    651       scfMax = fixMax(scfMax, scf[sfb]);
    652     }
    653   }
    654 
    655   if (scfMax != FDK_INT_MIN && scfMax <= scfMin + MAX_SCF_DELTA) {
    656     scfAct = scfMax;
    657 
    658     do {
    659       /* try smaller scf */
    660       scfAct--;
    661       for (i = 0; i < MAX_GROUPED_SFB; i++) scfTmp[i] = scf[i];
    662       stopSfb = 0;
    663       do {
    664         /* search for region where all scfs are bigger than scfAct */
    665         sfb = stopSfb;
    666         while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] <= scfAct))
    667           sfb++;
    668         startSfb = sfb;
    669         sfb++;
    670         while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] > scfAct))
    671           sfb++;
    672         stopSfb = sfb;
    673 
    674         /* check if in all sfb of a valid region scfAct >= minScf[sfb] */
    675         possibleRegionFound = 0;
    676         if (startSfb < sfbCnt) {
    677           possibleRegionFound = 1;
    678           for (sfb = startSfb; sfb < stopSfb; sfb++) {
    679             if (scf[sfb] != FDK_INT_MIN)
    680               if (scfAct < minScf[sfb]) {
    681                 possibleRegionFound = 0;
    682                 break;
    683               }
    684           }
    685         }
    686 
    687         if (possibleRegionFound) { /* region found */
    688 
    689           /* replace scfs in region by scfAct */
    690           for (sfb = startSfb; sfb < stopSfb; sfb++) {
    691             if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfAct;
    692           }
    693 
    694           /* estimate change in bit demand for new scfs */
    695           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
    696                                                     startSfb, stopSfb);
    697 
    698           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
    699               psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
    700               sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
    701 
    702           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
    703 
    704           /* new bit demand small enough ? */
    705           /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
    706           if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) {
    707             /* quantize and calc sum of new distortion */
    708             distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
    709             for (sfb = startSfb; sfb < stopSfb; sfb++) {
    710               if (scfTmp[sfb] != FDK_INT_MIN) {
    711                 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
    712 
    713                 sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
    714                            psyOutChan->sfbOffsets[sfb];
    715                 sfbOffs = psyOutChan->sfbOffsets[sfb];
    716 
    717                 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
    718                     qcOutChannel->mdctSpectrum + sfbOffs,
    719                     quantSpecTmp + sfbOffs, sfbWidth, scfAct, dZoneQuantEnable);
    720 
    721                 if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
    722                   /* no improvement, skip further dist. calculations */
    723                   distNewSum = distOldSum << 1;
    724                   break;
    725                 }
    726                 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
    727               }
    728             }
    729             /* distortion smaller ? -> use new scalefactors */
    730             if (distNewSum < distOldSum) {
    731               deltaPe = deltaPeNew;
    732               for (sfb = startSfb; sfb < stopSfb; sfb++) {
    733                 if (scf[sfb] != FDK_INT_MIN) {
    734                   sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
    735                              psyOutChan->sfbOffsets[sfb];
    736                   sfbOffs = psyOutChan->sfbOffsets[sfb];
    737                   scf[sfb] = scfAct;
    738                   sfbDist[sfb] = sfbDistNew[sfb];
    739 
    740                   for (k = 0; k < sfbWidth; k++)
    741                     quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
    742                 }
    743               }
    744             }
    745           }
    746         }
    747 
    748       } while (stopSfb <= sfbCnt);
    749 
    750     } while (scfAct > scfMin);
    751   }
    752 }
    753 
    754 /*
    755   Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2
    756 
    757 */
    758 static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
    759     PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
    760     SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
    761     FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
    762     FIXP_DBL *sfbNRelevantLines) {
    763   INT sfb, startSfb, stopSfb;
    764   INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew;
    765   INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi;
    766   INT scfMin, scfMax;
    767   INT *sfbOffs = psyOutChan->sfbOffsets;
    768   FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], sfbDistMax[MAX_GROUPED_SFB];
    769   FIXP_DBL distOldSum, distNewSum;
    770   INT deltaScfBits;
    771   FIXP_DBL deltaSpecPe;
    772   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
    773   FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f);
    774   INT sfbCnt = psyOutChan->sfbCnt;
    775   INT bSuccess, bCheckScf;
    776   INT i, k;
    777 
    778   /* calc min and max scalfactors */
    779   scfMin = FDK_INT_MAX;
    780   scfMax = FDK_INT_MIN;
    781   for (sfb = 0; sfb < sfbCnt; sfb++) {
    782     if (scf[sfb] != FDK_INT_MIN) {
    783       scfMin = fixMin(scfMin, scf[sfb]);
    784       scfMax = fixMax(scfMax, scf[sfb]);
    785     }
    786   }
    787 
    788   stopSfb = 0;
    789   scfAct = FDK_INT_MIN;
    790   do {
    791     /* search for region with same scf values scfAct */
    792     scfPrev = scfAct;
    793 
    794     sfb = stopSfb;
    795     while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN)) sfb++;
    796     startSfb = sfb;
    797     scfAct = scf[startSfb];
    798     sfb++;
    799     while (sfb < sfbCnt &&
    800            ((scf[sfb] == FDK_INT_MIN) || (scf[sfb] == scf[startSfb])))
    801       sfb++;
    802     stopSfb = sfb;
    803 
    804     if (stopSfb < sfbCnt)
    805       scfNext = scf[stopSfb];
    806     else
    807       scfNext = scfAct;
    808 
    809     if (scfPrev == FDK_INT_MIN) scfPrev = scfAct;
    810 
    811     scfPrevNextMax = fixMax(scfPrev, scfNext);
    812     scfPrevNextMin = fixMin(scfPrev, scfNext);
    813 
    814     /* try to reduce bits by checking scf values in the range
    815        scf[startSfb]...scfHi */
    816     scfHi = fixMax(scfPrevNextMax, scfAct);
    817     /* try to find a better solution by reducing the scf difference to
    818        the nearest possible lower scf */
    819     if (scfPrevNextMax >= scfAct)
    820       scfLo = fixMin(scfAct, scfPrevNextMin);
    821     else
    822       scfLo = scfPrevNextMax;
    823 
    824     if (startSfb < sfbCnt &&
    825         scfHi - scfLo <= MAX_SCF_DELTA) { /* region found */
    826       /* 1. try to save bits by coarser quantization */
    827       if (scfHi > scf[startSfb]) {
    828         /* calculate the allowed distortion */
    829         for (sfb = startSfb; sfb < stopSfb; sfb++) {
    830           if (scf[sfb] != FDK_INT_MIN) {
    831             /* sfbDistMax[sfb] =
    832              * (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f);
    833              */
    834             /* sfbDistMax[sfb] =
    835              * fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f));
    836              */
    837             /* -0.15571537944 = ld64(1.e-3f)*/
    838             sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f / 3.0f),
    839                                     qcOutChannel->sfbThresholdLdData[sfb]) +
    840                               fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]) +
    841                               fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]);
    842             sfbDistMax[sfb] =
    843                 fixMax(sfbDistMax[sfb], qcOutChannel->sfbEnergyLdData[sfb] -
    844                                             FL2FXCONST_DBL(0.15571537944));
    845             sfbDistMax[sfb] =
    846                 fixMin(sfbDistMax[sfb], qcOutChannel->sfbThresholdLdData[sfb]);
    847           }
    848         }
    849 
    850         /* loop over all possible scf values for this region */
    851         bCheckScf = 1;
    852         for (scfNew = scf[startSfb] + 1; scfNew <= scfHi; scfNew++) {
    853           for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
    854 
    855           /* replace scfs in region by scfNew */
    856           for (sfb = startSfb; sfb < stopSfb; sfb++) {
    857             if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
    858           }
    859 
    860           /* estimate change in bit demand for new scfs */
    861           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
    862                                                     startSfb, stopSfb);
    863 
    864           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
    865               psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
    866               sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
    867 
    868           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
    869 
    870           /* new bit demand small enough ? */
    871           if (deltaPeNew < FL2FXCONST_DBL(0.0f)) {
    872             bSuccess = 1;
    873 
    874             /* quantize and calc sum of new distortion */
    875             for (sfb = startSfb; sfb < stopSfb; sfb++) {
    876               if (scfTmp[sfb] != FDK_INT_MIN) {
    877                 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
    878                     qcOutChannel->mdctSpectrum + sfbOffs[sfb],
    879                     quantSpecTmp + sfbOffs[sfb],
    880                     sfbOffs[sfb + 1] - sfbOffs[sfb], scfNew, dZoneQuantEnable);
    881 
    882                 if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
    883                   /* no improvement, skip further dist. calculations */
    884                   bSuccess = 0;
    885                   if (sfbDistNew[sfb] == qcOutChannel->sfbEnergyLdData[sfb]) {
    886                     /* if whole sfb is already quantized to 0, further
    887                        checks with even coarser quant. are useless*/
    888                     bCheckScf = 0;
    889                   }
    890                   break;
    891                 }
    892               }
    893             }
    894             if (bCheckScf == 0) /* further calculations useless ? */
    895               break;
    896             /* distortion small enough ? -> use new scalefactors */
    897             if (bSuccess) {
    898               deltaPe = deltaPeNew;
    899               for (sfb = startSfb; sfb < stopSfb; sfb++) {
    900                 if (scf[sfb] != FDK_INT_MIN) {
    901                   scf[sfb] = scfNew;
    902                   sfbDist[sfb] = sfbDistNew[sfb];
    903 
    904                   for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
    905                     quantSpec[sfbOffs[sfb] + k] =
    906                         quantSpecTmp[sfbOffs[sfb] + k];
    907                 }
    908               }
    909             }
    910           }
    911         }
    912       }
    913 
    914       /* 2. only if coarser quantization was not successful, try to find
    915          a better solution by finer quantization and reducing bits for
    916          scalefactor coding */
    917       if (scfAct == scf[startSfb] && scfLo < scfAct &&
    918           scfMax - scfMin <= MAX_SCF_DELTA) {
    919         int bminScfViolation = 0;
    920 
    921         for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
    922 
    923         scfNew = scfLo;
    924 
    925         /* replace scfs in region by scfNew and
    926            check if in all sfb scfNew >= minScf[sfb] */
    927         for (sfb = startSfb; sfb < stopSfb; sfb++) {
    928           if (scfTmp[sfb] != FDK_INT_MIN) {
    929             scfTmp[sfb] = scfNew;
    930             if (scfNew < minScf[sfb]) bminScfViolation = 1;
    931           }
    932         }
    933 
    934         if (!bminScfViolation) {
    935           /* estimate change in bit demand for new scfs */
    936           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
    937                                                     startSfb, stopSfb);
    938 
    939           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
    940               psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
    941               sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
    942 
    943           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
    944         }
    945 
    946         /* new bit demand small enough ? */
    947         if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) {
    948           /* quantize and calc sum of new distortion */
    949           distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
    950           for (sfb = startSfb; sfb < stopSfb; sfb++) {
    951             if (scfTmp[sfb] != FDK_INT_MIN) {
    952               distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
    953 
    954               sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
    955                   qcOutChannel->mdctSpectrum + sfbOffs[sfb],
    956                   quantSpecTmp + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
    957                   scfNew, dZoneQuantEnable);
    958 
    959               if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
    960                 /* no improvement, skip further dist. calculations */
    961                 distNewSum = distOldSum << 1;
    962                 break;
    963               }
    964               distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
    965             }
    966           }
    967           /* distortion smaller ? -> use new scalefactors */
    968           if (distNewSum < fMult(FL2FXCONST_DBL(0.8f), distOldSum)) {
    969             deltaPe = deltaPeNew;
    970             for (sfb = startSfb; sfb < stopSfb; sfb++) {
    971               if (scf[sfb] != FDK_INT_MIN) {
    972                 scf[sfb] = scfNew;
    973                 sfbDist[sfb] = sfbDistNew[sfb];
    974 
    975                 for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
    976                   quantSpec[sfbOffs[sfb] + k] = quantSpecTmp[sfbOffs[sfb] + k];
    977               }
    978             }
    979           }
    980         }
    981       }
    982 
    983       /* 3. try to find a better solution (save bits) by only reducing the
    984          scalefactor without new quantization */
    985       if (scfMax - scfMin <=
    986           MAX_SCF_DELTA - 3) { /* 3 bec. scf is reduced 3 times,
    987                                   see for loop below */
    988 
    989         for (k = 0; k < sfbCnt; k++) scfTmp[k] = scf[k];
    990 
    991         for (i = 0; i < 3; i++) {
    992           scfNew = scfTmp[startSfb] - 1;
    993           /* replace scfs in region by scfNew */
    994           for (sfb = startSfb; sfb < stopSfb; sfb++) {
    995             if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
    996           }
    997           /* estimate change in bit demand for new scfs */
    998           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
    999                                                     startSfb, stopSfb);
   1000           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits;
   1001           /* new bit demand small enough ? */
   1002           if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) {
   1003             bSuccess = 1;
   1004             distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
   1005             for (sfb = startSfb; sfb < stopSfb; sfb++) {
   1006               if (scfTmp[sfb] != FDK_INT_MIN) {
   1007                 FIXP_DBL sfbEnQ;
   1008                 /* calc the energy and distortion of the quantized spectrum for
   1009                    a smaller scf */
   1010                 FDKaacEnc_calcSfbQuantEnergyAndDist(
   1011                     qcOutChannel->mdctSpectrum + sfbOffs[sfb],
   1012                     quantSpec + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
   1013                     scfNew, &sfbEnQ, &sfbDistNew[sfb]);
   1014 
   1015                 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
   1016                 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
   1017 
   1018                 /*  0.00259488556167 = ld64(1.122f) */
   1019                 /* -0.00778722686652 = ld64(0.7079f) */
   1020                 if ((sfbDistNew[sfb] >
   1021                      (sfbDist[sfb] + FL2FXCONST_DBL(0.00259488556167f))) ||
   1022                     (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] -
   1023                                FL2FXCONST_DBL(0.00778722686652f)))) {
   1024                   bSuccess = 0;
   1025                   break;
   1026                 }
   1027               }
   1028             }
   1029             /* distortion smaller ? -> use new scalefactors */
   1030             if (distNewSum < distOldSum && bSuccess) {
   1031               deltaPe = deltaPeNew;
   1032               for (sfb = startSfb; sfb < stopSfb; sfb++) {
   1033                 if (scf[sfb] != FDK_INT_MIN) {
   1034                   scf[sfb] = scfNew;
   1035                   sfbDist[sfb] = sfbDistNew[sfb];
   1036                 }
   1037               }
   1038             }
   1039           }
   1040         }
   1041       }
   1042     }
   1043   } while (stopSfb <= sfbCnt);
   1044 }
   1045 
   1046 static void FDKaacEnc_EstimateScaleFactorsChannel(
   1047     QC_OUT_CHANNEL *qcOutChannel, PSY_OUT_CHANNEL *psyOutChannel,
   1048     INT *RESTRICT scf, INT *RESTRICT globalGain,
   1049     FIXP_DBL *RESTRICT sfbFormFactorLdData, const INT invQuant,
   1050     SHORT *RESTRICT quantSpec, const INT dZoneQuantEnable) {
   1051   INT i, j, sfb, sfbOffs;
   1052   INT scfInt;
   1053   INT maxSf;
   1054   INT minSf;
   1055   FIXP_DBL threshLdData;
   1056   FIXP_DBL energyLdData;
   1057   FIXP_DBL energyPartLdData;
   1058   FIXP_DBL thresholdPartLdData;
   1059   FIXP_DBL scfFract;
   1060   FIXP_DBL maxSpec;
   1061   INT minScfCalculated[MAX_GROUPED_SFB];
   1062   FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB];
   1063   C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024))
   1064   INT minSfMaxQuant[MAX_GROUPED_SFB];
   1065 
   1066   FIXP_DBL threshConstLdData =
   1067       FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */
   1068   FIXP_DBL convConst = FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */
   1069   FIXP_DBL c1Const =
   1070       FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */
   1071 
   1072   if (invQuant > 0) {
   1073     FDKmemclear(quantSpec, (1024) * sizeof(SHORT));
   1074   }
   1075 
   1076   /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */
   1077   for (i = 0; i < psyOutChannel->sfbCnt; i++) {
   1078     scf[i] = FDK_INT_MIN;
   1079   }
   1080 
   1081   for (i = 0; i < MAX_GROUPED_SFB; i++) {
   1082     minSfMaxQuant[i] = FDK_INT_MIN;
   1083   }
   1084 
   1085   for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
   1086        sfbOffs += psyOutChannel->sfbPerGroup) {
   1087     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
   1088       threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs + sfb];
   1089       energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs + sfb];
   1090 
   1091       sfbDistLdData[sfbOffs + sfb] = energyLdData;
   1092 
   1093       if (energyLdData > threshLdData) {
   1094         FIXP_DBL tmp;
   1095 
   1096         /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */
   1097         /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
   1098         energyPartLdData =
   1099             sfbFormFactorLdData[sfbOffs + sfb] + FL2FXCONST_DBL(0.09375f);
   1100 
   1101         /* influence of allowed distortion */
   1102         /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */
   1103         thresholdPartLdData = threshConstLdData + threshLdData;
   1104 
   1105         /* scf calc */
   1106         /* scfFloat = 8.8585f * (thresholdPart - energyPart); */
   1107         scfFract = thresholdPartLdData - energyPartLdData;
   1108         /* conversion from log2 to log10 */
   1109         scfFract = fMult(convConst, scfFract);
   1110         /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */
   1111         scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f), scfFract >> 3);
   1112 
   1113         /* integer scalefactor */
   1114         /* scfInt = (int)floor(scfFloat); */
   1115         scfInt =
   1116             (INT)(scfFract >>
   1117                   ((DFRACT_BITS - 1) - 3 -
   1118                    LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */
   1119 
   1120         /* maximum of spectrum */
   1121         maxSpec = FL2FXCONST_DBL(0.0f);
   1122 
   1123         /* Unroll by 4, allow dual memory access */
   1124         DWORD_ALIGNED(qcOutChannel->mdctSpectrum);
   1125         for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
   1126              j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j += 4) {
   1127           maxSpec = fMax(maxSpec,
   1128                          fMax(fMax(fAbs(qcOutChannel->mdctSpectrum[j + 0]),
   1129                                    fAbs(qcOutChannel->mdctSpectrum[j + 1])),
   1130                               fMax(fAbs(qcOutChannel->mdctSpectrum[j + 2]),
   1131                                    fAbs(qcOutChannel->mdctSpectrum[j + 3]))));
   1132         }
   1133         /* lower scf limit to avoid quantized values bigger than MAX_QUANT */
   1134         /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */
   1135         /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */
   1136         /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8  => C1/2^8 +
   1137          * log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */
   1138 
   1139         // minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec))
   1140         // >> ((DFRACT_BITS-1)-8))) + 1;
   1141         tmp = CalcLdData(maxSpec);
   1142         if (c1Const > FL2FXCONST_DBL(-1.f) - tmp) {
   1143           minSfMaxQuant[sfbOffs + sfb] =
   1144               ((INT)((c1Const + tmp) >> ((DFRACT_BITS - 1) - 8))) + 1;
   1145         } else {
   1146           minSfMaxQuant[sfbOffs + sfb] =
   1147               ((INT)(FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS - 1) - 8))) + 1;
   1148         }
   1149 
   1150         scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs + sfb]);
   1151 
   1152         /* find better scalefactor with analysis by synthesis */
   1153         if (invQuant > 0) {
   1154           scfInt = FDKaacEnc_improveScf(
   1155               qcOutChannel->mdctSpectrum +
   1156                   psyOutChannel->sfbOffsets[sfbOffs + sfb],
   1157               quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
   1158               quantSpecTmp + psyOutChannel->sfbOffsets[sfbOffs + sfb],
   1159               psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
   1160                   psyOutChannel->sfbOffsets[sfbOffs + sfb],
   1161               threshLdData, scfInt, minSfMaxQuant[sfbOffs + sfb],
   1162               &sfbDistLdData[sfbOffs + sfb], &minScfCalculated[sfbOffs + sfb],
   1163               dZoneQuantEnable);
   1164         }
   1165         scf[sfbOffs + sfb] = scfInt;
   1166       }
   1167     }
   1168   }
   1169 
   1170   if (invQuant > 0) {
   1171     /* try to decrease scf differences */
   1172     FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB];
   1173     FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB];
   1174 
   1175     for (i = 0; i < psyOutChannel->sfbCnt; i++)
   1176       sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN;
   1177 
   1178     FDKaacEnc_calcSfbRelevantLines(
   1179         sfbFormFactorLdData, qcOutChannel->sfbEnergyLdData,
   1180         qcOutChannel->sfbThresholdLdData, psyOutChannel->sfbOffsets,
   1181         psyOutChannel->sfbCnt, psyOutChannel->sfbPerGroup,
   1182         psyOutChannel->maxSfbPerGroup, sfbNRelevantLines);
   1183 
   1184     FDKaacEnc_assimilateSingleScf(
   1185         psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, dZoneQuantEnable,
   1186         scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, sfbFormFactorLdData,
   1187         sfbNRelevantLines, minScfCalculated, 1);
   1188 
   1189     if (invQuant > 1) {
   1190       FDKaacEnc_assimilateMultipleScf(
   1191           psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
   1192           dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
   1193           sfbFormFactorLdData, sfbNRelevantLines);
   1194 
   1195       FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
   1196           psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
   1197           dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
   1198           sfbFormFactorLdData, sfbNRelevantLines);
   1199     }
   1200   }
   1201 
   1202   /* get min scalefac */
   1203   minSf = FDK_INT_MAX;
   1204   for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
   1205        sfbOffs += psyOutChannel->sfbPerGroup) {
   1206     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
   1207       if (scf[sfbOffs + sfb] != FDK_INT_MIN)
   1208         minSf = fixMin(minSf, scf[sfbOffs + sfb]);
   1209     }
   1210   }
   1211 
   1212   /* limit scf delta */
   1213   for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
   1214        sfbOffs += psyOutChannel->sfbPerGroup) {
   1215     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
   1216       if ((scf[sfbOffs + sfb] != FDK_INT_MIN) &&
   1217           (minSf + MAX_SCF_DELTA) < scf[sfbOffs + sfb]) {
   1218         scf[sfbOffs + sfb] = minSf + MAX_SCF_DELTA;
   1219         if (invQuant > 0) { /* changed bands need to be quantized again */
   1220           sfbDistLdData[sfbOffs + sfb] = FDKaacEnc_calcSfbDist(
   1221               qcOutChannel->mdctSpectrum +
   1222                   psyOutChannel->sfbOffsets[sfbOffs + sfb],
   1223               quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
   1224               psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
   1225                   psyOutChannel->sfbOffsets[sfbOffs + sfb],
   1226               scf[sfbOffs + sfb], dZoneQuantEnable);
   1227         }
   1228       }
   1229     }
   1230   }
   1231 
   1232   /* get max scalefac for global gain */
   1233   maxSf = FDK_INT_MIN;
   1234   for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
   1235        sfbOffs += psyOutChannel->sfbPerGroup) {
   1236     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
   1237       maxSf = fixMax(maxSf, scf[sfbOffs + sfb]);
   1238     }
   1239   }
   1240 
   1241   /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */
   1242   if (maxSf > FDK_INT_MIN) {
   1243     *globalGain = maxSf;
   1244     for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
   1245          sfbOffs += psyOutChannel->sfbPerGroup) {
   1246       for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
   1247         if (scf[sfbOffs + sfb] == FDK_INT_MIN) {
   1248           scf[sfbOffs + sfb] = 0;
   1249           /* set band explicitely to zero */
   1250           for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
   1251                j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
   1252             qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
   1253           }
   1254         } else {
   1255           scf[sfbOffs + sfb] = maxSf - scf[sfbOffs + sfb];
   1256         }
   1257       }
   1258     }
   1259   } else {
   1260     *globalGain = 0;
   1261     /* set spectrum explicitely to zero */
   1262     for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
   1263          sfbOffs += psyOutChannel->sfbPerGroup) {
   1264       for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
   1265         scf[sfbOffs + sfb] = 0;
   1266         /* set band explicitely to zero */
   1267         for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
   1268              j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
   1269           qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
   1270         }
   1271       }
   1272     }
   1273   }
   1274 
   1275   /* free quantSpecTmp from scratch */
   1276   C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024))
   1277 }
   1278 
   1279 void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
   1280                                     QC_OUT_CHANNEL *qcOutChannel[],
   1281                                     const INT invQuant,
   1282                                     const INT dZoneQuantEnable,
   1283                                     const INT nChannels) {
   1284   int ch;
   1285 
   1286   for (ch = 0; ch < nChannels; ch++) {
   1287     FDKaacEnc_EstimateScaleFactorsChannel(
   1288         qcOutChannel[ch], psyOutChannel[ch], qcOutChannel[ch]->scf,
   1289         &qcOutChannel[ch]->globalGain, qcOutChannel[ch]->sfbFormFactorLdData,
   1290         invQuant, qcOutChannel[ch]->quantSpec, dZoneQuantEnable);
   1291   }
   1292 }
   1293