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_tools.h" 105 #include "drcDec_gainDecoder.h" 106 #include "drcGainDec_init.h" 107 108 static DRC_ERROR _generateDrcInstructionsDerivedData( 109 HANDLE_DRC_GAIN_DECODER hGainDec, HANDLE_UNI_DRC_CONFIG hUniDrcConfig, 110 DRC_INSTRUCTIONS_UNI_DRC* pInst, DRC_COEFFICIENTS_UNI_DRC* pCoef, 111 ACTIVE_DRC* pActiveDrc) { 112 DRC_ERROR err = DE_OK; 113 int g; 114 int gainElementCount = 0; 115 UCHAR nDrcChannelGroups = 0; 116 SCHAR gainSetIndexForChannelGroup[8]; 117 118 err = deriveDrcChannelGroups( 119 pInst->drcSetEffect, pInst->drcChannelCount, pInst->gainSetIndex, 120 pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF) 121 ? pInst->duckingModificationForChannel 122 : NULL, 123 &nDrcChannelGroups, gainSetIndexForChannelGroup, 124 pActiveDrc->channelGroupForChannel, 125 pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF) 126 ? pActiveDrc->duckingModificationForChannelGroup 127 : NULL); 128 if (err) return (err); 129 130 /* sanity check */ 131 if (nDrcChannelGroups != pInst->nDrcChannelGroups) return DE_NOT_OK; 132 for (g = 0; g < pInst->nDrcChannelGroups; g++) { 133 if (gainSetIndexForChannelGroup[g] != pInst->gainSetIndexForChannelGroup[g]) 134 return DE_NOT_OK; 135 } 136 137 for (g = 0; g < pInst->nDrcChannelGroups; g++) { 138 int seq = pInst->gainSetIndexForChannelGroup[g]; 139 if (seq != -1 && (hUniDrcConfig->drcCoefficientsUniDrcCount == 0 || 140 seq >= pCoef->gainSetCount)) { 141 pActiveDrc->channelGroupIsParametricDrc[g] = 1; 142 } else { 143 pActiveDrc->channelGroupIsParametricDrc[g] = 0; 144 if (seq >= pCoef->gainSetCount) { 145 return DE_NOT_OK; 146 } 147 } 148 } 149 150 /* gainElementCount */ 151 if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) { 152 for (g = 0; g < pInst->nDrcChannelGroups; g++) { 153 pActiveDrc->bandCountForChannelGroup[g] = 1; 154 } 155 pActiveDrc->gainElementCount = 156 pInst->nDrcChannelGroups; /* one gain element per channel group */ 157 } else { 158 for (g = 0; g < pInst->nDrcChannelGroups; g++) { 159 if (pActiveDrc->channelGroupIsParametricDrc[g]) { 160 gainElementCount++; 161 pActiveDrc->bandCountForChannelGroup[g] = 1; 162 } else { 163 int seq, bandCount; 164 seq = pInst->gainSetIndexForChannelGroup[g]; 165 bandCount = pCoef->gainSet[seq].bandCount; 166 pActiveDrc->bandCountForChannelGroup[g] = bandCount; 167 gainElementCount += bandCount; 168 } 169 } 170 pActiveDrc->gainElementCount = gainElementCount; 171 } 172 173 /* prepare gainElementForGroup (cumulated sum of bandCountForChannelGroup) */ 174 pActiveDrc->gainElementForGroup[0] = 0; 175 for (g = 1; g < pInst->nDrcChannelGroups; g++) { 176 pActiveDrc->gainElementForGroup[g] = 177 pActiveDrc->gainElementForGroup[g - 1] + 178 pActiveDrc->bandCountForChannelGroup[g - 1]; /* index of first gain 179 sequence in channel 180 group */ 181 } 182 183 return DE_OK; 184 } 185 186 DRC_ERROR 187 initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize, 188 const int sampleRate) { 189 int i, j, k; 190 191 if (frameSize < 1) { 192 return DE_NOT_OK; 193 } 194 195 hGainDec->frameSize = frameSize; 196 197 if (hGainDec->frameSize * 1000 < sampleRate) { 198 return DE_NOT_OK; 199 } 200 201 hGainDec->deltaTminDefault = getDeltaTmin(sampleRate); 202 if (hGainDec->deltaTminDefault > hGainDec->frameSize) { 203 return DE_NOT_OK; 204 } 205 206 for (i = 0; i < MAX_ACTIVE_DRCS; i++) { 207 for (j = 0; j < 8; j++) { 208 /* use startup node at the beginning */ 209 hGainDec->activeDrc[i].lnbIndexForChannel[j][0] = 0; 210 for (k = 1; k < NUM_LNB_FRAMES; k++) { 211 hGainDec->activeDrc[i].lnbIndexForChannel[j][k] = -1; 212 } 213 } 214 } 215 216 for (j = 0; j < 8; j++) { 217 hGainDec->channelGain[j] = FL2FXCONST_DBL(1.0f / (float)(1 << 8)); 218 } 219 220 for (i = 0; i < 4 * 1024 / 256; i++) { 221 hGainDec->dummySubbandGains[i] = FL2FXCONST_DBL(1.0f / (float)(1 << 7)); 222 } 223 224 hGainDec->status = 0; /* startup */ 225 226 return DE_OK; 227 } 228 229 void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers) { 230 int i, c, j; 231 /* prepare 12 instances of node buffers */ 232 for (i = 0; i < 12; i++) { 233 for (j = 0; j < NUM_LNB_FRAMES; j++) { 234 drcGainBuffers->linearNodeBuffer[i].nNodes[j] = 1; 235 drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].gainLin = 236 FL2FXCONST_DBL(1.0f / (float)(1 << 7)); 237 if (j == 0) { 238 drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time = 239 0; /* initialize last node with startup node */ 240 } else { 241 drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time = 242 frameSize - 1; 243 } 244 } 245 } 246 247 /* prepare dummyLnb, a linearNodeBuffer containing a constant gain of 0 dB, 248 * for the "no DRC processing" case */ 249 drcGainBuffers->dummyLnb.gainInterpolationType = GIT_LINEAR; 250 for (i = 0; i < NUM_LNB_FRAMES; i++) { 251 drcGainBuffers->dummyLnb.nNodes[i] = 1; 252 drcGainBuffers->dummyLnb.linearNode[i][0].gainLin = 253 FL2FXCONST_DBL(1.0f / (float)(1 << 7)); 254 drcGainBuffers->dummyLnb.linearNode[i][0].time = frameSize - 1; 255 } 256 257 /* prepare channelGain delay line */ 258 for (c = 0; c < 8; c++) { 259 for (i = 0; i < NUM_LNB_FRAMES; i++) { 260 drcGainBuffers->channelGain[c][i] = 261 FL2FXCONST_DBL(1.0f / (float)(1 << 8)); 262 } 263 } 264 265 drcGainBuffers->lnbPointer = 0; 266 } 267 268 DRC_ERROR 269 initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec, 270 HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetIdSelected, 271 const int downmixIdSelected) { 272 int g, isMultiband = 0; 273 DRC_ERROR err = DE_OK; 274 DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL; 275 DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL; 276 277 pInst = selectDrcInstructions(hUniDrcConfig, drcSetIdSelected); 278 if (pInst == NULL) { 279 return DE_NOT_OK; 280 } 281 282 if (pInst->drcSetId >= 0) { 283 pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation); 284 if (pCoef == NULL) { 285 return DE_NOT_OK; 286 } 287 288 if (pCoef->drcFrameSizePresent) { 289 if (pCoef->drcFrameSize != hGainDec->frameSize) { 290 return DE_NOT_OK; 291 } 292 } 293 294 err = _generateDrcInstructionsDerivedData( 295 hGainDec, hUniDrcConfig, pInst, pCoef, 296 &(hGainDec->activeDrc[hGainDec->nActiveDrcs])); 297 if (err) return err; 298 } 299 300 hGainDec->activeDrc[hGainDec->nActiveDrcs].pInst = pInst; 301 hGainDec->activeDrc[hGainDec->nActiveDrcs].pCoef = pCoef; 302 303 for (g = 0; g < pInst->nDrcChannelGroups; g++) { 304 if (hGainDec->activeDrc[hGainDec->nActiveDrcs].bandCountForChannelGroup[g] > 305 1) { 306 if (hGainDec->multiBandActiveDrcIndex != -1) { 307 return DE_NOT_OK; 308 } 309 isMultiband = 1; 310 } 311 } 312 313 if (isMultiband) { 314 /* Keep activeDrc index of multiband DRC set */ 315 hGainDec->multiBandActiveDrcIndex = hGainDec->nActiveDrcs; 316 } 317 318 if ((hGainDec->channelGainActiveDrcIndex == -1) && 319 (downmixIdSelected == DOWNMIX_ID_BASE_LAYOUT) && 320 (hUniDrcConfig->drcInstructionsUniDrcCount > 321 0)) { /* use this activeDrc to apply channelGains */ 322 hGainDec->channelGainActiveDrcIndex = hGainDec->nActiveDrcs; 323 } 324 325 hGainDec->nActiveDrcs++; 326 if (hGainDec->nActiveDrcs > MAX_ACTIVE_DRCS) return DE_NOT_OK; 327 328 return DE_OK; 329 } 330 331 DRC_ERROR 332 initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec) { 333 int a, accGainElementCount; 334 335 accGainElementCount = 0; 336 for (a = 0; a < hGainDec->nActiveDrcs; a++) { 337 hGainDec->activeDrc[a].activeDrcOffset = accGainElementCount; 338 accGainElementCount += hGainDec->activeDrc[a].gainElementCount; 339 } 340 341 if (accGainElementCount > 12) return DE_NOT_OK; 342 343 return DE_OK; 344 } 345