1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@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
94struct 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 */
114TDLimiterPtr 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 */
174TDLIMITER_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 */
201TDLIMITER_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 */
216TDLIMITER_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 */
386unsigned int getLimiterDelay(TDLimiterPtr limiter)
387{
388  FDK_ASSERT(limiter != NULL);
389  return limiter->attack;
390}
391
392/* set number of channels */
393TDLIMITER_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 */
406TDLIMITER_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 */
442TDLIMITER_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 */
468TDLIMITER_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 */
491TDLIMITER_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