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 /************************  FDK PCM postprocessor module  *********************
     85 
     86    Author(s):   Matthias Neusinger
     87    Description: Hard limiter for clipping prevention
     88 
     89 *******************************************************************************/
     90 
     91 #include "limiter.h"
     92 
     93 
     94 struct TDLimiter {
     95   unsigned int  attack;
     96   FIXP_DBL      attackConst, releaseConst;
     97   unsigned int  attackMs, releaseMs, maxAttackMs;
     98   FIXP_PCM      threshold;
     99   unsigned int  channels, maxChannels;
    100   unsigned int  sampleRate, maxSampleRate;
    101   FIXP_DBL      cor, max;
    102   FIXP_DBL*     maxBuf;
    103   FIXP_DBL*     delayBuf;
    104   unsigned int  maxBufIdx, delayBufIdx;
    105   FIXP_DBL      smoothState0;
    106   FIXP_DBL      minGain;
    107 
    108   FIXP_DBL      additionalGainPrev;
    109   FIXP_DBL      additionalGainFilterState;
    110   FIXP_DBL      additionalGainFilterState1;
    111 };
    112 
    113 /* create limiter */
    114 TDLimiterPtr createLimiter(
    115                            unsigned int  maxAttackMs,
    116                            unsigned int  releaseMs,
    117                            INT_PCM       threshold,
    118                            unsigned int  maxChannels,
    119                            unsigned int  maxSampleRate
    120                            )
    121 {
    122   TDLimiterPtr limiter = NULL;
    123   unsigned int attack, release;
    124   FIXP_DBL attackConst, releaseConst, exponent;
    125   INT e_ans;
    126 
    127   /* calc attack and release time in samples */
    128   attack = (unsigned int)(maxAttackMs * maxSampleRate / 1000);
    129   release = (unsigned int)(releaseMs * maxSampleRate / 1000);
    130 
    131   /* alloc limiter struct */
    132   limiter = (TDLimiterPtr)FDKcalloc(1, sizeof(struct TDLimiter));
    133   if (!limiter) return NULL;
    134 
    135   /* alloc max and delay buffers */
    136   limiter->maxBuf   = (FIXP_DBL*)FDKcalloc(attack + 1, sizeof(FIXP_DBL));
    137   limiter->delayBuf = (FIXP_DBL*)FDKcalloc(attack * maxChannels, sizeof(FIXP_DBL));
    138 
    139   if (!limiter->maxBuf || !limiter->delayBuf) {
    140     destroyLimiter(limiter);
    141     return NULL;
    142   }
    143 
    144   /* attackConst = pow(0.1, 1.0 / (attack + 1)) */
    145   exponent = invFixp(attack+1);
    146   attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
    147   attackConst = scaleValue(attackConst, e_ans);
    148 
    149   /* releaseConst  = (float)pow(0.1, 1.0 / (release + 1)) */
    150   exponent = invFixp(release + 1);
    151   releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
    152   releaseConst = scaleValue(releaseConst, e_ans);
    153 
    154   /* init parameters */
    155   limiter->attackMs      = maxAttackMs;
    156   limiter->maxAttackMs   = maxAttackMs;
    157   limiter->releaseMs     = releaseMs;
    158   limiter->attack        = attack;
    159   limiter->attackConst   = attackConst;
    160   limiter->releaseConst  = releaseConst;
    161   limiter->threshold     = (FIXP_PCM)threshold;
    162   limiter->channels      = maxChannels;
    163   limiter->maxChannels   = maxChannels;
    164   limiter->sampleRate    = maxSampleRate;
    165   limiter->maxSampleRate = maxSampleRate;
    166 
    167   resetLimiter(limiter);
    168 
    169   return limiter;
    170 }
    171 
    172 
    173 /* reset limiter */
    174 TDLIMITER_ERROR resetLimiter(TDLimiterPtr limiter)
    175 {
    176   if (limiter != NULL) {
    177 
    178     limiter->maxBufIdx = 0;
    179     limiter->delayBufIdx = 0;
    180     limiter->max = (FIXP_DBL)0;
    181     limiter->cor = FL2FXCONST_DBL(1.0f/(1<<1));
    182     limiter->smoothState0 = FL2FXCONST_DBL(1.0f/(1<<1));
    183     limiter->minGain = FL2FXCONST_DBL(1.0f/(1<<1));
    184 
    185     limiter->additionalGainPrev = FL2FXCONST_DBL(1.0f/(1<<TDL_GAIN_SCALING));
    186     limiter->additionalGainFilterState = FL2FXCONST_DBL(1.0f/(1<<TDL_GAIN_SCALING));
    187     limiter->additionalGainFilterState1 = FL2FXCONST_DBL(1.0f/(1<<TDL_GAIN_SCALING));
    188 
    189     FDKmemset(limiter->maxBuf,   0, (limiter->attack + 1) * sizeof(FIXP_DBL) );
    190     FDKmemset(limiter->delayBuf, 0, limiter->attack * limiter->channels * sizeof(FIXP_DBL) );
    191   }
    192   else {
    193     return TDLIMIT_INVALID_HANDLE;
    194   }
    195 
    196   return TDLIMIT_OK;
    197 }
    198 
    199 
    200 /* destroy limiter */
    201 TDLIMITER_ERROR destroyLimiter(TDLimiterPtr limiter)
    202 {
    203   if (limiter != NULL) {
    204     FDKfree(limiter->maxBuf);
    205     FDKfree(limiter->delayBuf);
    206 
    207     FDKfree(limiter);
    208   }
    209   else {
    210     return TDLIMIT_INVALID_HANDLE;
    211   }
    212   return TDLIMIT_OK;
    213 }
    214 
    215 /* apply limiter */
    216 TDLIMITER_ERROR applyLimiter(TDLimiterPtr limiter,
    217                  INT_PCM*    samples,
    218                  FIXP_DBL*    pGain,
    219                  const INT*   gain_scale,
    220                  const UINT   gain_size,
    221                  const UINT   gain_delay,
    222                  const UINT   nSamples)
    223 {
    224   unsigned int i, j;
    225   FIXP_PCM tmp1, tmp2;
    226   FIXP_DBL tmp, old, gain, additionalGain, additionalGainUnfiltered;
    227   FIXP_DBL minGain = FL2FXCONST_DBL(1.0f/(1<<1));
    228 
    229   FDK_ASSERT(gain_size == 1);
    230   FDK_ASSERT(gain_delay <= nSamples);
    231 
    232   if ( limiter == NULL ) return TDLIMIT_INVALID_HANDLE;
    233 
    234   {
    235     unsigned int channels       = limiter->channels;
    236     unsigned int attack         = limiter->attack;
    237     FIXP_DBL     attackConst    = limiter->attackConst;
    238     FIXP_DBL     releaseConst   = limiter->releaseConst;
    239     FIXP_DBL     threshold      = FX_PCM2FX_DBL(limiter->threshold)>>TDL_GAIN_SCALING;
    240 
    241     FIXP_DBL     max            = limiter->max;
    242     FIXP_DBL*    maxBuf         = limiter->maxBuf;
    243     unsigned int maxBufIdx      = limiter->maxBufIdx;
    244     FIXP_DBL     cor            = limiter->cor;
    245     FIXP_DBL*    delayBuf       = limiter->delayBuf;
    246     unsigned int delayBufIdx    = limiter->delayBufIdx;
    247 
    248     FIXP_DBL     smoothState0   = limiter->smoothState0;
    249     FIXP_DBL     additionalGainSmoothState = limiter->additionalGainFilterState;
    250     FIXP_DBL     additionalGainSmoothState1 = limiter->additionalGainFilterState1;
    251 
    252     for (i = 0; i < nSamples; i++) {
    253 
    254       if (i < gain_delay) {
    255         additionalGainUnfiltered = limiter->additionalGainPrev;
    256       } else {
    257         additionalGainUnfiltered = pGain[0];
    258       }
    259 
    260       /* Smooth additionalGain */
    261       /* [b,a] = butter(1, 0.01) */
    262       static const FIXP_SGL b[] = { FL2FXCONST_SGL(0.015466*2.0), FL2FXCONST_SGL( 0.015466*2.0) };
    263       static const FIXP_SGL a[] = { FL2FXCONST_SGL(1.000000), FL2FXCONST_SGL(-0.96907) };
    264       /* [b,a] = butter(1, 0.001) */
    265       //static const FIXP_SGL b[] = { FL2FXCONST_SGL(0.0015683*2.0), FL2FXCONST_SGL( 0.0015683*2.0) };
    266       //static const FIXP_SGL a[] = { FL2FXCONST_SGL(1.0000000), FL2FXCONST_SGL(-0.99686) };
    267       additionalGain = - fMult(additionalGainSmoothState, a[1]) + fMultDiv2( additionalGainUnfiltered, b[0]) + fMultDiv2(additionalGainSmoothState1, b[1]);
    268       additionalGainSmoothState1 = additionalGainUnfiltered;
    269       additionalGainSmoothState = additionalGain;
    270 
    271       /* Apply the additional scaling that has no delay and no smoothing */
    272       if (gain_scale[0] > 0) {
    273         additionalGain <<= gain_scale[0];
    274       } else {
    275         additionalGain >>= gain_scale[0];
    276       }
    277 
    278       /* get maximum absolute sample value of all channels, including the additional gain. */
    279       tmp1 = (FIXP_PCM)0;
    280       for (j = 0; j < channels; j++) {
    281           tmp2 = (FIXP_PCM)samples[i * channels + j];
    282           if (tmp2 == (FIXP_PCM)SAMPLE_MIN) /* protect fAbs from -1.0 value */
    283               tmp2 = (FIXP_PCM)(SAMPLE_MIN+1);
    284         tmp1 = fMax(tmp1, fAbs(tmp2));
    285       }
    286       tmp = SATURATE_LEFT_SHIFT(fMultDiv2(tmp1, additionalGain), 1, DFRACT_BITS);
    287 
    288       /* set threshold as lower border to save calculations in running maximum algorithm */
    289       tmp = fMax(tmp, threshold);
    290 
    291       /* running maximum */
    292       old = maxBuf[maxBufIdx];
    293       maxBuf[maxBufIdx] = tmp;
    294 
    295       if (tmp >= max) {
    296         /* new sample is greater than old maximum, so it is the new maximum */
    297         max = tmp;
    298       }
    299       else if (old < max) {
    300         /* maximum does not change, as the sample, which has left the window was
    301            not the maximum */
    302       }
    303       else {
    304         /* the old maximum has left the window, we have to search the complete
    305            buffer for the new max */
    306         max = maxBuf[0];
    307         for (j = 1; j <= attack; j++) {
    308           if (maxBuf[j] > max) max = maxBuf[j];
    309         }
    310       }
    311       maxBufIdx++;
    312       if (maxBufIdx >= attack+1) maxBufIdx = 0;
    313 
    314       /* calc gain */
    315       /* gain is downscaled by one, so that gain = 1.0 can be represented */
    316       if (max > threshold) {
    317         gain = fDivNorm(threshold, max)>>1;
    318       }
    319       else {
    320         gain = FL2FXCONST_DBL(1.0f/(1<<1));
    321       }
    322 
    323       /* gain smoothing, method: TDL_EXPONENTIAL */
    324       /* first order IIR filter with attack correction to avoid overshoots */
    325 
    326       /* correct the 'aiming' value of the exponential attack to avoid the remaining overshoot */
    327       if (gain < smoothState0) {
    328         cor = fMin(cor, fMultDiv2((gain - fMultDiv2(FL2FXCONST_SGL(0.1f*(1<<1)),smoothState0)), FL2FXCONST_SGL(1.11111111f/(1<<1)))<<2);
    329       }
    330       else {
    331         cor = gain;
    332       }
    333 
    334       /* smoothing filter */
    335       if (cor < smoothState0) {
    336         smoothState0 = fMult(attackConst,(smoothState0 - cor)) + cor;  /* attack */
    337         smoothState0 = fMax(smoothState0, gain); /* avoid overshooting target */
    338       }
    339       else {
    340         /* sign inversion twice to round towards +infinity,
    341            so that gain can converge to 1.0 again,
    342            for bit-identical output when limiter is not active */
    343         smoothState0 = -fMult(releaseConst,-(smoothState0 - cor)) + cor; /* release */
    344       }
    345 
    346       gain = smoothState0;
    347 
    348       /* lookahead delay, apply gain */
    349       for (j = 0; j < channels; j++) {
    350 
    351         tmp = delayBuf[delayBufIdx * channels + j];
    352         delayBuf[delayBufIdx * channels + j] = fMult((FIXP_PCM)samples[i * channels + j], additionalGain);
    353 
    354         /* Apply gain to delayed signal */
    355         if (gain < FL2FXCONST_DBL(1.0f/(1<<1)))
    356           tmp = fMult(tmp,gain<<1);
    357 
    358         samples[i * channels + j] = FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(tmp,TDL_GAIN_SCALING,DFRACT_BITS));
    359       }
    360       delayBufIdx++;
    361       if (delayBufIdx >= attack) delayBufIdx = 0;
    362 
    363       /* save minimum gain factor */
    364       if (gain < minGain) minGain = gain;
    365     }
    366 
    367 
    368     limiter->max = max;
    369     limiter->maxBufIdx = maxBufIdx;
    370     limiter->cor = cor;
    371     limiter->delayBufIdx = delayBufIdx;
    372 
    373     limiter->smoothState0 = smoothState0;
    374     limiter->additionalGainFilterState = additionalGainSmoothState;
    375     limiter->additionalGainFilterState1 = additionalGainSmoothState1;
    376 
    377     limiter->minGain = minGain;
    378 
    379     limiter->additionalGainPrev = pGain[0];
    380 
    381     return TDLIMIT_OK;
    382   }
    383 }
    384 
    385 /* get delay in samples */
    386 unsigned int getLimiterDelay(TDLimiterPtr limiter)
    387 {
    388   FDK_ASSERT(limiter != NULL);
    389   return limiter->attack;
    390 }
    391 
    392 /* set number of channels */
    393 TDLIMITER_ERROR setLimiterNChannels(TDLimiterPtr limiter, unsigned int nChannels)
    394 {
    395   if ( limiter == NULL ) return TDLIMIT_INVALID_HANDLE;
    396 
    397   if (nChannels > limiter->maxChannels) return TDLIMIT_INVALID_PARAMETER;
    398 
    399   limiter->channels = nChannels;
    400   //resetLimiter(limiter);
    401 
    402   return TDLIMIT_OK;
    403 }
    404 
    405 /* set sampling rate */
    406 TDLIMITER_ERROR setLimiterSampleRate(TDLimiterPtr limiter, unsigned int sampleRate)
    407 {
    408   unsigned int attack, release;
    409   FIXP_DBL attackConst, releaseConst, exponent;
    410   INT e_ans;
    411 
    412   if ( limiter == NULL ) return TDLIMIT_INVALID_HANDLE;
    413 
    414   if (sampleRate > limiter->maxSampleRate) return TDLIMIT_INVALID_PARAMETER;
    415 
    416   /* update attack and release time in samples */
    417   attack = (unsigned int)(limiter->attackMs * sampleRate / 1000);
    418   release = (unsigned int)(limiter->releaseMs * sampleRate / 1000);
    419 
    420   /* attackConst = pow(0.1, 1.0 / (attack + 1)) */
    421   exponent = invFixp(attack+1);
    422   attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
    423   attackConst = scaleValue(attackConst, e_ans);
    424 
    425   /* releaseConst  = (float)pow(0.1, 1.0 / (release + 1)) */
    426   exponent = invFixp(release + 1);
    427   releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
    428   releaseConst = scaleValue(releaseConst, e_ans);
    429 
    430   limiter->attack        = attack;
    431   limiter->attackConst   = attackConst;
    432   limiter->releaseConst  = releaseConst;
    433   limiter->sampleRate    = sampleRate;
    434 
    435   /* reset */
    436   //resetLimiter(limiter);
    437 
    438   return TDLIMIT_OK;
    439 }
    440 
    441 /* set attack time */
    442 TDLIMITER_ERROR setLimiterAttack(TDLimiterPtr limiter, unsigned int attackMs)
    443 {
    444   unsigned int attack;
    445   FIXP_DBL attackConst, exponent;
    446   INT e_ans;
    447 
    448   if ( limiter == NULL ) return TDLIMIT_INVALID_HANDLE;
    449 
    450   if (attackMs > limiter->maxAttackMs) return TDLIMIT_INVALID_PARAMETER;
    451 
    452   /* calculate attack time in samples */
    453   attack = (unsigned int)(attackMs * limiter->sampleRate / 1000);
    454 
    455   /* attackConst = pow(0.1, 1.0 / (attack + 1)) */
    456   exponent = invFixp(attack+1);
    457   attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
    458   attackConst = scaleValue(attackConst, e_ans);
    459 
    460   limiter->attack        = attack;
    461   limiter->attackConst   = attackConst;
    462   limiter->attackMs      = attackMs;
    463 
    464   return TDLIMIT_OK;
    465 }
    466 
    467 /* set release time */
    468 TDLIMITER_ERROR setLimiterRelease(TDLimiterPtr limiter, unsigned int releaseMs)
    469 {
    470   unsigned int release;
    471   FIXP_DBL releaseConst, exponent;
    472   INT e_ans;
    473 
    474   if ( limiter == NULL ) return TDLIMIT_INVALID_HANDLE;
    475 
    476   /* calculate  release time in samples */
    477   release = (unsigned int)(releaseMs * limiter->sampleRate / 1000);
    478 
    479   /* releaseConst  = (float)pow(0.1, 1.0 / (release + 1)) */
    480   exponent = invFixp(release + 1);
    481   releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
    482   releaseConst = scaleValue(releaseConst, e_ans);
    483 
    484   limiter->releaseConst  = releaseConst;
    485   limiter->releaseMs     = releaseMs;
    486 
    487   return TDLIMIT_OK;
    488 }
    489 
    490 /* set limiter threshold */
    491 TDLIMITER_ERROR setLimiterThreshold(TDLimiterPtr limiter, INT_PCM threshold)
    492 {
    493   if ( limiter == NULL ) return TDLIMIT_INVALID_HANDLE;
    494 
    495   limiter->threshold = (FIXP_PCM)threshold;
    496 
    497   return TDLIMIT_OK;
    498 }
    499