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/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** 85 86 Author(s): M. Neusinger 87 Description: Compressor for AAC Metadata Generator 88 89******************************************************************************/ 90 91 92#include "metadata_compressor.h" 93#include "channel_map.h" 94 95 96#define LOG2 0.69314718056f /* natural logarithm of 2 */ 97#define ILOG2 1.442695041f /* 1/LOG2 */ 98#define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2/2)) 99 100/*----------------- defines ----------------------*/ 101 102#define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */ 103#define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */ 104#define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */ 105 106#define METADATA_INT_BITS 10 107#define METADATA_LINT_BITS 20 108#define METADATA_INT_SCALE (INT64(1)<<(METADATA_INT_BITS)) 109#define METADATA_FRACT_BITS (DFRACT_BITS-1-METADATA_INT_BITS) 110#define METADATA_FRACT_SCALE (INT64(1)<<(METADATA_FRACT_BITS)) 111 112/** 113 * Enum for channel assignment. 114 */ 115enum { 116 L = 0, 117 R = 1, 118 C = 2, 119 LFE = 3, 120 LS = 4, 121 RS = 5, 122 S = 6, 123 LS2 = 7, 124 RS2 = 8 125}; 126 127/*--------------- structure definitions --------------------*/ 128 129/** 130 * Structure holds weighting filter filter states. 131 */ 132struct WEIGHTING_STATES { 133 FIXP_DBL x1; 134 FIXP_DBL x2; 135 FIXP_DBL y1; 136 FIXP_DBL y2; 137}; 138 139/** 140 * Dynamic Range Control compressor structure. 141 */ 142struct DRC_COMP { 143 144 FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */ 145 FIXP_DBL boostThr[2]; /*!< Boost threshold. */ 146 FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */ 147 FIXP_DBL cutThr[2]; /*!< Cut threshold. */ 148 FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */ 149 150 FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */ 151 FIXP_DBL earlyCutFac[2]; /*!< Precalculated factor for early cut compression. */ 152 FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */ 153 154 FIXP_DBL maxBoost[2]; /*!< Maximum boost. */ 155 FIXP_DBL maxCut[2]; /*!< Maximum cut. */ 156 FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */ 157 158 FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */ 159 FIXP_DBL fastDecay[2]; /*!< Fast release coefficient. */ 160 FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */ 161 FIXP_DBL slowDecay[2]; /*!< Slow release coefficient. */ 162 UINT holdOff[2]; /*!< Hold time in blocks. */ 163 164 FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */ 165 FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */ 166 167 DRC_PROFILE profile[2]; /*!< DRC profile. */ 168 INT blockLength; /*!< Block length in samples. */ 169 UINT sampleRate; /*!< Sample rate. */ 170 CHANNEL_MODE chanConfig; /*!< Channel configuration. */ 171 172 UCHAR useWeighting; /*!< Use weighting filter. */ 173 174 UINT channels; /*!< Number of channels. */ 175 UINT fullChannels; /*!< Number of full range channels. */ 176 INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE, Ls, Rs, S, Ls2, Rs2). */ 177 178 FIXP_DBL smoothLevel[2]; /*!< level smoothing states */ 179 FIXP_DBL smoothGain[2]; /*!< gain smoothing states */ 180 UINT holdCnt[2]; /*!< hold counter */ 181 182 FIXP_DBL limGain[2]; /*!< limiter gain */ 183 FIXP_DBL limDecay; /*!< limiter decay (linear) */ 184 FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/ 185 186 WEIGHTING_STATES filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */ 187 188}; 189 190/*---------------- constants -----------------------*/ 191 192/** 193 * Profile tables. 194 */ 195static const FIXP_DBL tabMaxBoostThr[] = { 196 (FIXP_DBL)(int)((unsigned)-43<<METADATA_FRACT_BITS), 197 (FIXP_DBL)(int)((unsigned)-53<<METADATA_FRACT_BITS), 198 (FIXP_DBL)(int)((unsigned)-55<<METADATA_FRACT_BITS), 199 (FIXP_DBL)(int)((unsigned)-65<<METADATA_FRACT_BITS), 200 (FIXP_DBL)(int)((unsigned)-50<<METADATA_FRACT_BITS), 201 (FIXP_DBL)(int)((unsigned)-40<<METADATA_FRACT_BITS) 202}; 203static const FIXP_DBL tabBoostThr[] = { 204 (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS), 205 (FIXP_DBL)(int)((unsigned)-41<<METADATA_FRACT_BITS), 206 (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS), 207 (FIXP_DBL)(int)((unsigned)-41<<METADATA_FRACT_BITS), 208 (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS), 209 (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS) 210}; 211static const FIXP_DBL tabEarlyCutThr[] = { 212 (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS), 213 (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS), 214 (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS), 215 (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS), 216 (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS), 217 (FIXP_DBL)(int)((unsigned)-20<<METADATA_FRACT_BITS) 218}; 219static const FIXP_DBL tabCutThr[] = { 220 (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS), 221 (FIXP_DBL)(int)((unsigned)-11<<METADATA_FRACT_BITS), 222 (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS), 223 (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS), 224 (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS), 225 (FIXP_DBL)(int)((unsigned)-10<<METADATA_FRACT_BITS) 226}; 227static const FIXP_DBL tabMaxCutThr[] = { 228 (FIXP_DBL)(4<<METADATA_FRACT_BITS), 229 (FIXP_DBL)(9<<METADATA_FRACT_BITS), 230 (FIXP_DBL)(4<<METADATA_FRACT_BITS), 231 (FIXP_DBL)(9<<METADATA_FRACT_BITS), 232 (FIXP_DBL)(4<<METADATA_FRACT_BITS), 233 (FIXP_DBL)(4<<METADATA_FRACT_BITS) 234}; 235static const FIXP_DBL tabBoostRatio[] = { 236 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 237 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 238 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 239 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 240 FL2FXCONST_DBL( ((1.f/5.f) - 1.f) ), 241 FL2FXCONST_DBL( ((1.f/5.f) - 1.f) ) 242}; 243static const FIXP_DBL tabEarlyCutRatio[] = { 244 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 245 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 246 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 247 FL2FXCONST_DBL( ((1.f/1.f) - 1.f) ), 248 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), 249 FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ) 250}; 251static const FIXP_DBL tabCutRatio[] = { 252 FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), 253 FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), 254 FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), 255 FL2FXCONST_DBL( ((1.f/ 2.f) - 1.f) ), 256 FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), 257 FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ) 258}; 259static const FIXP_DBL tabMaxBoost[] = { 260 (FIXP_DBL)( 6<<METADATA_FRACT_BITS), 261 (FIXP_DBL)( 6<<METADATA_FRACT_BITS), 262 (FIXP_DBL)(12<<METADATA_FRACT_BITS), 263 (FIXP_DBL)(12<<METADATA_FRACT_BITS), 264 (FIXP_DBL)(15<<METADATA_FRACT_BITS), 265 (FIXP_DBL)(15<<METADATA_FRACT_BITS) 266}; 267static const FIXP_DBL tabMaxCut[] = { 268 (FIXP_DBL)(24<<METADATA_FRACT_BITS), 269 (FIXP_DBL)(24<<METADATA_FRACT_BITS), 270 (FIXP_DBL)(24<<METADATA_FRACT_BITS), 271 (FIXP_DBL)(15<<METADATA_FRACT_BITS), 272 (FIXP_DBL)(24<<METADATA_FRACT_BITS), 273 (FIXP_DBL)(24<<METADATA_FRACT_BITS) 274}; 275static const FIXP_DBL tabFastAttack[] = { 276 FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), 277 FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), 278 FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), 279 FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), 280 FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), 281 FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) 282}; 283static const FIXP_DBL tabFastDecay[] = { 284 FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), 285 FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), 286 FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), 287 FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), 288 FL2FXCONST_DBL( (200.f/1000.f)/METADATA_INT_SCALE), 289 FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) 290}; 291static const FIXP_DBL tabSlowAttack[] = { 292 FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), 293 FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), 294 FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), 295 FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), 296 FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), 297 FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) 298}; 299static const FIXP_DBL tabSlowDecay[] = { 300 FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE), 301 FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE), 302 FL2FXCONST_DBL((10000.f/1000.f)/METADATA_INT_SCALE), 303 FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE), 304 FL2FXCONST_DBL( (1000.f/1000.f)/METADATA_INT_SCALE), 305 FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) 306}; 307 308static const INT tabHoldOff[] = { 10, 10, 10, 10, 10, 0 }; 309 310static const FIXP_DBL tabAttackThr[] = { 311 (FIXP_DBL)(15<<METADATA_FRACT_BITS), 312 (FIXP_DBL)(15<<METADATA_FRACT_BITS), 313 (FIXP_DBL)(15<<METADATA_FRACT_BITS), 314 (FIXP_DBL)(15<<METADATA_FRACT_BITS), 315 (FIXP_DBL)(10<<METADATA_FRACT_BITS), 316 (FIXP_DBL)(0<<METADATA_FRACT_BITS) 317}; 318static const FIXP_DBL tabDecayThr[] = { 319 (FIXP_DBL)(20<<METADATA_FRACT_BITS), 320 (FIXP_DBL)(20<<METADATA_FRACT_BITS), 321 (FIXP_DBL)(20<<METADATA_FRACT_BITS), 322 (FIXP_DBL)(20<<METADATA_FRACT_BITS), 323 (FIXP_DBL)(10<<METADATA_FRACT_BITS), 324 (FIXP_DBL)( 0<<METADATA_FRACT_BITS) 325}; 326 327/** 328 * Weighting filter coefficients (biquad bandpass). 329 */ 330static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */ 331static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f), a2 = FL2FXCONST_DBL(-0.02248836f); /* a0 = 1 */ 332 333 334/*------------- function definitions ----------------*/ 335 336/** 337 * \brief Calculate scaling factor for denoted processing block. 338 * 339 * \param blockLength Length of processing block. 340 * 341 * \return shiftFactor 342 */ 343static UINT getShiftFactor( 344 const UINT length 345 ) 346{ 347 UINT ldN; 348 for(ldN=1;(((UINT)1)<<ldN) < length;ldN++); 349 350 return ldN; 351} 352 353/** 354 * \brief Sum up fixpoint values with best possible accuracy. 355 * 356 * \param value1 First input value. 357 * \param q1 Scaling factor of first input value. 358 * \param pValue2 Pointer to second input value, will be modified on return. 359 * \param pQ2 Pointer to second scaling factor, will be modified on return. 360 * 361 * \return void 362 */ 363static void fixpAdd( 364 const FIXP_DBL value1, 365 const int q1, 366 FIXP_DBL *const pValue2, 367 int *const pQ2 368 ) 369{ 370 const int headroom1 = fNormz(fixp_abs(value1))-1; 371 const int headroom2 = fNormz(fixp_abs(*pValue2))-1; 372 int resultScale = fixMax(q1-headroom1, (*pQ2)-headroom2); 373 374 if ( (value1!=FL2FXCONST_DBL(0.f)) && (*pValue2!=FL2FXCONST_DBL(0.f)) ) { 375 resultScale++; 376 } 377 378 *pValue2 = scaleValue(value1, q1-resultScale) + scaleValue(*pValue2, (*pQ2)-resultScale); 379 *pQ2 = (*pValue2!=(FIXP_DBL)0) ? resultScale : DFRACT_BITS-1; 380} 381 382/** 383 * \brief Function for converting time constant to filter coefficient. 384 * 385 * \param t Time constant. 386 * \param sampleRate Sampling rate in Hz. 387 * \param blockLength Length of processing block in samples per channel. 388 * 389 * \return result = 1.0 - exp(-1.0/((t) * (f))) 390 */ 391static FIXP_DBL tc2Coeff( 392 const FIXP_DBL t, 393 const INT sampleRate, 394 const INT blockLength 395 ) 396{ 397 FIXP_DBL sampleRateFract; 398 FIXP_DBL blockLengthFract; 399 FIXP_DBL f, product; 400 FIXP_DBL exponent, result; 401 INT e_res; 402 403 /* f = sampleRate/blockLength */ 404 sampleRateFract = (FIXP_DBL)(sampleRate<<(DFRACT_BITS-1-METADATA_LINT_BITS)); 405 blockLengthFract = (FIXP_DBL)(blockLength<<(DFRACT_BITS-1-METADATA_LINT_BITS)); 406 f = fDivNorm(sampleRateFract, blockLengthFract, &e_res); 407 f = scaleValue(f, e_res-METADATA_INT_BITS); /* convert to METADATA_FRACT */ 408 409 /* product = t*f */ 410 product = fMultNorm(t, f, &e_res); 411 product = scaleValue(product, e_res+METADATA_INT_BITS); /* convert to METADATA_FRACT */ 412 413 /* exponent = (-1.0/((t) * (f))) */ 414 exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res); 415 exponent = scaleValue(exponent, e_res-METADATA_INT_BITS); /* convert to METADATA_FRACT */ 416 417 /* exponent * ld(e) */ 418 exponent = fMult(exponent,FIXP_ILOG2_DIV2)<<1; /* e^(x) = 2^(x*ld(e)) */ 419 420 /* exp(-1.0/((t) * (f))) */ 421 result = f2Pow(-exponent, DFRACT_BITS-1-METADATA_FRACT_BITS, &e_res); 422 423 /* result = 1.0 - exp(-1.0/((t) * (f))) */ 424 result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res); 425 426 return result; 427} 428 429INT FDK_DRC_Generator_Open( 430 HDRC_COMP *phDrcComp 431 ) 432{ 433 INT err = 0; 434 HDRC_COMP hDcComp = NULL; 435 436 if (phDrcComp == NULL) { 437 err = -1; 438 goto bail; 439 } 440 441 /* allocate memory */ 442 hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP)); 443 444 if (hDcComp == NULL) { 445 err = -1; 446 goto bail; 447 } 448 449 FDKmemclear(hDcComp, sizeof(DRC_COMP)); 450 451 /* Return drc compressor instance */ 452 *phDrcComp = hDcComp; 453 return err; 454bail: 455 FDK_DRC_Generator_Close(&hDcComp); 456 return err; 457} 458 459INT FDK_DRC_Generator_Close( 460 HDRC_COMP *phDrcComp 461 ) 462{ 463 if (phDrcComp == NULL) { 464 return -1; 465 } 466 if (*phDrcComp != NULL) { 467 FDKfree(*phDrcComp); 468 *phDrcComp = NULL; 469 } 470 return 0; 471} 472 473 474INT FDK_DRC_Generator_Initialize( 475 HDRC_COMP drcComp, 476 const DRC_PROFILE profileLine, 477 const DRC_PROFILE profileRF, 478 const INT blockLength, 479 const UINT sampleRate, 480 const CHANNEL_MODE channelMode, 481 const CHANNEL_ORDER channelOrder, 482 const UCHAR useWeighting 483 ) 484{ 485 int i; 486 CHANNEL_MAPPING channelMapping; 487 488 drcComp->limDecay = FL2FXCONST_DBL( ((0.006f / 256) * blockLength) / METADATA_INT_SCALE ); 489 490 /* Save parameters. */ 491 drcComp->blockLength = blockLength; 492 drcComp->sampleRate = sampleRate; 493 drcComp->chanConfig = channelMode; 494 drcComp->useWeighting = useWeighting; 495 496 if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF)!=0) { /* expects initialized blockLength and sampleRate */ 497 return (-1); 498 } 499 500 /* Set number of channels and channel offsets. */ 501 if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, &channelMapping)!=AAC_ENC_OK) { 502 return (-2); 503 } 504 505 for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1; 506 507 switch (channelMode) { 508 case MODE_1: /* mono */ 509 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; 510 break; 511 case MODE_2: /* stereo */ 512 drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0]; 513 drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1]; 514 break; 515 case MODE_1_2: /* 3ch */ 516 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; 517 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; 518 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; 519 break; 520 case MODE_1_2_1: /* 4ch */ 521 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; 522 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; 523 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; 524 drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0]; 525 break; 526 case MODE_1_2_2: /* 5ch */ 527 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; 528 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; 529 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; 530 drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; 531 drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; 532 break; 533 case MODE_1_2_2_1: /* 5.1 ch */ 534 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; 535 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; 536 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; 537 drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0]; 538 drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; 539 drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; 540 break; 541 case MODE_1_2_2_2_1: /* 7.1 ch */ 542 case MODE_7_1_FRONT_CENTER: 543 drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */ 544 drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */ 545 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ 546 drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ 547 drcComp->channelIdx[LS] = channelMapping.elInfo[3].ChannelIndex[0]; /* ls */ 548 drcComp->channelIdx[RS] = channelMapping.elInfo[3].ChannelIndex[1]; /* rs */ 549 drcComp->channelIdx[LS2] = channelMapping.elInfo[1].ChannelIndex[0]; /* lc */ 550 drcComp->channelIdx[RS2] = channelMapping.elInfo[1].ChannelIndex[1]; /* rc */ 551 break; 552 case MODE_7_1_REAR_SURROUND: 553 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ 554 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ 555 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ 556 drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ 557 drcComp->channelIdx[LS] = channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */ 558 drcComp->channelIdx[RS] = channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */ 559 drcComp->channelIdx[LS2] = channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ 560 drcComp->channelIdx[RS2] = channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ 561 break; 562 case MODE_1_1: 563 case MODE_1_1_1_1: 564 case MODE_1_1_1_1_1_1: 565 case MODE_1_1_1_1_1_1_1_1: 566 case MODE_1_1_1_1_1_1_1_1_1_1_1_1: 567 case MODE_2_2: 568 case MODE_2_2_2: 569 case MODE_2_2_2_2: 570 case MODE_2_2_2_2_2_2: 571 default: 572 return (-1); 573 } 574 575 drcComp->fullChannels = channelMapping.nChannelsEff; 576 drcComp->channels = channelMapping.nChannels; 577 578 /* Init states. */ 579 drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(int)((unsigned)-135<<METADATA_FRACT_BITS); 580 581 FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); 582 FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); 583 FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain)); 584 FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak)); 585 FDKmemclear(drcComp->filter, sizeof(drcComp->filter)); 586 587 return (0); 588} 589 590 591INT FDK_DRC_Generator_setDrcProfile( 592 HDRC_COMP drcComp, 593 const DRC_PROFILE profileLine, 594 const DRC_PROFILE profileRF 595 ) 596{ 597 int profileIdx, i; 598 599 drcComp->profile[0] = profileLine; 600 drcComp->profile[1] = profileRF; 601 602 for (i = 0; i < 2; i++) { 603 /* get profile index */ 604 switch (drcComp->profile[i]) { 605 case DRC_NONE: 606 case DRC_FILMSTANDARD: profileIdx = 0; break; 607 case DRC_FILMLIGHT: profileIdx = 1; break; 608 case DRC_MUSICSTANDARD: profileIdx = 2; break; 609 case DRC_MUSICLIGHT: profileIdx = 3; break; 610 case DRC_SPEECH: profileIdx = 4; break; 611 case DRC_DELAY_TEST: profileIdx = 5; break; 612 default: return (-1); 613 } 614 615 /* get parameters for selected profile */ 616 if (profileIdx >= 0) { 617 drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx]; 618 drcComp->boostThr[i] = tabBoostThr[profileIdx]; 619 drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx]; 620 drcComp->cutThr[i] = tabCutThr[profileIdx]; 621 drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx]; 622 623 drcComp->boostFac[i] = tabBoostRatio[profileIdx]; 624 drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx]; 625 drcComp->cutFac[i] = tabCutRatio[profileIdx]; 626 627 drcComp->maxBoost[i] = tabMaxBoost[profileIdx]; 628 drcComp->maxCut[i] = tabMaxCut[profileIdx]; 629 drcComp->maxEarlyCut[i] = - fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */ 630 631 drcComp->fastAttack[i] = tc2Coeff(tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); 632 drcComp->fastDecay[i] = tc2Coeff(tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); 633 drcComp->slowAttack[i] = tc2Coeff(tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); 634 drcComp->slowDecay[i] = tc2Coeff(tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); 635 drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength; 636 637 drcComp->attackThr[i] = tabAttackThr[profileIdx]; 638 drcComp->decayThr[i] = tabDecayThr[profileIdx]; 639 } 640 641 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); 642 } 643 return (0); 644} 645 646 647INT FDK_DRC_Generator_Calc( 648 HDRC_COMP drcComp, 649 const INT_PCM * const inSamples, 650 const INT dialnorm, 651 const INT drc_TargetRefLevel, 652 const INT comp_TargetRefLevel, 653 FIXP_DBL clev, 654 FIXP_DBL slev, 655 INT * const pDynrng, 656 INT * const pCompr 657 ) 658{ 659 int i, c; 660 FIXP_DBL peak[2]; 661 662 663 /************************************************************************** 664 * compressor 665 **************************************************************************/ 666 if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) { 667 /* Calc loudness level */ 668 FIXP_DBL level_b = FL2FXCONST_DBL(0.f); 669 int level_e = DFRACT_BITS-1; 670 671 /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */ 672 const int granuleLength = fixMin(32, drcComp->blockLength); 673 674 if (drcComp->useWeighting) { 675 FIXP_DBL x1, x2, y, y1, y2; 676 /* sum of filter coefficients about 2.5 -> squared value is 6.25 677 WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1. 678 */ 679 const int granuleShift = getShiftFactor(granuleLength)-1; 680 681 for (c = 0; c < (int)drcComp->channels; c++) { 682 const INT_PCM* pSamples = &inSamples[c]; 683 684 if (c == drcComp->channelIdx[LFE]) { 685 continue; /* skip LFE */ 686 } 687 688 /* get filter states */ 689 x1 = drcComp->filter[c].x1; 690 x2 = drcComp->filter[c].x2; 691 y1 = drcComp->filter[c].y1; 692 y2 = drcComp->filter[c].y2; 693 694 i = 0; 695 696 do { 697 698 int offset = i; 699 FIXP_DBL accu = FL2FXCONST_DBL(0.f); 700 701 for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { 702 /* apply weighting filter */ 703 FIXP_DBL x = FX_PCM2FX_DBL((FIXP_PCM)pSamples[i*drcComp->channels]) >> WEIGHTING_FILTER_SHIFT; 704 705 /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */ 706 y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2); 707 708 x2 = x1; 709 x1 = x; 710 y2 = y1; 711 y1 = y; 712 713 accu += fPow2Div2(y)>>(granuleShift-1); /* partial energy */ 714 } /* i */ 715 716 fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */ 717 718 } while ( i < drcComp->blockLength ); 719 720 721 /* save filter states */ 722 drcComp->filter[c].x1 = x1; 723 drcComp->filter[c].x2 = x2; 724 drcComp->filter[c].y1 = y1; 725 drcComp->filter[c].y2 = y2; 726 } /* c */ 727 } /* weighting */ 728 else { 729 const int granuleShift = getShiftFactor(granuleLength); 730 731 for (c = 0; c < (int)drcComp->channels; c++) { 732 const INT_PCM* pSamples = &inSamples[c]; 733 734 if ((int)c == drcComp->channelIdx[LFE]) { 735 continue; /* skip LFE */ 736 } 737 738 i = 0; 739 740 do { 741 int offset = i; 742 FIXP_DBL accu = FL2FXCONST_DBL(0.f); 743 744 for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { 745 /* partial energy */ 746 accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1); 747 } /* i */ 748 749 fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */ 750 751 } while ( i < drcComp->blockLength ); 752 } 753 } /* weighting */ 754 755 /* 756 * Convert to dBFS, apply dialnorm 757 */ 758 /* level scaling */ 759 760 /* descaled level in ld64 representation */ 761 FIXP_DBL ldLevel = CalcLdData(level_b) + (FIXP_DBL)((level_e-12)<<(DFRACT_BITS-1-LD_DATA_SHIFT)) - CalcLdData((FIXP_DBL)(drcComp->blockLength<<(DFRACT_BITS-1-12))); 762 763 /* if (level < 1e-10) level = 1e-10f; */ 764 ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f)); 765 766 /* level = 10 * log(level)/log(10) + 3; 767 * = 10*log(2)/log(10) * ld(level) + 3; 768 * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3 769 * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3) 770 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 771 * 772 * additional scaling with METADATA_FRACT_BITS: 773 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS) 774 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) 775 * = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 ) 776 * */ 777 FIXP_DBL level = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) + (FIXP_DBL)(FL2FXCONST_DBL(0.3f)>>LD_DATA_SHIFT) ); 778 779 /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */ 780 level -= ((FIXP_DBL)(dialnorm<<(METADATA_FRACT_BITS-16)) + (FIXP_DBL)(31<<METADATA_FRACT_BITS)); 781 782 for (i = 0; i < 2; i++) { 783 if (drcComp->profile[i] == DRC_NONE) { 784 /* no compression */ 785 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); 786 } 787 else { 788 FIXP_DBL gain, alpha, lvl2smthlvl; 789 790 /* calc static gain */ 791 if (level <= drcComp->maxBoostThr[i]) { 792 /* max boost */ 793 gain = drcComp->maxBoost[i]; 794 } 795 else if (level < drcComp->boostThr[i]) { 796 /* boost range */ 797 gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]); 798 } 799 else if (level <= drcComp->earlyCutThr[i]) { 800 /* null band */ 801 gain = FL2FXCONST_DBL(0.f); 802 } 803 else if (level <= drcComp->cutThr[i]) { 804 /* early cut range */ 805 gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); 806 } 807 else if (level < drcComp->maxCutThr[i]) { 808 /* cut range */ 809 gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i]; 810 } 811 else { 812 /* max cut */ 813 gain = -drcComp->maxCut[i]; 814 } 815 816 /* choose time constant */ 817 lvl2smthlvl = level - drcComp->smoothLevel[i]; 818 if (gain < drcComp->smoothGain[i]) { 819 /* attack */ 820 if (lvl2smthlvl > drcComp->attackThr[i]) { 821 /* fast attack */ 822 alpha = drcComp->fastAttack[i]; 823 } 824 else { 825 /* slow attack */ 826 alpha = drcComp->slowAttack[i]; 827 } 828 } 829 else { 830 /* release */ 831 if (lvl2smthlvl < -drcComp->decayThr[i]) { 832 /* fast release */ 833 alpha = drcComp->fastDecay[i]; 834 } 835 else { 836 /* slow release */ 837 alpha = drcComp->slowDecay[i]; 838 } 839 } 840 841 /* smooth gain & level */ 842 if ((gain < drcComp->smoothGain[i]) || (drcComp->holdCnt[i] == 0)) { /* hold gain unless we have an attack or hold period is over */ 843 FIXP_DBL accu; 844 845 /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */ 846 accu = fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothLevel[i]); 847 accu += fMult(alpha,level); 848 drcComp->smoothLevel[i] = accu; 849 850 /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */ 851 accu = fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothGain[i]); 852 accu += fMult(alpha,gain); 853 drcComp->smoothGain[i] = accu; 854 } 855 856 /* hold counter */ 857 if (drcComp->holdCnt[i]) { 858 drcComp->holdCnt[i]--; 859 } 860 if (gain < drcComp->smoothGain[i]) { 861 drcComp->holdCnt[i] = drcComp->holdOff[i]; 862 } 863 } /* profile != DRC_NONE */ 864 } /* for i=1..2 */ 865 } else { 866 /* no compression */ 867 drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f); 868 drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f); 869 } 870 871 /************************************************************************** 872 * limiter 873 **************************************************************************/ 874 875 /* find peak level */ 876 peak[0] = peak[1] = FL2FXCONST_DBL(0.f); 877 for (i = 0; i < drcComp->blockLength; i++) { 878 FIXP_DBL tmp; 879 const INT_PCM* pSamples = &inSamples[i*drcComp->channels]; 880 INT_PCM maxSample = 0; 881 882 /* single channels */ 883 for (c = 0; c < (int)drcComp->channels; c++) { 884 maxSample = FDKmax(maxSample, fAbs(pSamples[c])); 885 } 886 peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT); 887 888 /* Lt/Rt downmix */ 889 if (drcComp->fullChannels > 2) { 890 /* Lt */ 891 tmp = FL2FXCONST_DBL(0.f); 892 893 if (drcComp->channelIdx[LS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 894 if (drcComp->channelIdx[LS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 895 if (drcComp->channelIdx[RS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 896 if (drcComp->channelIdx[RS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 897 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 898 if (drcComp->channelIdx[S] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ 899 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 900 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ 901 902 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 903 904 /* Rt */ 905 tmp = FL2FXCONST_DBL(0.f); 906 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 907 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 908 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 909 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 910 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 911 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ 912 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 913 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ 914 915 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 916 } 917 918 /* Lo/Ro downmix */ 919 if (drcComp->fullChannels > 2) { 920 /* Lo */ 921 tmp = FL2FXCONST_DBL(0.f); 922 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 923 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 924 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 925 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ 926 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 927 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ 928 929 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 930 931 /* Ro */ 932 tmp = FL2FXCONST_DBL(0.f); 933 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 934 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 935 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 936 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ 937 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 938 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ 939 940 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 941 } 942 943 peak[1] = fixMax(peak[0], peak[1]); 944 945 /* Mono Downmix - for comp_val only */ 946 if (drcComp->fullChannels > 1) { 947 tmp = FL2FXCONST_DBL(0.f); 948 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 949 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 950 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 951 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 952 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 953 /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */ 954 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ 955 if (drcComp->channelIdx[C] >= 0) tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C (2*clev) */ 956 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ 957 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ 958 959 peak[1] = fixMax(peak[1], fixp_abs(tmp)); 960 } 961 } 962 963 for (i=0; i<2; i++) { 964 FIXP_DBL tmp = drcComp->prevPeak[i]; 965 drcComp->prevPeak[i] = peak[i]; 966 peak[i] = fixMax(peak[i], tmp); 967 968 /* 969 * Convert to dBFS, apply dialnorm 970 */ 971 /* descaled peak in ld64 representation */ 972 FIXP_DBL ld_peak = CalcLdData(peak[i]) + (FIXP_DBL)((LONG)DOWNMIX_SHIFT<<(DFRACT_BITS-1-LD_DATA_SHIFT)); 973 974 /* if (peak < 1e-6) level = 1e-6f; */ 975 ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f)); 976 977 /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) 978 * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) 979 * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) 980 * 981 * additional scaling with METADATA_FRACT_BITS: 982 * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS) 983 * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i]) 984 * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i] 985 */ 986 peak[i] = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f), ld_peak)); 987 peak[i] += (FL2FX_DBL(0.5f)>>METADATA_INT_BITS); /* add a little bit headroom */ 988 peak[i] += drcComp->smoothGain[i]; 989 } 990 991 /* peak -= dialnorm + 31; */ /* this is Dolby style only */ 992 peak[0] -= (FIXP_DBL)((dialnorm-drc_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */ 993 994 /* peak += 11; */ /* this is Dolby style only */ /* RF mode output is 11dB higher */ 995 /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/ 996 peak[1] -= (FIXP_DBL)((dialnorm-comp_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */ 997 998 /* limiter gain */ 999 drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */ 1000 drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]); 1001 1002 drcComp->limGain[1] += 2*drcComp->limDecay; /* linear limiter release */ 1003 drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]); 1004 1005 /*************************************************************************/ 1006 1007 /* apply limiting, return DRC gains*/ 1008 { 1009 FIXP_DBL tmp; 1010 1011 tmp = drcComp->smoothGain[0]; 1012 if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) { 1013 tmp += drcComp->limGain[0]; 1014 } 1015 *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); 1016 1017 tmp = drcComp->smoothGain[1]; 1018 if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) { 1019 tmp += drcComp->limGain[1]; 1020 } 1021 *pCompr = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); 1022 } 1023 1024 return 0; 1025} 1026 1027 1028DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) 1029{ 1030 return drcComp->profile[0]; 1031} 1032 1033DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) 1034{ 1035 return drcComp->profile[1]; 1036} 1037 1038 1039