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 /************************* MPEG-D DRC decoder library ************************** 96 97 Author(s): 98 99 Description: 100 101 *******************************************************************************/ 102 103 #include "drcDec_types.h" 104 #include "drcDec_gainDecoder.h" 105 #include "drcGainDec_preprocess.h" 106 #include "drcGainDec_init.h" 107 #include "drcGainDec_process.h" 108 #include "drcDec_tools.h" 109 110 /*******************************************/ 111 /* static functions */ 112 /*******************************************/ 113 114 static int _fitsLocation(DRC_INSTRUCTIONS_UNI_DRC* pInst, 115 const GAIN_DEC_LOCATION drcLocation) { 116 int downmixId = pInst->drcApplyToDownmix ? pInst->downmixId[0] : 0; 117 switch (drcLocation) { 118 case GAIN_DEC_DRC1: 119 return (downmixId == 0); 120 case GAIN_DEC_DRC1_DRC2: 121 return ((downmixId == 0) || (downmixId == DOWNMIX_ID_ANY_DOWNMIX)); 122 case GAIN_DEC_DRC2: 123 return (downmixId == DOWNMIX_ID_ANY_DOWNMIX); 124 case GAIN_DEC_DRC3: 125 return ((downmixId != 0) && (downmixId != DOWNMIX_ID_ANY_DOWNMIX)); 126 case GAIN_DEC_DRC2_DRC3: 127 return (downmixId != 0); 128 } 129 return 0; 130 } 131 132 static void _setChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec, 133 const int numChannelGains, 134 const FIXP_DBL* channelGainDb) { 135 int i, channelGain_e; 136 FIXP_DBL channelGain; 137 FDK_ASSERT(numChannelGains <= 8); 138 for (i = 0; i < numChannelGains; i++) { 139 if (channelGainDb[i] == (FIXP_DBL)MINVAL_DBL) { 140 hGainDec->channelGain[i] = (FIXP_DBL)0; 141 } else { 142 /* add loudness normalisation gain (dB) to channel gain (dB) */ 143 FIXP_DBL tmp_channelGainDb = (channelGainDb[i] >> 1) + 144 (hGainDec->loudnessNormalisationGainDb >> 2); 145 tmp_channelGainDb = 146 SATURATE_LEFT_SHIFT(tmp_channelGainDb, 1, DFRACT_BITS); 147 channelGain = dB2lin(tmp_channelGainDb, 8, &channelGain_e); 148 hGainDec->channelGain[i] = scaleValue(channelGain, channelGain_e - 8); 149 } 150 } 151 } 152 153 /*******************************************/ 154 /* public functions */ 155 /*******************************************/ 156 157 DRC_ERROR 158 drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec) { 159 DRC_GAIN_DECODER* hGainDec = NULL; 160 161 hGainDec = (DRC_GAIN_DECODER*)FDKcalloc(1, sizeof(DRC_GAIN_DECODER)); 162 if (hGainDec == NULL) return DE_MEMORY_ERROR; 163 164 hGainDec->multiBandActiveDrcIndex = -1; 165 hGainDec->channelGainActiveDrcIndex = -1; 166 167 *phGainDec = hGainDec; 168 169 return DE_OK; 170 } 171 172 DRC_ERROR 173 drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize, 174 const int sampleRate) { 175 DRC_ERROR err = DE_OK; 176 177 err = initGainDec(hGainDec, frameSize, sampleRate); 178 if (err) return err; 179 180 initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers); 181 182 return err; 183 } 184 185 DRC_ERROR 186 drcDec_GainDecoder_SetCodecDependentParameters( 187 HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode, 188 const int timeDomainSupported, 189 const SUBBAND_DOMAIN_MODE subbandDomainSupported) { 190 if ((delayMode != DM_REGULAR_DELAY) && (delayMode != DM_LOW_DELAY)) { 191 return DE_NOT_OK; 192 } 193 hGainDec->delayMode = delayMode; 194 hGainDec->timeDomainSupported = timeDomainSupported; 195 hGainDec->subbandDomainSupported = subbandDomainSupported; 196 197 return DE_OK; 198 } 199 200 DRC_ERROR 201 drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec, 202 HANDLE_UNI_DRC_CONFIG hUniDrcConfig, 203 const UCHAR numSelectedDrcSets, 204 const SCHAR* selectedDrcSetIds, 205 const UCHAR* selectedDownmixIds) { 206 DRC_ERROR err = DE_OK; 207 int a; 208 209 hGainDec->nActiveDrcs = 0; 210 hGainDec->multiBandActiveDrcIndex = -1; 211 hGainDec->channelGainActiveDrcIndex = -1; 212 for (a = 0; a < numSelectedDrcSets; a++) { 213 err = initActiveDrc(hGainDec, hUniDrcConfig, selectedDrcSetIds[a], 214 selectedDownmixIds[a]); 215 if (err) return err; 216 } 217 218 err = initActiveDrcOffset(hGainDec); 219 if (err) return err; 220 221 return err; 222 } 223 224 DRC_ERROR 225 drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER* phGainDec) { 226 if (*phGainDec != NULL) { 227 FDKfree(*phGainDec); 228 *phGainDec = NULL; 229 } 230 231 return DE_OK; 232 } 233 234 DRC_ERROR 235 drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec, 236 HANDLE_UNI_DRC_GAIN hUniDrcGain, 237 const FIXP_DBL loudnessNormalizationGainDb, 238 const FIXP_SGL boost, const FIXP_SGL compress) { 239 DRC_ERROR err = DE_OK; 240 int a, c; 241 242 /* lnbPointer is the index on the most recent node buffer */ 243 hGainDec->drcGainBuffers.lnbPointer++; 244 if (hGainDec->drcGainBuffers.lnbPointer >= NUM_LNB_FRAMES) 245 hGainDec->drcGainBuffers.lnbPointer = 0; 246 247 for (a = 0; a < hGainDec->nActiveDrcs; a++) { 248 /* prepare gain interpolation of sequences used by copying and modifying 249 * nodes in node buffers */ 250 err = prepareDrcGain(hGainDec, hUniDrcGain, compress, boost, 251 loudnessNormalizationGainDb, a); 252 if (err) return err; 253 } 254 255 for (a = 0; a < MAX_ACTIVE_DRCS; a++) { 256 for (c = 0; c < 8; c++) { 257 hGainDec->activeDrc[a] 258 .lnbIndexForChannel[c][hGainDec->drcGainBuffers.lnbPointer] = 259 -1; /* "no DRC processing" */ 260 } 261 hGainDec->activeDrc[a].subbandGainsReady = 0; 262 } 263 264 for (c = 0; c < 8; c++) { 265 hGainDec->drcGainBuffers 266 .channelGain[c][hGainDec->drcGainBuffers.lnbPointer] = 267 FL2FXCONST_DBL(1.0f / (float)(1 << 8)); 268 } 269 270 return err; 271 } 272 273 /* create gain sequence out of gain sequences of last frame for concealment and 274 * flushing */ 275 DRC_ERROR 276 drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec, 277 HANDLE_UNI_DRC_CONFIG hUniDrcConfig, 278 HANDLE_UNI_DRC_GAIN hUniDrcGain) { 279 int seq, gainSequenceCount; 280 DRC_COEFFICIENTS_UNI_DRC* pCoef = 281 selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); 282 if (pCoef == NULL) return DE_OK; 283 284 gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); 285 286 for (seq = 0; seq < gainSequenceCount; seq++) { 287 int lastNodeIndex = 0; 288 FIXP_SGL lastGainDb = (FIXP_SGL)0; 289 290 lastNodeIndex = hUniDrcGain->nNodes[seq] - 1; 291 if ((lastNodeIndex >= 0) && (lastNodeIndex < 16)) { 292 lastGainDb = hUniDrcGain->gainNode[seq][lastNodeIndex].gainDb; 293 } 294 295 hUniDrcGain->nNodes[seq] = 1; 296 if (lastGainDb > (FIXP_SGL)0) { 297 hUniDrcGain->gainNode[seq][0].gainDb = 298 FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.9f), lastGainDb)); 299 } else { 300 hUniDrcGain->gainNode[seq][0].gainDb = 301 FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.98f), lastGainDb)); 302 } 303 hUniDrcGain->gainNode[seq][0].time = hGainDec->frameSize - 1; 304 } 305 return DE_OK; 306 } 307 308 void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec, 309 const int numChannels, 310 const int frameSize, 311 const FIXP_DBL* channelGainDb, 312 const int audioBufferChannelOffset, 313 FIXP_DBL* audioBuffer) { 314 int c, i; 315 316 if (hGainDec->channelGainActiveDrcIndex >= 0) { 317 /* channel gains will be applied in drcDec_GainDecoder_ProcessTimeDomain or 318 * drcDec_GainDecoder_ProcessSubbandDomain, respectively. */ 319 _setChannelGains(hGainDec, numChannels, channelGainDb); 320 321 if (!hGainDec->status) { /* overwrite previous channel gains at startup */ 322 DRC_GAIN_BUFFERS* pDrcGainBuffers = &hGainDec->drcGainBuffers; 323 for (c = 0; c < numChannels; c++) { 324 for (i = 0; i < NUM_LNB_FRAMES; i++) { 325 pDrcGainBuffers->channelGain[c][i] = hGainDec->channelGain[c]; 326 } 327 } 328 hGainDec->status = 1; 329 } 330 } else { 331 /* smooth and apply channel gains */ 332 FIXP_DBL prevChannelGain[8]; 333 for (c = 0; c < numChannels; c++) { 334 prevChannelGain[c] = hGainDec->channelGain[c]; 335 } 336 337 _setChannelGains(hGainDec, numChannels, channelGainDb); 338 339 if (!hGainDec->status) { /* overwrite previous channel gains at startup */ 340 for (c = 0; c < numChannels; c++) 341 prevChannelGain[c] = hGainDec->channelGain[c]; 342 hGainDec->status = 1; 343 } 344 345 for (c = 0; c < numChannels; c++) { 346 INT n_min = fMin(fMin(CntLeadingZeros(prevChannelGain[c]), 347 CntLeadingZeros(hGainDec->channelGain[c])) - 348 1, 349 9); 350 FIXP_DBL gain = prevChannelGain[c] << n_min; 351 FIXP_DBL stepsize = ((hGainDec->channelGain[c] << n_min) - gain); 352 if (stepsize != (FIXP_DBL)0) { 353 if (frameSize == 1024) 354 stepsize = stepsize >> 10; 355 else 356 stepsize = (LONG)stepsize / frameSize; 357 } 358 n_min = 9 - n_min; 359 #ifdef FUNCTION_drcDec_GainDecoder_SetChannelGains_func1 360 drcDec_GainDecoder_SetChannelGains_func1(audioBuffer, gain, stepsize, 361 n_min, frameSize); 362 #else 363 for (i = 0; i < frameSize; i++) { 364 audioBuffer[i] = fMultDiv2(audioBuffer[i], gain) << n_min; 365 gain += stepsize; 366 } 367 #endif 368 audioBuffer += audioBufferChannelOffset; 369 } 370 } 371 } 372 373 DRC_ERROR 374 drcDec_GainDecoder_ProcessTimeDomain( 375 HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples, 376 const GAIN_DEC_LOCATION drcLocation, const int channelOffset, 377 const int drcChannelOffset, const int numChannelsProcessed, 378 const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer) { 379 DRC_ERROR err = DE_OK; 380 int a; 381 382 if (!hGainDec->timeDomainSupported) { 383 return DE_NOT_OK; 384 } 385 386 for (a = 0; a < hGainDec->nActiveDrcs; a++) { 387 if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue; 388 389 /* Apply DRC */ 390 err = processDrcTime(hGainDec, a, delaySamples, channelOffset, 391 drcChannelOffset, numChannelsProcessed, 392 timeDataChannelOffset, audioIOBuffer); 393 if (err) return err; 394 } 395 396 return err; 397 } 398 399 DRC_ERROR 400 drcDec_GainDecoder_ProcessSubbandDomain( 401 HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples, 402 const GAIN_DEC_LOCATION drcLocation, const int channelOffset, 403 const int drcChannelOffset, const int numChannelsProcessed, 404 const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[], 405 FIXP_DBL* audioIOBufferImag[]) { 406 DRC_ERROR err = DE_OK; 407 int a; 408 409 if (hGainDec->subbandDomainSupported == SDM_OFF) { 410 return DE_NOT_OK; 411 } 412 413 for (a = 0; a < hGainDec->nActiveDrcs; a++) { 414 if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue; 415 416 /* Apply DRC */ 417 err = processDrcSubband(hGainDec, a, delaySamples, channelOffset, 418 drcChannelOffset, numChannelsProcessed, 419 processSingleTimeslot, audioIOBufferReal, 420 audioIOBufferImag); 421 if (err) return err; 422 } 423 424 return err; 425 } 426 427 DRC_ERROR 428 drcDec_GainDecoder_SetLoudnessNormalizationGainDb( 429 HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb) { 430 hGainDec->loudnessNormalisationGainDb = loudnessNormalizationGainDb; 431 432 return DE_OK; 433 } 434 435 int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec) { 436 if (hGainDec == NULL) return -1; 437 438 return hGainDec->frameSize; 439 } 440 441 int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec) { 442 if (hGainDec == NULL) return -1; 443 444 return hGainDec->deltaTminDefault; 445 } 446