• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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