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 /**************************** PCM utility library ****************************** 96 97 Author(s): Matthias Neusinger 98 99 Description: Hard limiter for clipping prevention 100 101 *******************************************************************************/ 102 103 #include "limiter.h" 104 #include "FDK_core.h" 105 106 /* library version */ 107 #include "version.h" 108 /* library title */ 109 #define TDLIMIT_LIB_TITLE "TD Limiter Lib" 110 111 /* create limiter */ 112 TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs, 113 FIXP_DBL threshold, unsigned int maxChannels, 114 UINT maxSampleRate) { 115 TDLimiterPtr limiter = NULL; 116 unsigned int attack, release; 117 FIXP_DBL attackConst, releaseConst, exponent; 118 INT e_ans; 119 120 /* calc attack and release time in samples */ 121 attack = (unsigned int)(maxAttackMs * maxSampleRate / 1000); 122 release = (unsigned int)(releaseMs * maxSampleRate / 1000); 123 124 /* alloc limiter struct */ 125 limiter = (TDLimiterPtr)FDKcalloc(1, sizeof(struct TDLimiter)); 126 if (!limiter) return NULL; 127 128 /* alloc max and delay buffers */ 129 limiter->maxBuf = (FIXP_DBL*)FDKcalloc(attack + 1, sizeof(FIXP_DBL)); 130 limiter->delayBuf = 131 (FIXP_DBL*)FDKcalloc(attack * maxChannels, sizeof(FIXP_DBL)); 132 133 if (!limiter->maxBuf || !limiter->delayBuf) { 134 pcmLimiter_Destroy(limiter); 135 return NULL; 136 } 137 138 /* attackConst = pow(0.1, 1.0 / (attack + 1)) */ 139 exponent = invFixp(attack + 1); 140 attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans); 141 attackConst = scaleValue(attackConst, e_ans); 142 143 /* releaseConst = (float)pow(0.1, 1.0 / (release + 1)) */ 144 exponent = invFixp(release + 1); 145 releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans); 146 releaseConst = scaleValue(releaseConst, e_ans); 147 148 /* init parameters */ 149 limiter->attackMs = maxAttackMs; 150 limiter->maxAttackMs = maxAttackMs; 151 limiter->releaseMs = releaseMs; 152 limiter->attack = attack; 153 limiter->attackConst = attackConst; 154 limiter->releaseConst = releaseConst; 155 limiter->threshold = threshold >> TDL_GAIN_SCALING; 156 limiter->channels = maxChannels; 157 limiter->maxChannels = maxChannels; 158 limiter->sampleRate = maxSampleRate; 159 limiter->maxSampleRate = maxSampleRate; 160 161 pcmLimiter_Reset(limiter); 162 163 return limiter; 164 } 165 166 /* apply limiter */ 167 TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, 168 INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain, 169 const INT* RESTRICT gain_scale, 170 const UINT gain_size, const UINT gain_delay, 171 const UINT nSamples) { 172 unsigned int i, j; 173 FIXP_DBL tmp1; 174 FIXP_DBL tmp2; 175 FIXP_DBL tmp, old, gain, additionalGain = 0, additionalGainUnfiltered; 176 FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1)); 177 178 FDK_ASSERT(gain_size == 1); 179 FDK_ASSERT(gain_delay <= nSamples); 180 181 if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; 182 183 { 184 unsigned int channels = limiter->channels; 185 unsigned int attack = limiter->attack; 186 FIXP_DBL attackConst = limiter->attackConst; 187 FIXP_DBL releaseConst = limiter->releaseConst; 188 FIXP_DBL threshold = limiter->threshold; 189 190 FIXP_DBL max = limiter->max; 191 FIXP_DBL* maxBuf = limiter->maxBuf; 192 unsigned int maxBufIdx = limiter->maxBufIdx; 193 FIXP_DBL cor = limiter->cor; 194 FIXP_DBL* delayBuf = limiter->delayBuf; 195 unsigned int delayBufIdx = limiter->delayBufIdx; 196 197 FIXP_DBL smoothState0 = limiter->smoothState0; 198 FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState; 199 FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1; 200 201 if (!gain_delay) { 202 additionalGain = pGain[0]; 203 if (gain_scale[0] > 0) { 204 additionalGain <<= gain_scale[0]; 205 } else { 206 additionalGain >>= -gain_scale[0]; 207 } 208 } 209 210 for (i = 0; i < nSamples; i++) { 211 if (gain_delay) { 212 if (i < gain_delay) { 213 additionalGainUnfiltered = limiter->additionalGainPrev; 214 } else { 215 additionalGainUnfiltered = pGain[0]; 216 } 217 218 /* Smooth additionalGain */ 219 /* [b,a] = butter(1, 0.01) */ 220 static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0), 221 FL2FXCONST_SGL(0.015466 * 2.0)}; 222 static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL, 223 FL2FXCONST_SGL(-0.96907)}; 224 additionalGain = -fMult(additionalGainSmoothState, a[1]) + 225 fMultDiv2(additionalGainUnfiltered, b[0]) + 226 fMultDiv2(additionalGainSmoothState1, b[1]); 227 additionalGainSmoothState1 = additionalGainUnfiltered; 228 additionalGainSmoothState = additionalGain; 229 230 /* Apply the additional scaling that has no delay and no smoothing */ 231 if (gain_scale[0] > 0) { 232 additionalGain <<= gain_scale[0]; 233 } else { 234 additionalGain >>= -gain_scale[0]; 235 } 236 } 237 /* get maximum absolute sample value of all channels, including the 238 * additional gain. */ 239 tmp1 = (FIXP_DBL)0; 240 for (j = 0; j < channels; j++) { 241 tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]); 242 tmp2 = fAbs(tmp2); 243 tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1)))); 244 tmp1 = fMax(tmp1, tmp2); 245 } 246 tmp = fMult(tmp1, additionalGain); 247 248 /* set threshold as lower border to save calculations in running maximum 249 * algorithm */ 250 tmp = fMax(tmp, threshold); 251 252 /* running maximum */ 253 old = maxBuf[maxBufIdx]; 254 maxBuf[maxBufIdx] = tmp; 255 256 if (tmp >= max) { 257 /* new sample is greater than old maximum, so it is the new maximum */ 258 max = tmp; 259 } else if (old < max) { 260 /* maximum does not change, as the sample, which has left the window was 261 not the maximum */ 262 } else { 263 /* the old maximum has left the window, we have to search the complete 264 buffer for the new max */ 265 max = maxBuf[0]; 266 for (j = 1; j <= attack; j++) { 267 max = fMax(max, maxBuf[j]); 268 } 269 } 270 maxBufIdx++; 271 if (maxBufIdx >= attack + 1) maxBufIdx = 0; 272 273 /* calc gain */ 274 /* gain is downscaled by one, so that gain = 1.0 can be represented */ 275 if (max > threshold) { 276 gain = fDivNorm(threshold, max) >> 1; 277 } else { 278 gain = FL2FXCONST_DBL(1.0f / (1 << 1)); 279 } 280 281 /* gain smoothing, method: TDL_EXPONENTIAL */ 282 /* first order IIR filter with attack correction to avoid overshoots */ 283 284 /* correct the 'aiming' value of the exponential attack to avoid the 285 * remaining overshoot */ 286 if (gain < smoothState0) { 287 cor = fMin(cor, 288 fMultDiv2((gain - fMultDiv2(FL2FXCONST_SGL(0.1f * (1 << 1)), 289 smoothState0)), 290 FL2FXCONST_SGL(1.11111111f / (1 << 1))) 291 << 2); 292 } else { 293 cor = gain; 294 } 295 296 /* smoothing filter */ 297 if (cor < smoothState0) { 298 smoothState0 = 299 fMult(attackConst, (smoothState0 - cor)) + cor; /* attack */ 300 smoothState0 = fMax(smoothState0, gain); /* avoid overshooting target */ 301 } else { 302 /* sign inversion twice to round towards +infinity, 303 so that gain can converge to 1.0 again, 304 for bit-identical output when limiter is not active */ 305 smoothState0 = 306 -fMult(releaseConst, -(smoothState0 - cor)) + cor; /* release */ 307 } 308 309 gain = smoothState0; 310 311 FIXP_DBL* p_delayBuf = &delayBuf[delayBufIdx * channels + 0]; 312 if (gain < FL2FXCONST_DBL(1.0f / (1 << 1))) { 313 gain <<= 1; 314 /* lookahead delay, apply gain */ 315 for (j = 0; j < channels; j++) { 316 tmp = p_delayBuf[j]; 317 p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); 318 319 /* Apply gain to delayed signal */ 320 tmp = fMultDiv2(tmp, gain); 321 322 samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT( 323 tmp, TDL_GAIN_SCALING + 1, DFRACT_BITS)); 324 } 325 gain >>= 1; 326 } else { 327 /* lookahead delay, apply gain=1.0f */ 328 for (j = 0; j < channels; j++) { 329 tmp = p_delayBuf[j]; 330 p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); 331 samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT( 332 tmp, TDL_GAIN_SCALING, DFRACT_BITS)); 333 } 334 } 335 336 delayBufIdx++; 337 if (delayBufIdx >= attack) { 338 delayBufIdx = 0; 339 } 340 341 /* save minimum gain factor */ 342 if (gain < minGain) { 343 minGain = gain; 344 } 345 346 /* advance sample pointer by <channel> samples */ 347 samplesIn += channels; 348 samplesOut += channels; 349 } 350 351 limiter->max = max; 352 limiter->maxBufIdx = maxBufIdx; 353 limiter->cor = cor; 354 limiter->delayBufIdx = delayBufIdx; 355 356 limiter->smoothState0 = smoothState0; 357 limiter->additionalGainFilterState = additionalGainSmoothState; 358 limiter->additionalGainFilterState1 = additionalGainSmoothState1; 359 360 limiter->minGain = minGain; 361 362 limiter->additionalGainPrev = pGain[0]; 363 364 return TDLIMIT_OK; 365 } 366 } 367 368 /* set limiter threshold */ 369 TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter, 370 FIXP_DBL threshold) { 371 if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; 372 373 limiter->threshold = threshold >> TDL_GAIN_SCALING; 374 375 return TDLIMIT_OK; 376 } 377 378 /* reset limiter */ 379 TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter) { 380 if (limiter != NULL) { 381 limiter->maxBufIdx = 0; 382 limiter->delayBufIdx = 0; 383 limiter->max = (FIXP_DBL)0; 384 limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1)); 385 limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1)); 386 limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1)); 387 388 limiter->additionalGainPrev = 389 FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); 390 limiter->additionalGainFilterState = 391 FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); 392 limiter->additionalGainFilterState1 = 393 FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); 394 395 FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL)); 396 FDKmemset(limiter->delayBuf, 0, 397 limiter->attack * limiter->channels * sizeof(FIXP_DBL)); 398 } else { 399 return TDLIMIT_INVALID_HANDLE; 400 } 401 402 return TDLIMIT_OK; 403 } 404 405 /* destroy limiter */ 406 TDLIMITER_ERROR pcmLimiter_Destroy(TDLimiterPtr limiter) { 407 if (limiter != NULL) { 408 FDKfree(limiter->maxBuf); 409 FDKfree(limiter->delayBuf); 410 411 FDKfree(limiter); 412 } else { 413 return TDLIMIT_INVALID_HANDLE; 414 } 415 return TDLIMIT_OK; 416 } 417 418 /* get delay in samples */ 419 unsigned int pcmLimiter_GetDelay(TDLimiterPtr limiter) { 420 FDK_ASSERT(limiter != NULL); 421 return limiter->attack; 422 } 423 424 /* get maximum gain reduction of last processed block */ 425 INT pcmLimiter_GetMaxGainReduction(TDLimiterPtr limiter) { 426 /* maximum gain reduction in dB = -20 * log10(limiter->minGain) 427 = -20 * log2(limiter->minGain)/log2(10) = -6.0206*log2(limiter->minGain) */ 428 int e_ans; 429 FIXP_DBL loggain, maxGainReduction; 430 431 FDK_ASSERT(limiter != NULL); 432 433 loggain = fLog2(limiter->minGain, 1, &e_ans); 434 435 maxGainReduction = fMult(loggain, FL2FXCONST_DBL(-6.0206f / (1 << 3))); 436 437 return fixp_roundToInt(maxGainReduction, (e_ans + 3)); 438 } 439 440 /* set number of channels */ 441 TDLIMITER_ERROR pcmLimiter_SetNChannels(TDLimiterPtr limiter, 442 unsigned int nChannels) { 443 if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; 444 445 if (nChannels > limiter->maxChannels) return TDLIMIT_INVALID_PARAMETER; 446 447 limiter->channels = nChannels; 448 // pcmLimiter_Reset(limiter); 449 450 return TDLIMIT_OK; 451 } 452 453 /* set sampling rate */ 454 TDLIMITER_ERROR pcmLimiter_SetSampleRate(TDLimiterPtr limiter, 455 UINT sampleRate) { 456 unsigned int attack, release; 457 FIXP_DBL attackConst, releaseConst, exponent; 458 INT e_ans; 459 460 if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; 461 462 if (sampleRate > limiter->maxSampleRate) return TDLIMIT_INVALID_PARAMETER; 463 464 /* update attack and release time in samples */ 465 attack = (unsigned int)(limiter->attackMs * sampleRate / 1000); 466 release = (unsigned int)(limiter->releaseMs * sampleRate / 1000); 467 468 /* attackConst = pow(0.1, 1.0 / (attack + 1)) */ 469 exponent = invFixp(attack + 1); 470 attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans); 471 attackConst = scaleValue(attackConst, e_ans); 472 473 /* releaseConst = (float)pow(0.1, 1.0 / (release + 1)) */ 474 exponent = invFixp(release + 1); 475 releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans); 476 releaseConst = scaleValue(releaseConst, e_ans); 477 478 limiter->attack = attack; 479 limiter->attackConst = attackConst; 480 limiter->releaseConst = releaseConst; 481 limiter->sampleRate = sampleRate; 482 483 /* reset */ 484 // pcmLimiter_Reset(limiter); 485 486 return TDLIMIT_OK; 487 } 488 489 /* set attack time */ 490 TDLIMITER_ERROR pcmLimiter_SetAttack(TDLimiterPtr limiter, 491 unsigned int attackMs) { 492 unsigned int attack; 493 FIXP_DBL attackConst, exponent; 494 INT e_ans; 495 496 if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; 497 498 if (attackMs > limiter->maxAttackMs) return TDLIMIT_INVALID_PARAMETER; 499 500 /* calculate attack time in samples */ 501 attack = (unsigned int)(attackMs * limiter->sampleRate / 1000); 502 503 /* attackConst = pow(0.1, 1.0 / (attack + 1)) */ 504 exponent = invFixp(attack + 1); 505 attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans); 506 attackConst = scaleValue(attackConst, e_ans); 507 508 limiter->attack = attack; 509 limiter->attackConst = attackConst; 510 limiter->attackMs = attackMs; 511 512 return TDLIMIT_OK; 513 } 514 515 /* set release time */ 516 TDLIMITER_ERROR pcmLimiter_SetRelease(TDLimiterPtr limiter, 517 unsigned int releaseMs) { 518 unsigned int release; 519 FIXP_DBL releaseConst, exponent; 520 INT e_ans; 521 522 if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; 523 524 /* calculate release time in samples */ 525 release = (unsigned int)(releaseMs * limiter->sampleRate / 1000); 526 527 /* releaseConst = (float)pow(0.1, 1.0 / (release + 1)) */ 528 exponent = invFixp(release + 1); 529 releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans); 530 releaseConst = scaleValue(releaseConst, e_ans); 531 532 limiter->releaseConst = releaseConst; 533 limiter->releaseMs = releaseMs; 534 535 return TDLIMIT_OK; 536 } 537 538 /* Get library info for this module. */ 539 TDLIMITER_ERROR pcmLimiter_GetLibInfo(LIB_INFO* info) { 540 int i; 541 542 if (info == NULL) { 543 return TDLIMIT_INVALID_PARAMETER; 544 } 545 546 /* Search for next free tab */ 547 for (i = 0; i < FDK_MODULE_LAST; i++) { 548 if (info[i].module_id == FDK_NONE) break; 549 } 550 if (i == FDK_MODULE_LAST) { 551 return TDLIMIT_UNKNOWN; 552 } 553 554 /* Add the library info */ 555 info[i].module_id = FDK_TDLIMIT; 556 info[i].version = 557 LIB_VERSION(PCMUTIL_LIB_VL0, PCMUTIL_LIB_VL1, PCMUTIL_LIB_VL2); 558 LIB_VERSION_STRING(info + i); 559 info[i].build_date = PCMUTIL_LIB_BUILD_DATE; 560 info[i].build_time = PCMUTIL_LIB_BUILD_TIME; 561 info[i].title = TDLIMIT_LIB_TITLE; 562 563 /* Set flags */ 564 info[i].flags = CAPF_LIMITER; 565 566 /* Add lib info for FDK tools (if not yet done). */ 567 FDK_toolsGetLibInfo(info); 568 569 return TDLIMIT_OK; 570 } 571