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 "fixpoint_math.h" 106 #include "drcDecoder.h" 107 108 int getDeltaTmin(const int sampleRate) { 109 /* half_ms = round (0.0005 * sampleRate); */ 110 int half_ms = (sampleRate + 1000) / 2000; 111 int deltaTmin = 1; 112 if (sampleRate < 1000) { 113 return DE_NOT_OK; 114 } 115 while (deltaTmin <= half_ms) { 116 deltaTmin = deltaTmin << 1; 117 } 118 return deltaTmin; 119 } 120 121 DRC_COEFFICIENTS_UNI_DRC* selectDrcCoefficients( 122 HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int location) { 123 int n; 124 int c = -1; 125 for (n = 0; n < hUniDrcConfig->drcCoefficientsUniDrcCount; n++) { 126 if (hUniDrcConfig->drcCoefficientsUniDrc[n].drcLocation == location) { 127 c = n; 128 } 129 } 130 if (c >= 0) { 131 return &(hUniDrcConfig->drcCoefficientsUniDrc[c]); 132 } 133 return NULL; /* possible during bitstream parsing */ 134 } 135 136 DRC_INSTRUCTIONS_UNI_DRC* selectDrcInstructions( 137 HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetId) { 138 int i; 139 for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) { 140 if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId == drcSetId) { 141 return &(hUniDrcConfig->drcInstructionsUniDrc[i]); 142 } 143 } 144 return NULL; 145 } 146 147 DOWNMIX_INSTRUCTIONS* selectDownmixInstructions( 148 HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int downmixId) { 149 int i; 150 for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) { 151 if (hUniDrcConfig->downmixInstructions[i].downmixId == downmixId) { 152 return &(hUniDrcConfig->downmixInstructions[i]); 153 } 154 } 155 return NULL; 156 } 157 158 DRC_ERROR 159 deriveDrcChannelGroups( 160 const int drcSetEffect, /* in */ 161 const int channelCount, /* in */ 162 const SCHAR* gainSetIndex, /* in */ 163 const DUCKING_MODIFICATION* duckingModificationForChannel, /* in */ 164 UCHAR* nDrcChannelGroups, /* out */ 165 SCHAR* uniqueIndex, /* out (gainSetIndexForChannelGroup) */ 166 SCHAR* groupForChannel, /* out */ 167 DUCKING_MODIFICATION* duckingModificationForChannelGroup) /* out */ 168 { 169 int duckingSequence = -1; 170 int c, n, g, match, idx; 171 FIXP_SGL factor; 172 FIXP_SGL uniqueScaling[8]; 173 174 for (g = 0; g < 8; g++) { 175 uniqueIndex[g] = -10; 176 uniqueScaling[g] = FIXP_SGL(-1.0f); 177 } 178 179 g = 0; 180 181 if (drcSetEffect & EB_DUCK_OTHER) { 182 for (c = 0; c < channelCount; c++) { 183 match = 0; 184 if (c >= 8) return DE_MEMORY_ERROR; 185 idx = gainSetIndex[c]; 186 factor = duckingModificationForChannel[c].duckingScaling; 187 if (idx < 0) { 188 for (n = 0; n < g; n++) { 189 if (uniqueScaling[n] == factor) { 190 match = 1; 191 groupForChannel[c] = n; 192 break; 193 } 194 } 195 if (match == 0) { 196 if (g >= 8) return DE_MEMORY_ERROR; 197 uniqueIndex[g] = idx; 198 uniqueScaling[g] = factor; 199 groupForChannel[c] = g; 200 g++; 201 } 202 } else { 203 if ((duckingSequence > 0) && (duckingSequence != idx)) { 204 return DE_NOT_OK; 205 } 206 duckingSequence = idx; 207 groupForChannel[c] = -1; 208 } 209 } 210 if (duckingSequence == -1) { 211 return DE_NOT_OK; 212 } 213 } else if (drcSetEffect & EB_DUCK_SELF) { 214 for (c = 0; c < channelCount; c++) { 215 match = 0; 216 if (c >= 8) return DE_MEMORY_ERROR; 217 idx = gainSetIndex[c]; 218 factor = duckingModificationForChannel[c].duckingScaling; 219 if (idx >= 0) { 220 for (n = 0; n < g; n++) { 221 if ((uniqueIndex[n] == idx) && (uniqueScaling[n] == factor)) { 222 match = 1; 223 groupForChannel[c] = n; 224 break; 225 } 226 } 227 if (match == 0) { 228 if (g >= 8) return DE_MEMORY_ERROR; 229 uniqueIndex[g] = idx; 230 uniqueScaling[g] = factor; 231 groupForChannel[c] = g; 232 g++; 233 } 234 } else { 235 groupForChannel[c] = -1; 236 } 237 } 238 } else { /* no ducking */ 239 for (c = 0; c < channelCount; c++) { 240 if (c >= 8) return DE_MEMORY_ERROR; 241 idx = gainSetIndex[c]; 242 match = 0; 243 if (idx >= 0) { 244 for (n = 0; n < g; n++) { 245 if (uniqueIndex[n] == idx) { 246 match = 1; 247 groupForChannel[c] = n; 248 break; 249 } 250 } 251 if (match == 0) { 252 if (g >= 8) return DE_MEMORY_ERROR; 253 uniqueIndex[g] = idx; 254 groupForChannel[c] = g; 255 g++; 256 } 257 } else { 258 groupForChannel[c] = -1; 259 } 260 } 261 } 262 *nDrcChannelGroups = g; 263 264 if (drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) { 265 for (g = 0; g < *nDrcChannelGroups; g++) { 266 if (drcSetEffect & EB_DUCK_OTHER) { 267 uniqueIndex[g] = duckingSequence; 268 } 269 duckingModificationForChannelGroup[g].duckingScaling = uniqueScaling[g]; 270 if (uniqueScaling[g] != FL2FXCONST_SGL(1.0f / (float)(1 << 2))) { 271 duckingModificationForChannelGroup[g].duckingScalingPresent = 1; 272 } else { 273 duckingModificationForChannelGroup[g].duckingScalingPresent = 0; 274 } 275 } 276 } 277 278 return DE_OK; 279 } 280 281 FIXP_DBL 282 dB2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e) { 283 /* get linear value from dB. 284 return lin_val = 10^(dB_val/20) = 2^(log2(10)/20*dB_val) 285 with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */ 286 FIXP_DBL lin_m = 287 f2Pow(fMult(dB_m, FL2FXCONST_DBL(0.1660964f * (float)(1 << 2))), dB_e - 2, 288 pLin_e); 289 290 return lin_m; 291 } 292 293 FIXP_DBL 294 lin2dB(const FIXP_DBL lin_m, const int lin_e, int* pDb_e) { 295 /* get dB value from linear value. 296 return dB_val = 20*log10(lin_val) 297 with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */ 298 FIXP_DBL dB_m; 299 300 if (lin_m == (FIXP_DBL)0) { /* return very small value representing -inf */ 301 dB_m = (FIXP_DBL)MINVAL_DBL; 302 *pDb_e = DFRACT_BITS - 1; 303 } else { 304 /* 20*log10(lin_val) = 20/log2(10)*log2(lin_val) */ 305 dB_m = fMultDiv2(FL2FXCONST_DBL(6.02059991f / (float)(1 << 3)), 306 fLog2(lin_m, lin_e, pDb_e)); 307 *pDb_e += 3 + 1; 308 } 309 310 return dB_m; 311 } 312 313 FIXP_DBL 314 approxDb2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e) { 315 /* get linear value from approximate dB. 316 return lin_val = 2^(dB_val/6) 317 with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */ 318 FIXP_DBL lin_m = 319 f2Pow(fMult(dB_m, FL2FXCONST_DBL(0.1666667f * (float)(1 << 2))), dB_e - 2, 320 pLin_e); 321 322 return lin_m; 323 } 324 325 int bitstreamContainsMultibandDrc(HANDLE_UNI_DRC_CONFIG hUniDrcConfig, 326 const int downmixId) { 327 int i, g, d, seq; 328 DRC_INSTRUCTIONS_UNI_DRC* pInst; 329 DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL; 330 int isMultiband = 0; 331 332 pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); 333 if (pCoef == NULL) return 0; 334 335 for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) { 336 pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]); 337 for (d = 0; d < pInst->downmixIdCount; d++) { 338 if (downmixId == pInst->downmixId[d]) { 339 for (g = 0; g < pInst->nDrcChannelGroups; g++) { 340 seq = pInst->gainSetIndexForChannelGroup[g]; 341 if (pCoef->gainSet[seq].bandCount > 1) { 342 isMultiband = 1; 343 } 344 } 345 } 346 } 347 } 348 349 return isMultiband; 350 } 351 352 FIXP_DBL getDownmixOffset(DOWNMIX_INSTRUCTIONS* pDown, int baseChannelCount) { 353 FIXP_DBL downmixOffset = FL2FXCONST_DBL(1.0f / (1 << 1)); /* e = 1 */ 354 if ((pDown->bsDownmixOffset == 1) || (pDown->bsDownmixOffset == 2)) { 355 int e_a, e_downmixOffset; 356 FIXP_DBL a, q; 357 if (baseChannelCount <= pDown->targetChannelCount) return downmixOffset; 358 359 q = fDivNorm((FIXP_DBL)pDown->targetChannelCount, 360 (FIXP_DBL)baseChannelCount); /* e = 0 */ 361 a = lin2dB(q, 0, &e_a); 362 if (pDown->bsDownmixOffset == 2) { 363 e_a += 1; /* a *= 2 */ 364 } 365 /* a = 0.5 * round (a) */ 366 a = fixp_round(a, e_a) >> 1; 367 downmixOffset = dB2lin(a, e_a, &e_downmixOffset); 368 downmixOffset = scaleValue(downmixOffset, e_downmixOffset - 1); 369 } 370 return downmixOffset; 371 } 372