• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software 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
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@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 */
createLimiter(unsigned int maxAttackMs,unsigned int releaseMs,INT_PCM threshold,unsigned int maxChannels,unsigned int maxSampleRate)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 */
resetLimiter(TDLimiterPtr 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 */
destroyLimiter(TDLimiterPtr 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 */
applyLimiter(TDLimiterPtr limiter,INT_PCM * samples,FIXP_DBL * pGain,const INT * gain_scale,const UINT gain_size,const UINT gain_delay,const UINT nSamples)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 */
getLimiterDelay(TDLimiterPtr limiter)386 unsigned int getLimiterDelay(TDLimiterPtr limiter)
387 {
388   FDK_ASSERT(limiter != NULL);
389   return limiter->attack;
390 }
391 
392 /* set number of channels */
setLimiterNChannels(TDLimiterPtr limiter,unsigned int nChannels)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 */
setLimiterSampleRate(TDLimiterPtr limiter,unsigned int sampleRate)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 */
setLimiterAttack(TDLimiterPtr limiter,unsigned int attackMs)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 */
setLimiterRelease(TDLimiterPtr limiter,unsigned int releaseMs)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 */
setLimiterThreshold(TDLimiterPtr limiter,INT_PCM 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