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 - 2013 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-4 AAC Decoder  **************************
     85 
     86    Author(s):   Josef Hoepfl
     87    Description: perceptual noise substitution tool
     88 
     89 ******************************************************************************/
     90 
     91 #include "aacdec_pns.h"
     92 
     93 
     94 #include "aac_ram.h"
     95 #include "aac_rom.h"
     96 #include "channelinfo.h"
     97 #include "block.h"
     98 #include "FDK_bitstream.h"
     99 
    100 #include "genericStds.h"
    101 
    102 
    103 #define NOISE_OFFSET 90           /* cf. ISO 14496-3 p. 175 */
    104 
    105 /*!
    106   \brief Reset InterChannel and PNS data
    107 
    108   The function resets the InterChannel and PNS data
    109 */
    110 void CPns_ResetData(
    111     CPnsData *pPnsData,
    112     CPnsInterChannelData *pPnsInterChannelData
    113     )
    114 {
    115   /* Assign pointer always, since pPnsData is not persistent data */
    116   pPnsData->pPnsInterChannelData = pPnsInterChannelData;
    117   pPnsData->PnsActive = 0;
    118   pPnsData->CurrentEnergy = 0;
    119 
    120   FDKmemclear(pPnsData->pnsUsed,(8*16)*sizeof(UCHAR));
    121   FDKmemclear(pPnsInterChannelData->correlated,(8*16)*sizeof(UCHAR));
    122 }
    123 
    124 /*!
    125   \brief Initialize PNS data
    126 
    127   The function initializes the PNS data
    128 */
    129 void CPns_InitPns(
    130     CPnsData *pPnsData,
    131     CPnsInterChannelData *pPnsInterChannelData,
    132     INT* currentSeed, INT* randomSeed)
    133 {
    134   /* save pointer to inter channel data */
    135   pPnsData->pPnsInterChannelData = pPnsInterChannelData;
    136 
    137   /* use pointer because seed has to be
    138      same, left and right channel ! */
    139   pPnsData->currentSeed = currentSeed;
    140   pPnsData->randomSeed  = randomSeed;
    141 }
    142 
    143 /*!
    144   \brief Indicates if PNS is used
    145 
    146   The function returns a value indicating whether PNS is used or not
    147   acordding to the noise energy
    148 
    149   \return  PNS used
    150 */
    151 int CPns_IsPnsUsed (const CPnsData *pPnsData,
    152                     const int group,
    153                     const int band)
    154 {
    155   unsigned pns_band = group*16+band;
    156 
    157   return pPnsData->pnsUsed[pns_band] & (UCHAR)1;
    158 }
    159 
    160 /*!
    161   \brief Set correlation
    162 
    163   The function activates the noise correlation between the channel pair
    164 */
    165 void CPns_SetCorrelation(CPnsData *pPnsData,
    166                          const int group,
    167                          const int band,
    168                          const int outofphase)
    169 {
    170   CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
    171   unsigned pns_band = group*16+band;
    172 
    173   pInterChannelData->correlated[pns_band] = (outofphase) ? 3 : 1;
    174 }
    175 
    176 /*!
    177   \brief Indicates if correlation is used
    178 
    179   The function indicates if the noise correlation between the channel pair
    180   is activated
    181 
    182   \return  PNS is correlated
    183 */
    184 static
    185 int CPns_IsCorrelated(const CPnsData *pPnsData,
    186                       const int group,
    187                       const int band)
    188 {
    189   CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
    190   unsigned pns_band = group*16+band;
    191 
    192   return (pInterChannelData->correlated[pns_band] & 0x01) ? 1 : 0;
    193 }
    194 
    195 /*!
    196   \brief Indicates if correlated out of phase mode is used.
    197 
    198   The function indicates if the noise correlation between the channel pair
    199   is activated in out-of-phase mode.
    200 
    201   \return  PNS is out-of-phase
    202 */
    203 static
    204 int CPns_IsOutOfPhase(const CPnsData *pPnsData,
    205                       const int group,
    206                       const int band)
    207 {
    208   CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
    209   unsigned pns_band = group*16+band;
    210 
    211   return (pInterChannelData->correlated[pns_band] & 0x02) ? 1 : 0;
    212 }
    213 
    214 /*!
    215   \brief Read PNS information
    216 
    217   The function reads the PNS information from the bitstream
    218 */
    219 void CPns_Read (CPnsData *pPnsData,
    220                 HANDLE_FDK_BITSTREAM bs,
    221                 const CodeBookDescription *hcb,
    222                 SHORT *pScaleFactor,
    223                 UCHAR global_gain,
    224                 int band,
    225                 int group /* = 0 */)
    226 {
    227   int delta ;
    228   UINT pns_band = group*16+band;
    229 
    230   if (pPnsData->PnsActive) {
    231     /* Next PNS band case */
    232     delta = CBlock_DecodeHuffmanWord (bs, hcb) - 60;
    233   } else {
    234     /* First PNS band case */
    235     int noiseStartValue = FDKreadBits(bs,9);
    236 
    237     delta = noiseStartValue - 256 ;
    238     pPnsData->PnsActive = 1;
    239     pPnsData->CurrentEnergy = global_gain - NOISE_OFFSET;
    240   }
    241 
    242   pPnsData->CurrentEnergy += delta ;
    243   pScaleFactor[pns_band] = pPnsData->CurrentEnergy;
    244 
    245   pPnsData->pnsUsed[pns_band] = 1;
    246 }
    247 
    248 
    249 /**
    250  * \brief Generate a vector of noise of given length. The noise values are
    251  *        scaled in order to yield a noise energy of 1.0
    252  * \param spec pointer to were the noise values will be written to.
    253  * \param size amount of noise values to be generated.
    254  * \param pRandomState pointer to the state of the random generator being used.
    255  * \return exponent of generated noise vector.
    256  */
    257 static int GenerateRandomVector (FIXP_DBL *RESTRICT spec,
    258                                   int size,
    259                                   int *pRandomState)
    260 {
    261   int i, invNrg_e = 0, nrg_e = 0;
    262   FIXP_DBL invNrg_m, nrg_m = FL2FXCONST_DBL(0.0f) ;
    263   FIXP_DBL *RESTRICT ptr = spec;
    264   int randomState = *pRandomState;
    265 
    266 #define GEN_NOISE_NRG_SCALE 7
    267 
    268   /* Generate noise and calculate energy. */
    269   for (i=0; i<size; i++)
    270   {
    271     randomState = (1664525L * randomState) + 1013904223L; // Numerical Recipes
    272     nrg_m = fPow2AddDiv2(nrg_m, (FIXP_DBL)randomState>>GEN_NOISE_NRG_SCALE);
    273     *ptr++ = (FIXP_DBL)randomState;
    274   }
    275   nrg_e = GEN_NOISE_NRG_SCALE*2 + 1;
    276 
    277   /* weight noise with = 1 / sqrt_nrg; */
    278   invNrg_m = invSqrtNorm2(nrg_m<<1, &invNrg_e);
    279   invNrg_e += -((nrg_e-1)>>1);
    280 
    281   for (i=size; i--; )
    282   {
    283     spec[i] = fMult(spec[i], invNrg_m);
    284   }
    285 
    286   /* Store random state */
    287   *pRandomState = randomState;
    288 
    289   return invNrg_e;
    290 }
    291 
    292 static void ScaleBand (FIXP_DBL *RESTRICT spec, int size, int scaleFactor, int specScale, int noise_e, int out_of_phase)
    293 {
    294   int i, shift, sfExponent;
    295   FIXP_DBL sfMatissa;
    296 
    297   /* Get gain from scale factor value = 2^(scaleFactor * 0.25) */
    298   sfMatissa = MantissaTable[scaleFactor & 0x03][0];
    299   /* sfExponent = (scaleFactor >> 2) + ExponentTable[scaleFactor & 0x03][0]; */
    300   /* Note:  ExponentTable[scaleFactor & 0x03][0] is always 1. */
    301   sfExponent = (scaleFactor >> 2) + 1;
    302 
    303   if (out_of_phase != 0) {
    304     sfMatissa = -sfMatissa;
    305   }
    306 
    307   /* +1 because of fMultDiv2 below. */
    308   shift = sfExponent - specScale + 1 + noise_e;
    309 
    310   /* Apply gain to noise values */
    311   if (shift>=0) {
    312     shift = fixMin( shift, DFRACT_BITS-1 );
    313     for (i = size ; i-- != 0; ) {
    314       spec [i] = fMultDiv2 (spec [i], sfMatissa) << shift;
    315     }
    316   } else {
    317     shift = fixMin( -shift, DFRACT_BITS-1 );
    318     for (i = size ; i-- != 0; ) {
    319       spec [i] = fMultDiv2 (spec [i], sfMatissa) >> shift;
    320     }
    321   }
    322 }
    323 
    324 
    325 /*!
    326   \brief Apply PNS
    327 
    328   The function applies PNS (i.e. it generates noise) on the bands
    329   flagged as noisy bands
    330 
    331 */
    332 void CPns_Apply (const CPnsData *pPnsData,
    333                  const CIcsInfo *pIcsInfo,
    334                  SPECTRAL_PTR pSpectrum,
    335                  const SHORT    *pSpecScale,
    336                  const SHORT    *pScaleFactor,
    337                  const SamplingRateInfo *pSamplingRateInfo,
    338                  const INT granuleLength,
    339                  const int channel)
    340 {
    341   if (pPnsData->PnsActive) {
    342     const short *BandOffsets = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo);
    343 
    344     int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(pIcsInfo);
    345 
    346     for (int window = 0, group = 0; group < GetWindowGroups(pIcsInfo); group++) {
    347       for (int groupwin = 0; groupwin < GetWindowGroupLength(pIcsInfo, group); groupwin++, window++) {
    348         FIXP_DBL *spectrum = SPEC(pSpectrum, window, granuleLength);
    349 
    350         for (int band = 0 ; band < ScaleFactorBandsTransmitted; band++) {
    351           if (CPns_IsPnsUsed (pPnsData, group, band)) {
    352             UINT pns_band = group*16+band;
    353 
    354             int bandWidth = BandOffsets [band + 1] - BandOffsets [band] ;
    355             int noise_e;
    356 
    357             FDK_ASSERT(bandWidth >= 0);
    358 
    359             if (channel > 0 && CPns_IsCorrelated(pPnsData, group, band))
    360             {
    361               noise_e = GenerateRandomVector (spectrum + BandOffsets [band], bandWidth,
    362                                     &pPnsData->randomSeed [pns_band]) ;
    363             }
    364             else
    365             {
    366               pPnsData->randomSeed [pns_band] = *pPnsData->currentSeed ;
    367 
    368               noise_e = GenerateRandomVector (spectrum + BandOffsets [band], bandWidth,
    369                                     pPnsData->currentSeed) ;
    370             }
    371 
    372             int outOfPhase  = CPns_IsOutOfPhase (pPnsData, group, band);
    373 
    374             ScaleBand (spectrum + BandOffsets [band], bandWidth,
    375                        pScaleFactor[pns_band],
    376                        pSpecScale[window], noise_e, outOfPhase) ;
    377           }
    378         }
    379       }
    380     }
    381   }
    382 }
    383