• 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_gainDecoder.h"
105 #include "drcGainDec_preprocess.h"
106 #include "drcGainDec_init.h"
107 #include "drcGainDec_process.h"
108 #include "drcDec_tools.h"
109 
110 /*******************************************/
111 /* static functions                        */
112 /*******************************************/
113 
_fitsLocation(DRC_INSTRUCTIONS_UNI_DRC * pInst,const GAIN_DEC_LOCATION drcLocation)114 static int _fitsLocation(DRC_INSTRUCTIONS_UNI_DRC* pInst,
115                          const GAIN_DEC_LOCATION drcLocation) {
116   int downmixId = pInst->drcApplyToDownmix ? pInst->downmixId[0] : 0;
117   switch (drcLocation) {
118     case GAIN_DEC_DRC1:
119       return (downmixId == 0);
120     case GAIN_DEC_DRC1_DRC2:
121       return ((downmixId == 0) || (downmixId == DOWNMIX_ID_ANY_DOWNMIX));
122     case GAIN_DEC_DRC2:
123       return (downmixId == DOWNMIX_ID_ANY_DOWNMIX);
124     case GAIN_DEC_DRC3:
125       return ((downmixId != 0) && (downmixId != DOWNMIX_ID_ANY_DOWNMIX));
126     case GAIN_DEC_DRC2_DRC3:
127       return (downmixId != 0);
128   }
129   return 0;
130 }
131 
_setChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,const int numChannelGains,const FIXP_DBL * channelGainDb)132 static void _setChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
133                              const int numChannelGains,
134                              const FIXP_DBL* channelGainDb) {
135   int i, channelGain_e;
136   FIXP_DBL channelGain;
137   FDK_ASSERT(numChannelGains <= 8);
138   for (i = 0; i < numChannelGains; i++) {
139     if (channelGainDb[i] == (FIXP_DBL)MINVAL_DBL) {
140       hGainDec->channelGain[i] = (FIXP_DBL)0;
141     } else {
142       /* add loudness normalisation gain (dB) to channel gain (dB) */
143       FIXP_DBL tmp_channelGainDb = (channelGainDb[i] >> 1) +
144                                    (hGainDec->loudnessNormalisationGainDb >> 2);
145       tmp_channelGainDb =
146           SATURATE_LEFT_SHIFT(tmp_channelGainDb, 1, DFRACT_BITS);
147       channelGain = dB2lin(tmp_channelGainDb, 8, &channelGain_e);
148       hGainDec->channelGain[i] = scaleValue(channelGain, channelGain_e - 8);
149     }
150   }
151 }
152 
153 /*******************************************/
154 /* public functions                        */
155 /*******************************************/
156 
157 DRC_ERROR
drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER * phGainDec)158 drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec) {
159   DRC_GAIN_DECODER* hGainDec = NULL;
160 
161   hGainDec = (DRC_GAIN_DECODER*)FDKcalloc(1, sizeof(DRC_GAIN_DECODER));
162   if (hGainDec == NULL) return DE_MEMORY_ERROR;
163 
164   hGainDec->multiBandActiveDrcIndex = -1;
165   hGainDec->channelGainActiveDrcIndex = -1;
166 
167   *phGainDec = hGainDec;
168 
169   return DE_OK;
170 }
171 
172 DRC_ERROR
drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec,const int frameSize,const int sampleRate)173 drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
174                         const int sampleRate) {
175   DRC_ERROR err = DE_OK;
176 
177   err = initGainDec(hGainDec, frameSize, sampleRate);
178   if (err) return err;
179 
180   initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers);
181 
182   return err;
183 }
184 
185 DRC_ERROR
drcDec_GainDecoder_SetCodecDependentParameters(HANDLE_DRC_GAIN_DECODER hGainDec,const DELAY_MODE delayMode,const int timeDomainSupported,const SUBBAND_DOMAIN_MODE subbandDomainSupported)186 drcDec_GainDecoder_SetCodecDependentParameters(
187     HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode,
188     const int timeDomainSupported,
189     const SUBBAND_DOMAIN_MODE subbandDomainSupported) {
190   if ((delayMode != DM_REGULAR_DELAY) && (delayMode != DM_LOW_DELAY)) {
191     return DE_NOT_OK;
192   }
193   hGainDec->delayMode = delayMode;
194   hGainDec->timeDomainSupported = timeDomainSupported;
195   hGainDec->subbandDomainSupported = subbandDomainSupported;
196 
197   return DE_OK;
198 }
199 
200 DRC_ERROR
drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const UCHAR numSelectedDrcSets,const SCHAR * selectedDrcSetIds,const UCHAR * selectedDownmixIds)201 drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,
202                           HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
203                           const UCHAR numSelectedDrcSets,
204                           const SCHAR* selectedDrcSetIds,
205                           const UCHAR* selectedDownmixIds) {
206   DRC_ERROR err = DE_OK;
207   int a;
208 
209   hGainDec->nActiveDrcs = 0;
210   hGainDec->multiBandActiveDrcIndex = -1;
211   hGainDec->channelGainActiveDrcIndex = -1;
212   for (a = 0; a < numSelectedDrcSets; a++) {
213     err = initActiveDrc(hGainDec, hUniDrcConfig, selectedDrcSetIds[a],
214                         selectedDownmixIds[a]);
215     if (err) return err;
216   }
217 
218   err = initActiveDrcOffset(hGainDec);
219   if (err) return err;
220 
221   return err;
222 }
223 
224 DRC_ERROR
drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER * phGainDec)225 drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER* phGainDec) {
226   if (*phGainDec != NULL) {
227     FDKfree(*phGainDec);
228     *phGainDec = NULL;
229   }
230 
231   return DE_OK;
232 }
233 
234 DRC_ERROR
drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_GAIN hUniDrcGain,const FIXP_DBL loudnessNormalizationGainDb,const FIXP_SGL boost,const FIXP_SGL compress)235 drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec,
236                               HANDLE_UNI_DRC_GAIN hUniDrcGain,
237                               const FIXP_DBL loudnessNormalizationGainDb,
238                               const FIXP_SGL boost, const FIXP_SGL compress) {
239   DRC_ERROR err = DE_OK;
240   int a, c;
241 
242   /* lnbPointer is the index on the most recent node buffer */
243   hGainDec->drcGainBuffers.lnbPointer++;
244   if (hGainDec->drcGainBuffers.lnbPointer >= NUM_LNB_FRAMES)
245     hGainDec->drcGainBuffers.lnbPointer = 0;
246 
247   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
248     /* prepare gain interpolation of sequences used by copying and modifying
249      * nodes in node buffers */
250     err = prepareDrcGain(hGainDec, hUniDrcGain, compress, boost,
251                          loudnessNormalizationGainDb, a);
252     if (err) return err;
253   }
254 
255   for (a = 0; a < MAX_ACTIVE_DRCS; a++) {
256     for (c = 0; c < 8; c++) {
257       hGainDec->activeDrc[a]
258           .lnbIndexForChannel[c][hGainDec->drcGainBuffers.lnbPointer] =
259           -1; /* "no DRC processing" */
260     }
261     hGainDec->activeDrc[a].subbandGainsReady = 0;
262   }
263 
264   for (c = 0; c < 8; c++) {
265     hGainDec->drcGainBuffers
266         .channelGain[c][hGainDec->drcGainBuffers.lnbPointer] =
267         FL2FXCONST_DBL(1.0f / (float)(1 << 8));
268   }
269 
270   return err;
271 }
272 
273 /* create gain sequence out of gain sequences of last frame for concealment and
274  * flushing */
275 DRC_ERROR
drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_UNI_DRC_GAIN hUniDrcGain)276 drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
277                            HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
278                            HANDLE_UNI_DRC_GAIN hUniDrcGain) {
279   int seq, gainSequenceCount;
280   DRC_COEFFICIENTS_UNI_DRC* pCoef =
281       selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
282   if (pCoef == NULL) return DE_OK;
283 
284   gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
285 
286   for (seq = 0; seq < gainSequenceCount; seq++) {
287     int lastNodeIndex = 0;
288     FIXP_SGL lastGainDb = (FIXP_SGL)0;
289 
290     lastNodeIndex = hUniDrcGain->nNodes[seq] - 1;
291     if ((lastNodeIndex >= 0) && (lastNodeIndex < 16)) {
292       lastGainDb = hUniDrcGain->gainNode[seq][lastNodeIndex].gainDb;
293     }
294 
295     hUniDrcGain->nNodes[seq] = 1;
296     if (lastGainDb > (FIXP_SGL)0) {
297       hUniDrcGain->gainNode[seq][0].gainDb =
298           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.9f), lastGainDb));
299     } else {
300       hUniDrcGain->gainNode[seq][0].gainDb =
301           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.98f), lastGainDb));
302     }
303     hUniDrcGain->gainNode[seq][0].time = hGainDec->frameSize - 1;
304   }
305   return DE_OK;
306 }
307 
drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,const int numChannels,const int frameSize,const FIXP_DBL * channelGainDb,const int audioBufferChannelOffset,FIXP_DBL * audioBuffer)308 void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
309                                         const int numChannels,
310                                         const int frameSize,
311                                         const FIXP_DBL* channelGainDb,
312                                         const int audioBufferChannelOffset,
313                                         FIXP_DBL* audioBuffer) {
314   int c, i;
315 
316   if (hGainDec->channelGainActiveDrcIndex >= 0) {
317     /* channel gains will be applied in drcDec_GainDecoder_ProcessTimeDomain or
318      * drcDec_GainDecoder_ProcessSubbandDomain, respectively. */
319     _setChannelGains(hGainDec, numChannels, channelGainDb);
320 
321     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
322       DRC_GAIN_BUFFERS* pDrcGainBuffers = &hGainDec->drcGainBuffers;
323       for (c = 0; c < numChannels; c++) {
324         for (i = 0; i < NUM_LNB_FRAMES; i++) {
325           pDrcGainBuffers->channelGain[c][i] = hGainDec->channelGain[c];
326         }
327       }
328       hGainDec->status = 1;
329     }
330   } else {
331     /* smooth and apply channel gains */
332     FIXP_DBL prevChannelGain[8];
333     for (c = 0; c < numChannels; c++) {
334       prevChannelGain[c] = hGainDec->channelGain[c];
335     }
336 
337     _setChannelGains(hGainDec, numChannels, channelGainDb);
338 
339     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
340       for (c = 0; c < numChannels; c++)
341         prevChannelGain[c] = hGainDec->channelGain[c];
342       hGainDec->status = 1;
343     }
344 
345     for (c = 0; c < numChannels; c++) {
346       INT n_min = fMin(fMin(CntLeadingZeros(prevChannelGain[c]),
347                             CntLeadingZeros(hGainDec->channelGain[c])) -
348                            1,
349                        9);
350       FIXP_DBL gain = prevChannelGain[c] << n_min;
351       FIXP_DBL stepsize = ((hGainDec->channelGain[c] << n_min) - gain);
352       if (stepsize != (FIXP_DBL)0) {
353         if (frameSize == 1024)
354           stepsize = stepsize >> 10;
355         else
356           stepsize = (LONG)stepsize / frameSize;
357       }
358       n_min = 9 - n_min;
359 #ifdef FUNCTION_drcDec_GainDecoder_SetChannelGains_func1
360       drcDec_GainDecoder_SetChannelGains_func1(audioBuffer, gain, stepsize,
361                                                n_min, frameSize);
362 #else
363       for (i = 0; i < frameSize; i++) {
364         audioBuffer[i] = fMultDiv2(audioBuffer[i], gain) << n_min;
365         gain += stepsize;
366       }
367 #endif
368       audioBuffer += audioBufferChannelOffset;
369     }
370   }
371 }
372 
373 DRC_ERROR
drcDec_GainDecoder_ProcessTimeDomain(HANDLE_DRC_GAIN_DECODER hGainDec,const int delaySamples,const GAIN_DEC_LOCATION drcLocation,const int channelOffset,const int drcChannelOffset,const int numChannelsProcessed,const int timeDataChannelOffset,FIXP_DBL * audioIOBuffer)374 drcDec_GainDecoder_ProcessTimeDomain(
375     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
376     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
377     const int drcChannelOffset, const int numChannelsProcessed,
378     const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer) {
379   DRC_ERROR err = DE_OK;
380   int a;
381 
382   if (!hGainDec->timeDomainSupported) {
383     return DE_NOT_OK;
384   }
385 
386   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
387     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
388 
389     /* Apply DRC */
390     err = processDrcTime(hGainDec, a, delaySamples, channelOffset,
391                          drcChannelOffset, numChannelsProcessed,
392                          timeDataChannelOffset, audioIOBuffer);
393     if (err) return err;
394   }
395 
396   return err;
397 }
398 
399 DRC_ERROR
drcDec_GainDecoder_ProcessSubbandDomain(HANDLE_DRC_GAIN_DECODER hGainDec,const int delaySamples,const GAIN_DEC_LOCATION drcLocation,const int channelOffset,const int drcChannelOffset,const int numChannelsProcessed,const int processSingleTimeslot,FIXP_DBL * audioIOBufferReal[],FIXP_DBL * audioIOBufferImag[])400 drcDec_GainDecoder_ProcessSubbandDomain(
401     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
402     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
403     const int drcChannelOffset, const int numChannelsProcessed,
404     const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[],
405     FIXP_DBL* audioIOBufferImag[]) {
406   DRC_ERROR err = DE_OK;
407   int a;
408 
409   if (hGainDec->subbandDomainSupported == SDM_OFF) {
410     return DE_NOT_OK;
411   }
412 
413   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
414     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
415 
416     /* Apply DRC */
417     err = processDrcSubband(hGainDec, a, delaySamples, channelOffset,
418                             drcChannelOffset, numChannelsProcessed,
419                             processSingleTimeslot, audioIOBufferReal,
420                             audioIOBufferImag);
421     if (err) return err;
422   }
423 
424   return err;
425 }
426 
427 DRC_ERROR
drcDec_GainDecoder_SetLoudnessNormalizationGainDb(HANDLE_DRC_GAIN_DECODER hGainDec,FIXP_DBL loudnessNormalizationGainDb)428 drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
429     HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb) {
430   hGainDec->loudnessNormalisationGainDb = loudnessNormalizationGainDb;
431 
432   return DE_OK;
433 }
434 
drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec)435 int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec) {
436   if (hGainDec == NULL) return -1;
437 
438   return hGainDec->frameSize;
439 }
440 
drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec)441 int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec) {
442   if (hGainDec == NULL) return -1;
443 
444   return hGainDec->deltaTminDefault;
445 }
446