1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung 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@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
getDeltaTmin(const int sampleRate)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
selectDrcCoefficients(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const int location)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
selectDrcInstructions(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const int drcSetId)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
selectDownmixInstructions(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const int downmixId)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
deriveDrcChannelGroups(const int drcSetEffect,const int channelCount,const SCHAR * gainSetIndex,const DUCKING_MODIFICATION * duckingModificationForChannel,UCHAR * nDrcChannelGroups,SCHAR * uniqueIndex,SCHAR * groupForChannel,DUCKING_MODIFICATION * duckingModificationForChannelGroup)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
dB2lin(const FIXP_DBL dB_m,const int dB_e,int * pLin_e)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
lin2dB(const FIXP_DBL lin_m,const int lin_e,int * pDb_e)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
approxDb2lin(const FIXP_DBL dB_m,const int dB_e,int * pLin_e)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
bitstreamContainsMultibandDrc(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const int downmixId)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
getDownmixOffset(DOWNMIX_INSTRUCTIONS * pDown,int baseChannelCount)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