• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2019 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)187 initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec) {
188   int i, j, k;
189 
190   /* sanity check */
191   if (hGainDec->deltaTminDefault > hGainDec->frameSize) return DE_NOT_OK;
192 
193   for (i = 0; i < MAX_ACTIVE_DRCS; i++) {
194     for (j = 0; j < 8; j++) {
195       /* use startup node at the beginning */
196       hGainDec->activeDrc[i].lnbIndexForChannel[j][0] = 0;
197       for (k = 1; k < NUM_LNB_FRAMES; k++) {
198         hGainDec->activeDrc[i].lnbIndexForChannel[j][k] = -1;
199       }
200     }
201   }
202 
203   for (j = 0; j < 8; j++) {
204     hGainDec->channelGain[j] = FL2FXCONST_DBL(1.0f / (float)(1 << 8));
205   }
206 
207   for (i = 0; i < 4 * 1024 / 256; i++) {
208     hGainDec->dummySubbandGains[i] = FL2FXCONST_DBL(1.0f / (float)(1 << 7));
209   }
210 
211   hGainDec->status = 0; /* startup */
212 
213   return DE_OK;
214 }
215 
initDrcGainBuffers(const int frameSize,DRC_GAIN_BUFFERS * drcGainBuffers)216 void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers) {
217   int i, c, j;
218   /* prepare 12 instances of node buffers */
219   for (i = 0; i < 12; i++) {
220     for (j = 0; j < NUM_LNB_FRAMES; j++) {
221       drcGainBuffers->linearNodeBuffer[i].nNodes[j] = 1;
222       drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].gainLin =
223           FL2FXCONST_DBL(1.0f / (float)(1 << 7));
224       if (j == 0) {
225         drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
226             0; /* initialize last node with startup node */
227       } else {
228         drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
229             frameSize - 1;
230       }
231     }
232   }
233 
234   /* prepare dummyLnb, a linearNodeBuffer containing a constant gain of 0 dB,
235    * for the "no DRC processing" case */
236   drcGainBuffers->dummyLnb.gainInterpolationType = GIT_LINEAR;
237   for (i = 0; i < NUM_LNB_FRAMES; i++) {
238     drcGainBuffers->dummyLnb.nNodes[i] = 1;
239     drcGainBuffers->dummyLnb.linearNode[i][0].gainLin =
240         FL2FXCONST_DBL(1.0f / (float)(1 << 7));
241     drcGainBuffers->dummyLnb.linearNode[i][0].time = frameSize - 1;
242   }
243 
244   /* prepare channelGain delay line */
245   for (c = 0; c < 8; c++) {
246     for (i = 0; i < NUM_LNB_FRAMES; i++) {
247       drcGainBuffers->channelGain[c][i] =
248           FL2FXCONST_DBL(1.0f / (float)(1 << 8));
249     }
250   }
251 
252   drcGainBuffers->lnbPointer = 0;
253 }
254 
255 DRC_ERROR
initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const int drcSetIdSelected,const int downmixIdSelected)256 initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec,
257               HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetIdSelected,
258               const int downmixIdSelected) {
259   int g, isMultiband = 0;
260   DRC_ERROR err = DE_OK;
261   DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
262   DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
263 
264   pInst = selectDrcInstructions(hUniDrcConfig, drcSetIdSelected);
265   if (pInst == NULL) {
266     return DE_NOT_OK;
267   }
268 
269   if (pInst->drcSetId >= 0) {
270     pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);
271     if (pCoef == NULL) {
272       return DE_NOT_OK;
273     }
274 
275     if (pCoef->drcFrameSizePresent) {
276       if (pCoef->drcFrameSize != hGainDec->frameSize) {
277         return DE_NOT_OK;
278       }
279     }
280 
281     err = _generateDrcInstructionsDerivedData(
282         hGainDec, hUniDrcConfig, pInst, pCoef,
283         &(hGainDec->activeDrc[hGainDec->nActiveDrcs]));
284     if (err) return err;
285   }
286 
287   hGainDec->activeDrc[hGainDec->nActiveDrcs].pInst = pInst;
288   hGainDec->activeDrc[hGainDec->nActiveDrcs].pCoef = pCoef;
289 
290   for (g = 0; g < pInst->nDrcChannelGroups; g++) {
291     if (hGainDec->activeDrc[hGainDec->nActiveDrcs].bandCountForChannelGroup[g] >
292         1) {
293       if (hGainDec->multiBandActiveDrcIndex != -1) {
294         return DE_NOT_OK;
295       }
296       isMultiband = 1;
297     }
298   }
299 
300   if (isMultiband) {
301     /* Keep activeDrc index of multiband DRC set */
302     hGainDec->multiBandActiveDrcIndex = hGainDec->nActiveDrcs;
303   }
304 
305   if ((hGainDec->channelGainActiveDrcIndex == -1) &&
306       (downmixIdSelected == DOWNMIX_ID_BASE_LAYOUT) &&
307       (hUniDrcConfig->drcInstructionsUniDrcCount >
308        0)) { /* use this activeDrc to apply channelGains */
309     hGainDec->channelGainActiveDrcIndex = hGainDec->nActiveDrcs;
310   }
311 
312   hGainDec->nActiveDrcs++;
313   if (hGainDec->nActiveDrcs > MAX_ACTIVE_DRCS) return DE_NOT_OK;
314 
315   return DE_OK;
316 }
317 
318 DRC_ERROR
initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec)319 initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec) {
320   int a, accGainElementCount;
321 
322   accGainElementCount = 0;
323   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
324     hGainDec->activeDrc[a].activeDrcOffset = accGainElementCount;
325     accGainElementCount += hGainDec->activeDrc[a].gainElementCount;
326     if (accGainElementCount > 12) {
327       hGainDec->nActiveDrcs = a;
328       return DE_NOT_OK;
329     }
330   }
331 
332   return DE_OK;
333 }
334