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 "drcDec_gainDecoder.h"
106 #include "drcGainDec_init.h"
107
_generateDrcInstructionsDerivedData(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRC_INSTRUCTIONS_UNI_DRC * pInst,DRC_COEFFICIENTS_UNI_DRC * pCoef,ACTIVE_DRC * pActiveDrc)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
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec,const int frameSize,const int sampleRate)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
initDrcGainBuffers(const int frameSize,DRC_GAIN_BUFFERS * drcGainBuffers)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
initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const int drcSetIdSelected,const int downmixIdSelected)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
initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec)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