• 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 "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