1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V. 6 All rights reserved. 7 8 1. INTRODUCTION 9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16 of the MPEG specifications. 17 18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20 individually for the purpose of encoding or decoding bit streams in products that are compliant with 21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23 software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27 applications information and documentation. 28 29 2. COPYRIGHT LICENSE 30 31 Redistribution and use in source and binary forms, with or without modification, are permitted without 32 payment of copyright license fees provided that you satisfy the following conditions: 33 34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35 your modifications thereto in source code form. 36 37 You must retain the complete text of this software license in the documentation and/or other materials 38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40 modifications thereto to recipients of copies in binary form. 41 42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43 prior written permission. 44 45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46 software or your modifications thereto. 47 48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49 and the date of any change. For modified versions of the FDK AAC Codec, the term 50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 52 53 3. NO PATENT LICENSE 54 55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57 respect to this software. 58 59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60 by appropriate patent licenses. 61 62 4. DISCLAIMER 63 64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69 or business interruption, however caused and on any theory of liability, whether in contract, strict 70 liability, or tort (including negligence), arising in any way out of the use of this software, even if 71 advised of the possibility of such damage. 72 73 5. CONTACT INFORMATION 74 75 Fraunhofer Institute for Integrated Circuits IIS 76 Attention: Audio and Multimedia Departments - FDK AAC LL 77 Am Wolfsmantel 33 78 91058 Erlangen, Germany 79 80 www.iis.fraunhofer.de/amm 81 amm-info (at) iis.fraunhofer.de 82 ----------------------------------------------------------------------------------------------------------- */ 83 84 /********************** 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 */ 115 enum { 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 */ 132 struct 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 */ 142 struct 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 */ 195 static const FIXP_DBL tabMaxBoostThr[] = { 196 (FIXP_DBL)(-43<<METADATA_FRACT_BITS), 197 (FIXP_DBL)(-53<<METADATA_FRACT_BITS), 198 (FIXP_DBL)(-55<<METADATA_FRACT_BITS), 199 (FIXP_DBL)(-65<<METADATA_FRACT_BITS), 200 (FIXP_DBL)(-50<<METADATA_FRACT_BITS), 201 (FIXP_DBL)(-40<<METADATA_FRACT_BITS) 202 }; 203 static const FIXP_DBL tabBoostThr[] = { 204 (FIXP_DBL)(-31<<METADATA_FRACT_BITS), 205 (FIXP_DBL)(-41<<METADATA_FRACT_BITS), 206 (FIXP_DBL)(-31<<METADATA_FRACT_BITS), 207 (FIXP_DBL)(-41<<METADATA_FRACT_BITS), 208 (FIXP_DBL)(-31<<METADATA_FRACT_BITS), 209 (FIXP_DBL)(-31<<METADATA_FRACT_BITS) 210 }; 211 static const FIXP_DBL tabEarlyCutThr[] = { 212 (FIXP_DBL)(-26<<METADATA_FRACT_BITS), 213 (FIXP_DBL)(-21<<METADATA_FRACT_BITS), 214 (FIXP_DBL)(-26<<METADATA_FRACT_BITS), 215 (FIXP_DBL)(-21<<METADATA_FRACT_BITS), 216 (FIXP_DBL)(-26<<METADATA_FRACT_BITS), 217 (FIXP_DBL)(-20<<METADATA_FRACT_BITS) 218 }; 219 static const FIXP_DBL tabCutThr[] = { 220 (FIXP_DBL)(-16<<METADATA_FRACT_BITS), 221 (FIXP_DBL)(-11<<METADATA_FRACT_BITS), 222 (FIXP_DBL)(-16<<METADATA_FRACT_BITS), 223 (FIXP_DBL)(-21<<METADATA_FRACT_BITS), 224 (FIXP_DBL)(-16<<METADATA_FRACT_BITS), 225 (FIXP_DBL)(-10<<METADATA_FRACT_BITS) 226 }; 227 static 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 }; 235 static 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 }; 243 static 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 }; 251 static 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 }; 259 static 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 }; 267 static 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 }; 275 static 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 }; 283 static 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 }; 291 static 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 }; 299 static 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 308 static const INT tabHoldOff[] = { 10, 10, 10, 10, 10, 0 }; 309 310 static 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 }; 318 static 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 */ 330 static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */ 331 static 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 */ 343 static 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 */ 363 static 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 */ 391 static 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 = FL2FXCONST_DBL(1.0f) - scaleValue(result, e_res); 425 426 return result; 427 } 428 429 INT 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; 454 bail: 455 FDK_DRC_Generator_Close(&hDcComp); 456 return err; 457 } 458 459 INT 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 474 INT 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 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; 543 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; 544 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; 545 drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; 546 drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; 547 drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; 548 drcComp->channelIdx[LS2] = channelMapping.elInfo[3].ChannelIndex[0]; 549 drcComp->channelIdx[RS2] = channelMapping.elInfo[3].ChannelIndex[1]; 550 break; 551 case MODE_1_1: 552 case MODE_1_1_1_1: 553 case MODE_1_1_1_1_1_1: 554 case MODE_1_1_1_1_1_1_1_1: 555 case MODE_1_1_1_1_1_1_1_1_1_1_1_1: 556 case MODE_2_2: 557 case MODE_2_2_2: 558 case MODE_2_2_2_2: 559 case MODE_2_2_2_2_2_2: 560 default: 561 return (-1); 562 } 563 564 drcComp->fullChannels = channelMapping.nChannelsEff; 565 drcComp->channels = channelMapping.nChannels; 566 567 /* Init states. */ 568 drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(-135<<METADATA_FRACT_BITS); 569 570 FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); 571 FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); 572 FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain)); 573 FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak)); 574 FDKmemclear(drcComp->filter, sizeof(drcComp->filter)); 575 576 return (0); 577 } 578 579 580 INT FDK_DRC_Generator_setDrcProfile( 581 HDRC_COMP drcComp, 582 const DRC_PROFILE profileLine, 583 const DRC_PROFILE profileRF 584 ) 585 { 586 int profileIdx, i; 587 588 drcComp->profile[0] = profileLine; 589 drcComp->profile[1] = profileRF; 590 591 for (i = 0; i < 2; i++) { 592 /* get profile index */ 593 switch (drcComp->profile[i]) { 594 case DRC_NONE: 595 case DRC_FILMSTANDARD: profileIdx = 0; break; 596 case DRC_FILMLIGHT: profileIdx = 1; break; 597 case DRC_MUSICSTANDARD: profileIdx = 2; break; 598 case DRC_MUSICLIGHT: profileIdx = 3; break; 599 case DRC_SPEECH: profileIdx = 4; break; 600 case DRC_DELAY_TEST: profileIdx = 5; break; 601 default: return (-1); 602 } 603 604 /* get parameters for selected profile */ 605 if (profileIdx >= 0) { 606 drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx]; 607 drcComp->boostThr[i] = tabBoostThr[profileIdx]; 608 drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx]; 609 drcComp->cutThr[i] = tabCutThr[profileIdx]; 610 drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx]; 611 612 drcComp->boostFac[i] = tabBoostRatio[profileIdx]; 613 drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx]; 614 drcComp->cutFac[i] = tabCutRatio[profileIdx]; 615 616 drcComp->maxBoost[i] = tabMaxBoost[profileIdx]; 617 drcComp->maxCut[i] = tabMaxCut[profileIdx]; 618 drcComp->maxEarlyCut[i] = - fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */ 619 620 drcComp->fastAttack[i] = tc2Coeff(tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); 621 drcComp->fastDecay[i] = tc2Coeff(tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); 622 drcComp->slowAttack[i] = tc2Coeff(tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); 623 drcComp->slowDecay[i] = tc2Coeff(tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); 624 drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength; 625 626 drcComp->attackThr[i] = tabAttackThr[profileIdx]; 627 drcComp->decayThr[i] = tabDecayThr[profileIdx]; 628 } 629 630 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); 631 } 632 return (0); 633 } 634 635 636 INT FDK_DRC_Generator_Calc( 637 HDRC_COMP drcComp, 638 const INT_PCM * const inSamples, 639 const INT dialnorm, 640 const INT drc_TargetRefLevel, 641 const INT comp_TargetRefLevel, 642 FIXP_DBL clev, 643 FIXP_DBL slev, 644 INT * const pDynrng, 645 INT * const pCompr 646 ) 647 { 648 int i, c; 649 FIXP_DBL peak[2]; 650 651 652 /************************************************************************** 653 * compressor 654 **************************************************************************/ 655 if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) { 656 /* Calc loudness level */ 657 FIXP_DBL level_b = FL2FXCONST_DBL(0.f); 658 int level_e = DFRACT_BITS-1; 659 660 /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */ 661 const int granuleLength = fixMin(32, drcComp->blockLength); 662 663 if (drcComp->useWeighting) { 664 FIXP_DBL x1, x2, y, y1, y2; 665 /* sum of filter coefficients about 2.5 -> squared value is 6.25 666 WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1. 667 */ 668 const int granuleShift = getShiftFactor(granuleLength)-1; 669 670 for (c = 0; c < (int)drcComp->channels; c++) { 671 const INT_PCM* pSamples = &inSamples[c]; 672 673 if (c == drcComp->channelIdx[LFE]) { 674 continue; /* skip LFE */ 675 } 676 677 /* get filter states */ 678 x1 = drcComp->filter[c].x1; 679 x2 = drcComp->filter[c].x2; 680 y1 = drcComp->filter[c].y1; 681 y2 = drcComp->filter[c].y2; 682 683 i = 0; 684 685 do { 686 687 int offset = i; 688 FIXP_DBL accu = FL2FXCONST_DBL(0.f); 689 690 for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { 691 /* apply weighting filter */ 692 FIXP_DBL x = FX_PCM2FX_DBL((FIXP_PCM)pSamples[i*drcComp->channels]) >> WEIGHTING_FILTER_SHIFT; 693 694 /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */ 695 y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2); 696 697 x2 = x1; 698 x1 = x; 699 y2 = y1; 700 y1 = y; 701 702 accu += fPow2Div2(y)>>(granuleShift-1); /* partial energy */ 703 } /* i */ 704 705 fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */ 706 707 } while ( i < drcComp->blockLength ); 708 709 710 /* save filter states */ 711 drcComp->filter[c].x1 = x1; 712 drcComp->filter[c].x2 = x2; 713 drcComp->filter[c].y1 = y1; 714 drcComp->filter[c].y2 = y2; 715 } /* c */ 716 } /* weighting */ 717 else { 718 const int granuleShift = getShiftFactor(granuleLength); 719 720 for (c = 0; c < (int)drcComp->channels; c++) { 721 const INT_PCM* pSamples = &inSamples[c]; 722 723 if ((int)c == drcComp->channelIdx[LFE]) { 724 continue; /* skip LFE */ 725 } 726 727 i = 0; 728 729 do { 730 int offset = i; 731 FIXP_DBL accu = FL2FXCONST_DBL(0.f); 732 733 for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { 734 /* partial energy */ 735 accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1); 736 } /* i */ 737 738 fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */ 739 740 } while ( i < drcComp->blockLength ); 741 } 742 } /* weighting */ 743 744 /* 745 * Convert to dBFS, apply dialnorm 746 */ 747 /* level scaling */ 748 749 /* descaled level in ld64 representation */ 750 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))); 751 752 /* if (level < 1e-10) level = 1e-10f; */ 753 ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f)); 754 755 /* level = 10 * log(level)/log(10) + 3; 756 * = 10*log(2)/log(10) * ld(level) + 3; 757 * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3 758 * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3) 759 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 760 * 761 * additional scaling with METADATA_FRACT_BITS: 762 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS) 763 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) 764 * = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 ) 765 * */ 766 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) ); 767 768 /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */ 769 level -= ((FIXP_DBL)(dialnorm<<(METADATA_FRACT_BITS-16)) + (FIXP_DBL)(31<<METADATA_FRACT_BITS)); 770 771 for (i = 0; i < 2; i++) { 772 if (drcComp->profile[i] == DRC_NONE) { 773 /* no compression */ 774 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); 775 } 776 else { 777 FIXP_DBL gain, alpha, lvl2smthlvl; 778 779 /* calc static gain */ 780 if (level <= drcComp->maxBoostThr[i]) { 781 /* max boost */ 782 gain = drcComp->maxBoost[i]; 783 } 784 else if (level < drcComp->boostThr[i]) { 785 /* boost range */ 786 gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]); 787 } 788 else if (level <= drcComp->earlyCutThr[i]) { 789 /* null band */ 790 gain = FL2FXCONST_DBL(0.f); 791 } 792 else if (level <= drcComp->cutThr[i]) { 793 /* early cut range */ 794 gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); 795 } 796 else if (level < drcComp->maxCutThr[i]) { 797 /* cut range */ 798 gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i]; 799 } 800 else { 801 /* max cut */ 802 gain = -drcComp->maxCut[i]; 803 } 804 805 /* choose time constant */ 806 lvl2smthlvl = level - drcComp->smoothLevel[i]; 807 if (gain < drcComp->smoothGain[i]) { 808 /* attack */ 809 if (lvl2smthlvl > drcComp->attackThr[i]) { 810 /* fast attack */ 811 alpha = drcComp->fastAttack[i]; 812 } 813 else { 814 /* slow attack */ 815 alpha = drcComp->slowAttack[i]; 816 } 817 } 818 else { 819 /* release */ 820 if (lvl2smthlvl < -drcComp->decayThr[i]) { 821 /* fast release */ 822 alpha = drcComp->fastDecay[i]; 823 } 824 else { 825 /* slow release */ 826 alpha = drcComp->slowDecay[i]; 827 } 828 } 829 830 /* smooth gain & level */ 831 if ((gain < drcComp->smoothGain[i]) || (drcComp->holdCnt[i] == 0)) { /* hold gain unless we have an attack or hold period is over */ 832 FIXP_DBL accu; 833 834 /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */ 835 accu = fMult((FL2FXCONST_DBL(1.f)-alpha), drcComp->smoothLevel[i]); 836 accu += fMult(alpha,level); 837 drcComp->smoothLevel[i] = accu; 838 839 /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */ 840 accu = fMult((FL2FXCONST_DBL(1.f)-alpha), drcComp->smoothGain[i]); 841 accu += fMult(alpha,gain); 842 drcComp->smoothGain[i] = accu; 843 } 844 845 /* hold counter */ 846 if (drcComp->holdCnt[i]) { 847 drcComp->holdCnt[i]--; 848 } 849 if (gain < drcComp->smoothGain[i]) { 850 drcComp->holdCnt[i] = drcComp->holdOff[i]; 851 } 852 } /* profile != DRC_NONE */ 853 } /* for i=1..2 */ 854 } else { 855 /* no compression */ 856 drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f); 857 drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f); 858 } 859 860 /************************************************************************** 861 * limiter 862 **************************************************************************/ 863 864 /* find peak level */ 865 peak[0] = peak[1] = FL2FXCONST_DBL(0.f); 866 for (i = 0; i < drcComp->blockLength; i++) { 867 FIXP_DBL tmp; 868 const INT_PCM* pSamples = &inSamples[i*drcComp->channels]; 869 INT_PCM maxSample = 0; 870 871 /* single channels */ 872 for (c = 0; c < (int)drcComp->channels; c++) { 873 maxSample = FDKmax(maxSample, fAbs(pSamples[c])); 874 } 875 peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT); 876 877 /* Lt/Rt downmix */ 878 if (drcComp->fullChannels > 2) { 879 /* Lt */ 880 tmp = FL2FXCONST_DBL(0.f); 881 882 if (drcComp->channelIdx[LS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 883 if (drcComp->channelIdx[LS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 884 if (drcComp->channelIdx[RS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 885 if (drcComp->channelIdx[RS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 886 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 887 if (drcComp->channelIdx[S] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ 888 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 889 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ 890 891 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 892 893 /* Rt */ 894 tmp = FL2FXCONST_DBL(0.f); 895 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 896 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 897 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 898 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 899 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 900 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ 901 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 902 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ 903 904 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 905 } 906 907 /* Lo/Ro downmix */ 908 if (drcComp->fullChannels > 2) { 909 /* Lo */ 910 tmp = FL2FXCONST_DBL(0.f); 911 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 912 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 913 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 914 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ 915 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 916 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ 917 918 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 919 920 /* Ro */ 921 tmp = FL2FXCONST_DBL(0.f); 922 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 923 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 924 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 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[R]])>>DOWNMIX_SHIFT); /* R */ 928 929 peak[0] = fixMax(peak[0], fixp_abs(tmp)); 930 } 931 932 peak[1] = fixMax(peak[0], peak[1]); 933 934 /* Mono Downmix - for comp_val only */ 935 if (drcComp->fullChannels > 1) { 936 tmp = FL2FXCONST_DBL(0.f); 937 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ 938 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ 939 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ 940 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ 941 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ 942 /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */ 943 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ 944 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ 945 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ 946 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ 947 948 peak[1] = fixMax(peak[1], fixp_abs(tmp)); 949 } 950 } 951 952 for (i=0; i<2; i++) { 953 FIXP_DBL tmp = drcComp->prevPeak[i]; 954 drcComp->prevPeak[i] = peak[i]; 955 peak[i] = fixMax(peak[i], tmp); 956 957 /* 958 * Convert to dBFS, apply dialnorm 959 */ 960 /* descaled peak in ld64 representation */ 961 FIXP_DBL ld_peak = CalcLdData(peak[i]) + (FIXP_DBL)((LONG)DOWNMIX_SHIFT<<(DFRACT_BITS-1-LD_DATA_SHIFT)); 962 963 /* if (peak < 1e-6) level = 1e-6f; */ 964 ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f)); 965 966 /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) 967 * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) 968 * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) 969 * 970 * additional scaling with METADATA_FRACT_BITS: 971 * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS) 972 * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i]) 973 * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i] 974 */ 975 peak[i] = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f), ld_peak)); 976 peak[i] += (FL2FX_DBL(0.2f)>>METADATA_INT_BITS); /* add a little bit headroom */ 977 peak[i] += drcComp->smoothGain[i]; 978 } 979 980 /* peak -= dialnorm + 31; */ /* this is Dolby style only */ 981 peak[0] -= (FIXP_DBL)((dialnorm-drc_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */ 982 983 /* peak += 11; */ /* this is Dolby style only */ /* RF mode output is 11dB higher */ 984 /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/ 985 peak[1] -= (FIXP_DBL)((dialnorm-comp_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */ 986 987 /* limiter gain */ 988 drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */ 989 drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]); 990 991 drcComp->limGain[1] += 2*drcComp->limDecay; /* linear limiter release */ 992 drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]); 993 994 /*************************************************************************/ 995 996 /* apply limiting, return DRC gains*/ 997 { 998 FIXP_DBL tmp; 999 1000 tmp = drcComp->smoothGain[0]; 1001 if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) { 1002 tmp += drcComp->limGain[0]; 1003 } 1004 *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); 1005 1006 tmp = drcComp->smoothGain[1]; 1007 if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) { 1008 tmp += drcComp->limGain[1]; 1009 } 1010 *pCompr = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); 1011 } 1012 1013 return 0; 1014 } 1015 1016 1017 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) 1018 { 1019 return drcComp->profile[0]; 1020 } 1021 1022 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) 1023 { 1024 return drcComp->profile[1]; 1025 } 1026 1027 1028