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: Band/Line energy calculations
    100 
    101 *******************************************************************************/
    102 
    103 #include "band_nrg.h"
    104 
    105 /*****************************************************************************
    106   functionname: FDKaacEnc_CalcSfbMaxScaleSpec
    107   description:
    108   input:
    109   output:
    110 *****************************************************************************/
    111 void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum,
    112                                    const INT *RESTRICT bandOffset,
    113                                    INT *RESTRICT sfbMaxScaleSpec,
    114                                    const INT numBands) {
    115   INT i, j;
    116   FIXP_DBL maxSpc, tmp;
    117 
    118   for (i = 0; i < numBands; i++) {
    119     maxSpc = (FIXP_DBL)0;
    120 
    121     DWORD_ALIGNED(mdctSpectrum);
    122 
    123     for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
    124       tmp = fixp_abs(mdctSpectrum[j]);
    125       maxSpc = fixMax(maxSpc, tmp);
    126     }
    127     j = CntLeadingZeros(maxSpc) - 1;
    128     sfbMaxScaleSpec[i] = fixMin((DFRACT_BITS - 2), j);
    129     /* CountLeadingBits() is not necessary here since test value is always > 0
    130      */
    131   }
    132 }
    133 
    134 /*****************************************************************************
    135   functionname: FDKaacEnc_CheckBandEnergyOptim
    136   description:
    137   input:
    138   output:
    139 *****************************************************************************/
    140 FIXP_DBL
    141 FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum,
    142                                const INT *const RESTRICT sfbMaxScaleSpec,
    143                                const INT *const RESTRICT bandOffset,
    144                                const INT numBands,
    145                                FIXP_DBL *RESTRICT bandEnergy,
    146                                FIXP_DBL *RESTRICT bandEnergyLdData,
    147                                const INT minSpecShift) {
    148   INT i, j, scale, nr = 0;
    149   FIXP_DBL maxNrgLd = FL2FXCONST_DBL(-1.0f);
    150   FIXP_DBL maxNrg = 0;
    151   FIXP_DBL spec;
    152 
    153   for (i = 0; i < numBands; i++) {
    154     scale = fixMax(0, sfbMaxScaleSpec[i] - 4);
    155     FIXP_DBL tmp = 0;
    156 
    157     DWORD_ALIGNED(mdctSpectrum);
    158 
    159     for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
    160       spec = mdctSpectrum[j] << scale;
    161       tmp = fPow2AddDiv2(tmp, spec);
    162     }
    163     bandEnergy[i] = tmp << 1;
    164 
    165     /* calculate ld of bandNrg, subtract scaling */
    166     bandEnergyLdData[i] = CalcLdData(bandEnergy[i]);
    167     if (bandEnergyLdData[i] != FL2FXCONST_DBL(-1.0f)) {
    168       bandEnergyLdData[i] -= scale * FL2FXCONST_DBL(2.0 / 64);
    169     }
    170     /* find index of maxNrg */
    171     if (bandEnergyLdData[i] > maxNrgLd) {
    172       maxNrgLd = bandEnergyLdData[i];
    173       nr = i;
    174     }
    175   }
    176 
    177   /* return unscaled maxNrg*/
    178   scale = fixMax(0, sfbMaxScaleSpec[nr] - 4);
    179   scale = fixMax(2 * (minSpecShift - scale), -(DFRACT_BITS - 1));
    180 
    181   maxNrg = scaleValue(bandEnergy[nr], scale);
    182 
    183   return maxNrg;
    184 }
    185 
    186 /*****************************************************************************
    187   functionname: FDKaacEnc_CalcBandEnergyOptimLong
    188   description:
    189   input:
    190   output:
    191 *****************************************************************************/
    192 INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum,
    193                                       INT *RESTRICT sfbMaxScaleSpec,
    194                                       const INT *RESTRICT bandOffset,
    195                                       const INT numBands,
    196                                       FIXP_DBL *RESTRICT bandEnergy,
    197                                       FIXP_DBL *RESTRICT bandEnergyLdData) {
    198   INT i, j, shiftBits = 0;
    199   FIXP_DBL maxNrgLd = FL2FXCONST_DBL(0.0f);
    200 
    201   FIXP_DBL spec;
    202 
    203   for (i = 0; i < numBands; i++) {
    204     INT leadingBits = sfbMaxScaleSpec[i] -
    205                       4; /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */
    206     FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
    207     /* don't use scaleValue() here, it increases workload quite sufficiently...
    208      */
    209     if (leadingBits >= 0) {
    210       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
    211         spec = mdctSpectrum[j] << leadingBits;
    212         tmp = fPow2AddDiv2(tmp, spec);
    213       }
    214     } else {
    215       INT shift = -leadingBits;
    216       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
    217         spec = mdctSpectrum[j] >> shift;
    218         tmp = fPow2AddDiv2(tmp, spec);
    219       }
    220     }
    221     bandEnergy[i] = tmp << 1;
    222   }
    223 
    224   /* calculate ld of bandNrg, subtract scaling */
    225   LdDataVector(bandEnergy, bandEnergyLdData, numBands);
    226   for (i = numBands; i-- != 0;) {
    227     FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i] - 4) * FL2FXCONST_DBL(2.0 / 64);
    228 
    229     bandEnergyLdData[i] = (bandEnergyLdData[i] >=
    230                            ((FL2FXCONST_DBL(-1.f) >> 1) + (scaleDiff >> 1)))
    231                               ? bandEnergyLdData[i] - scaleDiff
    232                               : FL2FXCONST_DBL(-1.f);
    233     /* find maxNrgLd */
    234     maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]);
    235   }
    236 
    237   if (maxNrgLd <= (FIXP_DBL)0) {
    238     for (i = numBands; i-- != 0;) {
    239       INT scale = fixMin((sfbMaxScaleSpec[i] - 4) << 1, (DFRACT_BITS - 1));
    240       bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
    241     }
    242     return 0;
    243   } else { /* scale down NRGs */
    244     while (maxNrgLd > FL2FXCONST_DBL(0.0f)) {
    245       maxNrgLd -= FL2FXCONST_DBL(2.0 / 64);
    246       shiftBits++;
    247     }
    248     for (i = numBands; i-- != 0;) {
    249       INT scale = fixMin(((sfbMaxScaleSpec[i] - 4) + shiftBits) << 1,
    250                          (DFRACT_BITS - 1));
    251       bandEnergyLdData[i] -= shiftBits * FL2FXCONST_DBL(2.0 / 64);
    252       bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
    253     }
    254     return shiftBits;
    255   }
    256 }
    257 
    258 /*****************************************************************************
    259   functionname: FDKaacEnc_CalcBandEnergyOptimShort
    260   description:
    261   input:
    262   output:
    263 *****************************************************************************/
    264 void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum,
    265                                         INT *RESTRICT sfbMaxScaleSpec,
    266                                         const INT *RESTRICT bandOffset,
    267                                         const INT numBands,
    268                                         FIXP_DBL *RESTRICT bandEnergy) {
    269   INT i, j;
    270 
    271   for (i = 0; i < numBands; i++) {
    272     int leadingBits = sfbMaxScaleSpec[i] -
    273                       3; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
    274     FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
    275     for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
    276       FIXP_DBL spec = scaleValue(mdctSpectrum[j], leadingBits);
    277       tmp = fPow2AddDiv2(tmp, spec);
    278     }
    279     bandEnergy[i] = tmp;
    280   }
    281 
    282   for (i = 0; i < numBands; i++) {
    283     INT scale = (2 * (sfbMaxScaleSpec[i] - 3)) -
    284                 1; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
    285     scale = fixMax(fixMin(scale, (DFRACT_BITS - 1)), -(DFRACT_BITS - 1));
    286     bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale);
    287   }
    288 }
    289 
    290 /*****************************************************************************
    291   functionname: FDKaacEnc_CalcBandNrgMSOpt
    292   description:
    293   input:
    294   output:
    295 *****************************************************************************/
    296 void FDKaacEnc_CalcBandNrgMSOpt(
    297     const FIXP_DBL *RESTRICT mdctSpectrumLeft,
    298     const FIXP_DBL *RESTRICT mdctSpectrumRight,
    299     INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight,
    300     const INT *RESTRICT bandOffset, const INT numBands,
    301     FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide,
    302     INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData,
    303     FIXP_DBL *RESTRICT bandEnergySideLdData) {
    304   INT i, j, minScale;
    305   FIXP_DBL NrgMid, NrgSide, specm, specs;
    306 
    307   for (i = 0; i < numBands; i++) {
    308     NrgMid = NrgSide = FL2FXCONST_DBL(0.0);
    309     minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]) - 4;
    310     minScale = fixMax(0, minScale);
    311 
    312     if (minScale > 0) {
    313       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
    314         FIXP_DBL specL = mdctSpectrumLeft[j] << (minScale - 1);
    315         FIXP_DBL specR = mdctSpectrumRight[j] << (minScale - 1);
    316         specm = specL + specR;
    317         specs = specL - specR;
    318         NrgMid = fPow2AddDiv2(NrgMid, specm);
    319         NrgSide = fPow2AddDiv2(NrgSide, specs);
    320       }
    321     } else {
    322       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
    323         FIXP_DBL specL = mdctSpectrumLeft[j] >> 1;
    324         FIXP_DBL specR = mdctSpectrumRight[j] >> 1;
    325         specm = specL + specR;
    326         specs = specL - specR;
    327         NrgMid = fPow2AddDiv2(NrgMid, specm);
    328         NrgSide = fPow2AddDiv2(NrgSide, specs);
    329       }
    330     }
    331     bandEnergyMid[i] = fMin(NrgMid, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
    332     bandEnergySide[i] = fMin(NrgSide, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
    333   }
    334 
    335   if (calcLdData) {
    336     LdDataVector(bandEnergyMid, bandEnergyMidLdData, numBands);
    337     LdDataVector(bandEnergySide, bandEnergySideLdData, numBands);
    338   }
    339 
    340   for (i = 0; i < numBands; i++) {
    341     minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]);
    342     INT scale = fixMax(0, 2 * (minScale - 4));
    343 
    344     if (calcLdData) {
    345       /* using the minimal scaling of left and right channel can cause very
    346       small energies; check ldNrg before subtract scaling multiplication:
    347       fract*INT we don't need fMult */
    348 
    349       int minus = scale * FL2FXCONST_DBL(1.0 / 64);
    350 
    351       if (bandEnergyMidLdData[i] != FL2FXCONST_DBL(-1.0f))
    352         bandEnergyMidLdData[i] -= minus;
    353 
    354       if (bandEnergySideLdData[i] != FL2FXCONST_DBL(-1.0f))
    355         bandEnergySideLdData[i] -= minus;
    356     }
    357     scale = fixMin(scale, (DFRACT_BITS - 1));
    358     bandEnergyMid[i] >>= scale;
    359     bandEnergySide[i] >>= scale;
    360   }
    361 }
    362