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 /**************************** SBR encoder library ******************************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 /*!
    104   \file
    105   \brief  FDK resampler tool box:$Revision: 91655 $
    106   \author M. Werner
    107 */
    108 
    109 #include "resampler.h"
    110 
    111 #include "genericStds.h"
    112 
    113 /**************************************************************************/
    114 /*                   BIQUAD Filter Specifications                         */
    115 /**************************************************************************/
    116 
    117 #define B1 0
    118 #define B2 1
    119 #define A1 2
    120 #define A2 3
    121 
    122 #define BQC(x) FL2FXCONST_SGL(x / 2)
    123 
    124 struct FILTER_PARAM {
    125   const FIXP_SGL *coeffa; /*! SOS matrix One row/section. Scaled using BQC().
    126                              Order of coefficients: B1,B2,A1,A2. B0=A0=1.0 */
    127   FIXP_DBL g;             /*! overall gain */
    128   int Wc;       /*! normalized passband bandwidth at input samplerate * 1000 */
    129   int noCoeffs; /*! number of filter coeffs */
    130   int delay;    /*! delay in samples at input samplerate */
    131 };
    132 
    133 #define BIQUAD_COEFSTEP 4
    134 
    135 /**
    136  *\brief Low Pass
    137  Wc = 0,5, order 30, Stop Band -96dB. Wc criteria is "almost 0dB passband", not
    138  the usual -3db gain point. [b,a]=cheby2(30,96,0.505) [sos,g]=tf2sos(b,a)
    139  bandwidth 0.48
    140  */
    141 static const FIXP_SGL sos48[] = {
    142     BQC(1.98941075681938),      BQC(0.999999996890811),
    143     BQC(0.863264527201963),     BQC(0.189553799960663),
    144     BQC(1.90733804822445),      BQC(1.00000001736189),
    145     BQC(0.836321575841691),     BQC(0.203505809266564),
    146     BQC(1.75616665495325),      BQC(0.999999946079721),
    147     BQC(0.784699225121588),     BQC(0.230471265506986),
    148     BQC(1.55727745512726),      BQC(1.00000011737815),
    149     BQC(0.712515423588351),     BQC(0.268752723900498),
    150     BQC(1.33407591943643),      BQC(0.999999795953228),
    151     BQC(0.625059117330989),     BQC(0.316194685288965),
    152     BQC(1.10689898412458),      BQC(1.00000035057114),
    153     BQC(0.52803514366398),      BQC(0.370517843224669),
    154     BQC(0.89060371078454),      BQC(0.999999343962822),
    155     BQC(0.426920462165257),     BQC(0.429608200207746),
    156     BQC(0.694438261209433),     BQC(1.0000008629792),
    157     BQC(0.326530699561716),     BQC(0.491714450654174),
    158     BQC(0.523237800935322),     BQC(1.00000101349782),
    159     BQC(0.230829556274851),     BQC(0.555559034843281),
    160     BQC(0.378631165929563),     BQC(0.99998986482665),
    161     BQC(0.142906422036095),     BQC(0.620338874442411),
    162     BQC(0.260786911308437),     BQC(1.00003261460178),
    163     BQC(0.0651008576256505),    BQC(0.685759923926262),
    164     BQC(0.168409429188098),     BQC(0.999933049695828),
    165     BQC(-0.000790067789975562), BQC(0.751905896602325),
    166     BQC(0.100724533818628),     BQC(1.00009472669872),
    167     BQC(-0.0533772830257041),   BQC(0.81930744384525),
    168     BQC(0.0561434357867363),    BQC(0.999911636304276),
    169     BQC(-0.0913550299236405),   BQC(0.88883625875915),
    170     BQC(0.0341680678662057),    BQC(1.00003667508676),
    171     BQC(-0.113405185536697),    BQC(0.961756638268446)};
    172 
    173 static const FIXP_DBL g48 =
    174     FL2FXCONST_DBL(0.002712866530047) - (FIXP_DBL)0x8000;
    175 
    176 static const struct FILTER_PARAM param_set48 = {
    177     sos48, g48, 480, 15, 4 /* LF 2 */
    178 };
    179 
    180 /**
    181  *\brief Low Pass
    182  Wc = 0,5, order 24, Stop Band -96dB. Wc criteria is "almost 0dB passband", not
    183  the usual -3db gain point. [b,a]=cheby2(24,96,0.5) [sos,g]=tf2sos(b,a)
    184  bandwidth 0.45
    185  */
    186 static const FIXP_SGL sos45[] = {
    187     BQC(1.982962601444),     BQC(1.00000000007504),    BQC(0.646113303737836),
    188     BQC(0.10851149979981),   BQC(1.85334094281111),    BQC(0.999999999677192),
    189     BQC(0.612073220102006),  BQC(0.130022141698044),   BQC(1.62541051415425),
    190     BQC(1.00000000080398),   BQC(0.547879702855959),   BQC(0.171165825133192),
    191     BQC(1.34554656923247),   BQC(0.9999999980169),     BQC(0.460373914508491),
    192     BQC(0.228677463376354),  BQC(1.05656568503116),    BQC(1.00000000569363),
    193     BQC(0.357891894038287),  BQC(0.298676843912185),   BQC(0.787967587877312),
    194     BQC(0.999999984415017),  BQC(0.248826893211877),   BQC(0.377441803512978),
    195     BQC(0.555480971120497),  BQC(1.00000003583307),    BQC(0.140614263345315),
    196     BQC(0.461979302213679),  BQC(0.364986207070964),   BQC(0.999999932084303),
    197     BQC(0.0392669446074516), BQC(0.55033451180825),    BQC(0.216827267631558),
    198     BQC(1.00000010534682),   BQC(-0.0506232228865103), BQC(0.641691581560946),
    199     BQC(0.108951672277119),  BQC(0.999999871167516),   BQC(-0.125584840183225),
    200     BQC(0.736367748771803),  BQC(0.0387988607229035),  BQC(1.00000011205574),
    201     BQC(-0.182814849097974), BQC(0.835802108714964),   BQC(0.0042866175809225),
    202     BQC(0.999999954830813),  BQC(-0.21965740617151),   BQC(0.942623047782363)};
    203 
    204 static const FIXP_DBL g45 =
    205     FL2FXCONST_DBL(0.00242743980909524) - (FIXP_DBL)0x8000;
    206 
    207 static const struct FILTER_PARAM param_set45 = {
    208     sos45, g45, 450, 12, 4 /* LF 2 */
    209 };
    210 
    211 /*
    212  Created by Octave 2.1.73, Mon Oct 13 17:31:32 2008 CEST
    213  Wc = 0,5, order 16, Stop Band -96dB damping.
    214  [b,a]=cheby2(16,96,0.5)
    215  [sos,g]=tf2sos(b,a)
    216  bandwidth = 0.41
    217  */
    218 
    219 static const FIXP_SGL sos41[] = {
    220     BQC(1.96193625292),      BQC(0.999999999999964),   BQC(0.169266178786789),
    221     BQC(0.0128823300475907), BQC(1.68913437662092),    BQC(1.00000000000053),
    222     BQC(0.124751503206552),  BQC(0.0537472273950989),  BQC(1.27274692366017),
    223     BQC(0.999999999995674),  BQC(0.0433108625178357),  BQC(0.131015753236317),
    224     BQC(0.85214175088395),   BQC(1.00000000001813),    BQC(-0.0625658152550408),
    225     BQC(0.237763778993806),  BQC(0.503841579939009),   BQC(0.999999999953223),
    226     BQC(-0.179176128722865), BQC(0.367475236424474),   BQC(0.249990711986162),
    227     BQC(1.00000000007952),   BQC(-0.294425165824676),  BQC(0.516594857170212),
    228     BQC(0.087971668680286),  BQC(0.999999999915528),   BQC(-0.398956566777928),
    229     BQC(0.686417767801123),  BQC(0.00965373325350294), BQC(1.00000000003744),
    230     BQC(-0.48579173764817),  BQC(0.884931534239068)};
    231 
    232 static const FIXP_DBL g41 = FL2FXCONST_DBL(0.00155956951169248);
    233 
    234 static const struct FILTER_PARAM param_set41 = {
    235     sos41, g41, 410, 8, 5 /* LF 3 */
    236 };
    237 
    238 /*
    239  # Created by Octave 2.1.73, Mon Oct 13 17:55:33 2008 CEST
    240  Wc = 0,5, order 12, Stop Band -96dB damping.
    241  [b,a]=cheby2(12,96,0.5);
    242  [sos,g]=tf2sos(b,a)
    243 */
    244 static const FIXP_SGL sos35[] = {
    245     BQC(1.93299325235762),   BQC(0.999999999999985),  BQC(-0.140733187246596),
    246     BQC(0.0124139497836062), BQC(1.4890416764109),    BQC(1.00000000000011),
    247     BQC(-0.198215402588504), BQC(0.0746730616584138), BQC(0.918450161309795),
    248     BQC(0.999999999999619),  BQC(-0.30133912791941),  BQC(0.192276468839529),
    249     BQC(0.454877024246818),  BQC(1.00000000000086),   BQC(-0.432337328809815),
    250     BQC(0.356852933642815),  BQC(0.158017147118507),  BQC(0.999999999998876),
    251     BQC(-0.574817494249777), BQC(0.566380436970833),  BQC(0.0171834649478749),
    252     BQC(1.00000000000055),   BQC(-0.718581178041165), BQC(0.83367484487889)};
    253 
    254 static const FIXP_DBL g35 = FL2FXCONST_DBL(0.00162580994125131);
    255 
    256 static const struct FILTER_PARAM param_set35 = {sos35, g35, 350, 6, 4};
    257 
    258 /*
    259  # Created by Octave 2.1.73, Mon Oct 13 18:15:38 2008 CEST
    260  Wc = 0,5, order 8, Stop Band -96dB damping.
    261  [b,a]=cheby2(8,96,0.5);
    262  [sos,g]=tf2sos(b,a)
    263 */
    264 static const FIXP_SGL sos25[] = {
    265     BQC(1.85334094301225),   BQC(1.0),
    266     BQC(-0.702127214212663), BQC(0.132452403998767),
    267     BQC(1.056565682167),     BQC(0.999999999999997),
    268     BQC(-0.789503667880785), BQC(0.236328693569128),
    269     BQC(0.364986307455489),  BQC(0.999999999999996),
    270     BQC(-0.955191189843375), BQC(0.442966457936379),
    271     BQC(0.0387985751642125), BQC(1.0),
    272     BQC(-1.19817786088084),  BQC(0.770493895456328)};
    273 
    274 static const FIXP_DBL g25 = FL2FXCONST_DBL(0.000945182835294559);
    275 
    276 static const struct FILTER_PARAM param_set25 = {sos25, g25, 250, 4, 5};
    277 
    278 /* Must be sorted in descending order */
    279 static const struct FILTER_PARAM *const filter_paramSet[] = {
    280     &param_set48, &param_set45, &param_set41, &param_set35, &param_set25};
    281 
    282 /**************************************************************************/
    283 /*                         Resampler Functions                            */
    284 /**************************************************************************/
    285 
    286 /*!
    287   \brief   Reset downsampler instance and clear delay lines
    288 
    289   \return  success of operation
    290 */
    291 
    292 INT FDKaacEnc_InitDownsampler(
    293     DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
    294     int Wc,                   /*!< normalized cutoff freq * 1000*  */
    295     int ratio)                /*!< downsampler ratio */
    296 
    297 {
    298   UINT i;
    299   const struct FILTER_PARAM *currentSet = NULL;
    300 
    301   FDKmemclear(DownSampler->downFilter.states,
    302               sizeof(DownSampler->downFilter.states));
    303   DownSampler->downFilter.ptr = 0;
    304 
    305   /*
    306     find applicable parameter set
    307   */
    308   currentSet = filter_paramSet[0];
    309   for (i = 1; i < sizeof(filter_paramSet) / sizeof(struct FILTER_PARAM *);
    310        i++) {
    311     if (filter_paramSet[i]->Wc <= Wc) {
    312       break;
    313     }
    314     currentSet = filter_paramSet[i];
    315   }
    316 
    317   DownSampler->downFilter.coeffa = currentSet->coeffa;
    318 
    319   DownSampler->downFilter.gain = currentSet->g;
    320   FDK_ASSERT(currentSet->noCoeffs <= MAXNR_SECTIONS * 2);
    321 
    322   DownSampler->downFilter.noCoeffs = currentSet->noCoeffs;
    323   DownSampler->delay = currentSet->delay;
    324   DownSampler->downFilter.Wc = currentSet->Wc;
    325 
    326   DownSampler->ratio = ratio;
    327   DownSampler->pending = ratio - 1;
    328   return (1);
    329 }
    330 
    331 /*!
    332   \brief   faster simple folding operation
    333            Filter:
    334            H(z) = A(z)/B(z)
    335            with
    336            A(z) = a[0]*z^0 + a[1]*z^1 + a[2]*z^2 ... a[n]*z^n
    337 
    338   \return  filtered value
    339 */
    340 
    341 static inline INT_PCM AdvanceFilter(
    342     LP_FILTER *downFilter, /*!< pointer to iir filter instance */
    343     INT_PCM *pInput,       /*!< input of filter                */
    344     int downRatio) {
    345   INT_PCM output;
    346   int i, n;
    347 
    348 #define BIQUAD_SCALE 12
    349 
    350   FIXP_DBL y = FL2FXCONST_DBL(0.0f);
    351   FIXP_DBL input;
    352 
    353   for (n = 0; n < downRatio; n++) {
    354     FIXP_BQS(*states)[2] = downFilter->states;
    355     const FIXP_SGL *coeff = downFilter->coeffa;
    356     int s1, s2;
    357 
    358     s1 = downFilter->ptr;
    359     s2 = s1 ^ 1;
    360 
    361 #if (SAMPLE_BITS == 16)
    362     input = ((FIXP_DBL)pInput[n]) << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE);
    363 #elif (SAMPLE_BITS == 32)
    364     input = pInput[n] >> BIQUAD_SCALE;
    365 #else
    366 #error NOT IMPLEMENTED
    367 #endif
    368 
    369     FIXP_BQS state1, state2, state1b, state2b;
    370 
    371     state1 = states[0][s1];
    372     state2 = states[0][s2];
    373 
    374     /* Loop over sections */
    375     for (i = 0; i < downFilter->noCoeffs; i++) {
    376       FIXP_DBL state0;
    377 
    378       /* Load merged states (from next section) */
    379       state1b = states[i + 1][s1];
    380       state2b = states[i + 1][s2];
    381 
    382       state0 = input + fMult(state1, coeff[B1]) + fMult(state2, coeff[B2]);
    383       y = state0 - fMult(state1b, coeff[A1]) - fMult(state2b, coeff[A2]);
    384 
    385       /* Store new feed forward merge state */
    386       states[i + 1][s2] = y << 1;
    387       /* Store new feed backward state */
    388       states[i][s2] = input << 1;
    389 
    390       /* Feedback output to next section. */
    391       input = y;
    392 
    393       /* Transfer merged states */
    394       state1 = state1b;
    395       state2 = state2b;
    396 
    397       /* Step to next coef set */
    398       coeff += BIQUAD_COEFSTEP;
    399     }
    400     downFilter->ptr ^= 1;
    401   }
    402   /* Apply global gain */
    403   y = fMult(y, downFilter->gain);
    404 
    405   /* Apply final gain/scaling to output */
    406 #if (SAMPLE_BITS == 16)
    407   output = (INT_PCM)SATURATE_RIGHT_SHIFT(
    408       y + (FIXP_DBL)(1 << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE - 1)),
    409       DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE, SAMPLE_BITS);
    410   // output = (INT_PCM) SATURATE_RIGHT_SHIFT(y,
    411   // DFRACT_BITS-SAMPLE_BITS-BIQUAD_SCALE, SAMPLE_BITS);
    412 #else
    413   output = SATURATE_LEFT_SHIFT(y, BIQUAD_SCALE, SAMPLE_BITS);
    414 #endif
    415 
    416   return output;
    417 }
    418 
    419 /*!
    420   \brief   FDKaacEnc_Downsample numInSamples of type INT_PCM
    421            Returns number of output samples in numOutSamples
    422 
    423   \return  success of operation
    424 */
    425 
    426 INT FDKaacEnc_Downsample(
    427     DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
    428     INT_PCM *inSamples,       /*!< pointer to input samples */
    429     INT numInSamples,         /*!< number  of input samples  */
    430     INT_PCM *outSamples,      /*!< pointer to output samples */
    431     INT *numOutSamples        /*!< pointer tp number of output samples */
    432 ) {
    433   INT i;
    434   *numOutSamples = 0;
    435 
    436   for (i = 0; i < numInSamples; i += DownSampler->ratio) {
    437     *outSamples = AdvanceFilter(&(DownSampler->downFilter), &inSamples[i],
    438                                 DownSampler->ratio);
    439     outSamples++;
    440   }
    441   *numOutSamples = numInSamples / DownSampler->ratio;
    442 
    443   return 0;
    444 }
    445