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