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: Quantization
     88 
     89 ******************************************************************************/
     90 
     91 #include "quantize.h"
     92 
     93 #include "aacEnc_rom.h"
     94 
     95 /*****************************************************************************
     96 
     97     functionname: FDKaacEnc_quantizeLines
     98     description: quantizes spectrum lines
     99     returns:
    100     input: global gain, number of lines to process, spectral data
    101     output: quantized spectrum
    102 
    103 *****************************************************************************/
    104 static void FDKaacEnc_quantizeLines(INT      gain,
    105                           INT      noOfLines,
    106                           FIXP_DBL *mdctSpectrum,
    107                           SHORT      *quaSpectrum)
    108 {
    109   int   line;
    110   FIXP_DBL k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>16;
    111   FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3];
    112   INT      quantizershift = ((-gain)>>2)+1;
    113 
    114 
    115   for (line = 0; line < noOfLines; line++)
    116   {
    117     FIXP_DBL accu = fMultDiv2(mdctSpectrum[line],quantizer);
    118 
    119     if (accu < FL2FXCONST_DBL(0.0f))
    120     {
    121       accu=-accu;
    122       /* normalize */
    123       INT   accuShift = CntLeadingZeros(accu) - 1;  /* CountLeadingBits() is not necessary here since test value is always > 0 */
    124       accu <<= accuShift;
    125       INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
    126       INT totalShift = quantizershift-accuShift+1;
    127       accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]);
    128       totalShift = (16-4)-(3*(totalShift>>2));
    129       FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */
    130       accu>>=totalShift;
    131       quaSpectrum[line] = (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS-1-16)));
    132     }
    133     else if(accu > FL2FXCONST_DBL(0.0f))
    134     {
    135       /* normalize */
    136       INT   accuShift = CntLeadingZeros(accu) - 1;  /* CountLeadingBits() is not necessary here since test value is always > 0 */
    137       accu <<= accuShift;
    138       INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
    139       INT totalShift = quantizershift-accuShift+1;
    140       accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]);
    141       totalShift = (16-4)-(3*(totalShift>>2));
    142       FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */
    143       accu>>=totalShift;
    144       quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS-1-16));
    145     }
    146     else
    147       quaSpectrum[line]=0;
    148   }
    149 }
    150 
    151 
    152 /*****************************************************************************
    153 
    154     functionname:iFDKaacEnc_quantizeLines
    155     description: iquantizes spectrum lines
    156                  mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)
    157     input: global gain, number of lines to process,quantized spectrum
    158     output: spectral data
    159 
    160 *****************************************************************************/
    161 static void FDKaacEnc_invQuantizeLines(INT  gain,
    162                              INT  noOfLines,
    163                              SHORT *quantSpectrum,
    164                              FIXP_DBL *mdctSpectrum)
    165 
    166 {
    167   INT iquantizermod;
    168   INT iquantizershift;
    169   INT line;
    170 
    171   iquantizermod = gain&3;
    172   iquantizershift = gain>>2;
    173 
    174   for (line = 0; line < noOfLines; line++) {
    175 
    176     if(quantSpectrum[line] < 0) {
    177       FIXP_DBL accu;
    178       INT ex,specExp,tabIndex;
    179       FIXP_DBL s,t;
    180 
    181       accu = (FIXP_DBL) -quantSpectrum[line];
    182 
    183       ex = CountLeadingBits(accu);
    184       accu <<= ex;
    185       specExp = (DFRACT_BITS-1) - ex;
    186 
    187       FDK_ASSERT(specExp < 14);       /* this fails if abs(value) > 8191 */
    188 
    189       tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
    190 
    191       /* calculate "mantissa" ^4/3 */
    192       s = FDKaacEnc_mTab_4_3Elc[tabIndex];
    193 
    194       /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */
    195       t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
    196 
    197       /* multiply "mantissa" ^4/3 with exponent multiplier */
    198       accu = fMult(s,t);
    199 
    200       /* get approperiate exponent shifter */
    201       specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */
    202 
    203       if ((-iquantizershift-specExp) < 0)
    204         accu <<= -(-iquantizershift-specExp);
    205       else
    206         accu >>= -iquantizershift-specExp;
    207 
    208       mdctSpectrum[line] = -accu;
    209     }
    210     else if (quantSpectrum[line] > 0) {
    211       FIXP_DBL accu;
    212       INT ex,specExp,tabIndex;
    213       FIXP_DBL s,t;
    214 
    215       accu = (FIXP_DBL)(INT)quantSpectrum[line];
    216 
    217       ex = CountLeadingBits(accu);
    218       accu <<= ex;
    219       specExp = (DFRACT_BITS-1) - ex;
    220 
    221       FDK_ASSERT(specExp < 14);       /* this fails if abs(value) > 8191 */
    222 
    223       tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
    224 
    225       /* calculate "mantissa" ^4/3 */
    226       s = FDKaacEnc_mTab_4_3Elc[tabIndex];
    227 
    228       /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */
    229       t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
    230 
    231       /* multiply "mantissa" ^4/3 with exponent multiplier */
    232       accu = fMult(s,t);
    233 
    234       /* get approperiate exponent shifter */
    235       specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */
    236 
    237       if (( -iquantizershift-specExp) < 0)
    238         accu <<= -(-iquantizershift-specExp);
    239       else
    240         accu >>= -iquantizershift-specExp;
    241 
    242       mdctSpectrum[line] = accu;
    243     }
    244     else {
    245       mdctSpectrum[line] = FL2FXCONST_DBL(0.0f);
    246     }
    247   }
    248 }
    249 
    250 /*****************************************************************************
    251 
    252     functionname: FDKaacEnc_QuantizeSpectrum
    253     description: quantizes the entire spectrum
    254     returns:
    255     input: number of scalefactor bands to be quantized, ...
    256     output: quantized spectrum
    257 
    258 *****************************************************************************/
    259 void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
    260                       INT maxSfbPerGroup,
    261                       INT sfbPerGroup,
    262                       INT *sfbOffset,
    263                       FIXP_DBL *mdctSpectrum,
    264                       INT globalGain,
    265                       INT *scalefactors,
    266                       SHORT *quantizedSpectrum)
    267 {
    268   INT sfbOffs,sfb;
    269 
    270   /* in FDKaacEnc_quantizeLines quaSpectrum is calculated with:
    271         spec^(3/4) * 2^(-3/16*QSS) * 2^(3/4*scale) + k
    272      simplify scaling calculation and reduce QSS before:
    273         spec^(3/4) * 2^(-3/16*(QSS - 4*scale)) */
    274 
    275   for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup)
    276   for (sfb = 0; sfb < maxSfbPerGroup; sfb++)
    277   {
    278     INT scalefactor = scalefactors[sfbOffs+sfb] ;
    279 
    280     FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */
    281                   sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb],
    282                   mdctSpectrum + sfbOffset[sfbOffs+sfb],
    283                   quantizedSpectrum + sfbOffset[sfbOffs+sfb]);
    284   }
    285 }
    286 
    287 /*****************************************************************************
    288 
    289     functionname: FDKaacEnc_calcSfbDist
    290     description: calculates distortion of quantized values
    291     returns: distortion
    292     input: gain, number of lines to process, spectral data
    293     output:
    294 
    295 *****************************************************************************/
    296 FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
    297                      SHORT *quantSpectrum,
    298                      INT noOfLines,
    299                      INT gain
    300                      )
    301 {
    302   INT i,scale;
    303   FIXP_DBL xfsf;
    304   FIXP_DBL diff;
    305   FIXP_DBL invQuantSpec;
    306 
    307   xfsf = FL2FXCONST_DBL(0.0f);
    308 
    309   for (i=0; i<noOfLines; i++) {
    310     /* quantization */
    311     FDKaacEnc_quantizeLines(gain,
    312                   1,
    313                  &mdctSpectrum[i],
    314                  &quantSpectrum[i]);
    315 
    316     if (fAbs(quantSpectrum[i])>MAX_QUANT) {
    317       return FL2FXCONST_DBL(0.0f);
    318     }
    319     /* inverse quantization */
    320     FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec);
    321 
    322     /* dist */
    323     diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1));
    324 
    325     scale = CountLeadingBits(diff);
    326     diff = scaleValue(diff, scale);
    327     diff = fPow2(diff);
    328     scale = fixMin(2*(scale-1), DFRACT_BITS-1);
    329 
    330     diff = scaleValue(diff, -scale);
    331 
    332     xfsf = xfsf + diff;
    333   }
    334 
    335   xfsf = CalcLdData(xfsf);
    336 
    337   return xfsf;
    338 }
    339 
    340 /*****************************************************************************
    341 
    342     functionname: FDKaacEnc_calcSfbQuantEnergyAndDist
    343     description: calculates energy and distortion of quantized values
    344     returns:
    345     input: gain, number of lines to process, quantized spectral data,
    346            spectral data
    347     output: energy, distortion
    348 
    349 *****************************************************************************/
    350 void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
    351                                SHORT *quantSpectrum,
    352                                INT noOfLines,
    353                                INT gain,
    354                                FIXP_DBL *en,
    355                                FIXP_DBL *dist)
    356 {
    357   INT i,scale;
    358   FIXP_DBL invQuantSpec;
    359   FIXP_DBL diff;
    360 
    361   FIXP_DBL energy = FL2FXCONST_DBL(0.0f);
    362   FIXP_DBL distortion = FL2FXCONST_DBL(0.0f);
    363 
    364   for (i=0; i<noOfLines; i++) {
    365 
    366     if (fAbs(quantSpectrum[i])>MAX_QUANT) {
    367       *en   = FL2FXCONST_DBL(0.0f);
    368       *dist = FL2FXCONST_DBL(0.0f);
    369       return;
    370     }
    371 
    372     /* inverse quantization */
    373     FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec);
    374 
    375     /* energy */
    376     energy += fPow2(invQuantSpec);
    377 
    378     /* dist */
    379     diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1));
    380 
    381     scale = CountLeadingBits(diff);
    382     diff = scaleValue(diff, scale);
    383     diff = fPow2(diff);
    384 
    385     scale = fixMin(2*(scale-1), DFRACT_BITS-1);
    386 
    387     diff = scaleValue(diff, -scale);
    388 
    389     distortion += diff;
    390   }
    391 
    392   *en   = CalcLdData(energy)+FL2FXCONST_DBL(0.03125f);
    393   *dist = CalcLdData(distortion);
    394 }
    395 
    396