• 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_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)173 drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec) {
174   DRC_ERROR err = DE_OK;
175 
176   err = initGainDec(hGainDec);
177   if (err) return err;
178 
179   initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers);
180 
181   return err;
182 }
183 
184 DRC_ERROR
drcDec_GainDecoder_SetParam(HANDLE_DRC_GAIN_DECODER hGainDec,const GAIN_DEC_PARAM paramType,const int paramValue)185 drcDec_GainDecoder_SetParam(HANDLE_DRC_GAIN_DECODER hGainDec,
186                             const GAIN_DEC_PARAM paramType,
187                             const int paramValue) {
188   switch (paramType) {
189     case GAIN_DEC_FRAME_SIZE:
190       if (paramValue < 0) return DE_PARAM_OUT_OF_RANGE;
191       hGainDec->frameSize = paramValue;
192       break;
193     case GAIN_DEC_SAMPLE_RATE:
194       if (paramValue < 0) return DE_PARAM_OUT_OF_RANGE;
195       hGainDec->deltaTminDefault = getDeltaTmin(paramValue);
196       break;
197     default:
198       return DE_PARAM_INVALID;
199   }
200   return DE_OK;
201 }
202 
203 DRC_ERROR
drcDec_GainDecoder_SetCodecDependentParameters(HANDLE_DRC_GAIN_DECODER hGainDec,const DELAY_MODE delayMode,const int timeDomainSupported,const SUBBAND_DOMAIN_MODE subbandDomainSupported)204 drcDec_GainDecoder_SetCodecDependentParameters(
205     HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode,
206     const int timeDomainSupported,
207     const SUBBAND_DOMAIN_MODE subbandDomainSupported) {
208   if ((delayMode != DM_REGULAR_DELAY) && (delayMode != DM_LOW_DELAY)) {
209     return DE_NOT_OK;
210   }
211   hGainDec->delayMode = delayMode;
212   hGainDec->timeDomainSupported = timeDomainSupported;
213   hGainDec->subbandDomainSupported = subbandDomainSupported;
214 
215   return DE_OK;
216 }
217 
218 DRC_ERROR
drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,const UCHAR numSelectedDrcSets,const SCHAR * selectedDrcSetIds,const UCHAR * selectedDownmixIds)219 drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,
220                           HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
221                           const UCHAR numSelectedDrcSets,
222                           const SCHAR* selectedDrcSetIds,
223                           const UCHAR* selectedDownmixIds) {
224   DRC_ERROR err = DE_OK;
225   int a;
226 
227   hGainDec->nActiveDrcs = 0;
228   hGainDec->multiBandActiveDrcIndex = -1;
229   hGainDec->channelGainActiveDrcIndex = -1;
230   for (a = 0; a < numSelectedDrcSets; a++) {
231     err = initActiveDrc(hGainDec, hUniDrcConfig, selectedDrcSetIds[a],
232                         selectedDownmixIds[a]);
233     if (err) return err;
234   }
235 
236   err = initActiveDrcOffset(hGainDec);
237   if (err) return err;
238 
239   return err;
240 }
241 
242 DRC_ERROR
drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER * phGainDec)243 drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER* phGainDec) {
244   if (*phGainDec != NULL) {
245     FDKfree(*phGainDec);
246     *phGainDec = NULL;
247   }
248 
249   return DE_OK;
250 }
251 
252 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)253 drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec,
254                               HANDLE_UNI_DRC_GAIN hUniDrcGain,
255                               const FIXP_DBL loudnessNormalizationGainDb,
256                               const FIXP_SGL boost, const FIXP_SGL compress) {
257   DRC_ERROR err = DE_OK;
258   int a, c;
259 
260   /* lnbPointer is the index on the most recent node buffer */
261   hGainDec->drcGainBuffers.lnbPointer++;
262   if (hGainDec->drcGainBuffers.lnbPointer >= NUM_LNB_FRAMES)
263     hGainDec->drcGainBuffers.lnbPointer = 0;
264 
265   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
266     /* prepare gain interpolation of sequences used by copying and modifying
267      * nodes in node buffers */
268     err = prepareDrcGain(hGainDec, hUniDrcGain, compress, boost,
269                          loudnessNormalizationGainDb, a);
270     if (err) return err;
271   }
272 
273   for (a = 0; a < MAX_ACTIVE_DRCS; a++) {
274     for (c = 0; c < 8; c++) {
275       hGainDec->activeDrc[a]
276           .lnbIndexForChannel[c][hGainDec->drcGainBuffers.lnbPointer] =
277           -1; /* "no DRC processing" */
278     }
279     hGainDec->activeDrc[a].subbandGainsReady = 0;
280   }
281 
282   for (c = 0; c < 8; c++) {
283     hGainDec->drcGainBuffers
284         .channelGain[c][hGainDec->drcGainBuffers.lnbPointer] =
285         FL2FXCONST_DBL(1.0f / (float)(1 << 8));
286   }
287 
288   return err;
289 }
290 
291 /* create gain sequence out of gain sequences of last frame for concealment and
292  * flushing */
293 DRC_ERROR
drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_UNI_DRC_GAIN hUniDrcGain)294 drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
295                            HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
296                            HANDLE_UNI_DRC_GAIN hUniDrcGain) {
297   int seq, gainSequenceCount;
298   DRC_COEFFICIENTS_UNI_DRC* pCoef =
299       selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
300   if (pCoef && pCoef->gainSequenceCount) {
301     gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
302   } else {
303     gainSequenceCount = 1;
304   }
305 
306   for (seq = 0; seq < gainSequenceCount; seq++) {
307     int lastNodeIndex = 0;
308     FIXP_SGL lastGainDb = (FIXP_SGL)0;
309 
310     lastNodeIndex = hUniDrcGain->nNodes[seq] - 1;
311     if ((lastNodeIndex >= 0) && (lastNodeIndex < 16)) {
312       lastGainDb = hUniDrcGain->gainNode[seq][lastNodeIndex].gainDb;
313     }
314 
315     hUniDrcGain->nNodes[seq] = 1;
316     if (lastGainDb > (FIXP_SGL)0) {
317       hUniDrcGain->gainNode[seq][0].gainDb =
318           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.9f), lastGainDb));
319     } else {
320       hUniDrcGain->gainNode[seq][0].gainDb =
321           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.98f), lastGainDb));
322     }
323     hUniDrcGain->gainNode[seq][0].time = hGainDec->frameSize - 1;
324   }
325   return DE_OK;
326 }
327 
drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,const int numChannels,const int frameSize,const FIXP_DBL * channelGainDb,const int audioBufferChannelOffset,FIXP_DBL * audioBuffer)328 void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
329                                         const int numChannels,
330                                         const int frameSize,
331                                         const FIXP_DBL* channelGainDb,
332                                         const int audioBufferChannelOffset,
333                                         FIXP_DBL* audioBuffer) {
334   int c, i;
335 
336   if (hGainDec->channelGainActiveDrcIndex >= 0) {
337     /* channel gains will be applied in drcDec_GainDecoder_ProcessTimeDomain or
338      * drcDec_GainDecoder_ProcessSubbandDomain, respectively. */
339     _setChannelGains(hGainDec, numChannels, channelGainDb);
340 
341     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
342       DRC_GAIN_BUFFERS* pDrcGainBuffers = &hGainDec->drcGainBuffers;
343       for (c = 0; c < numChannels; c++) {
344         for (i = 0; i < NUM_LNB_FRAMES; i++) {
345           pDrcGainBuffers->channelGain[c][i] = hGainDec->channelGain[c];
346         }
347       }
348       hGainDec->status = 1;
349     }
350   } else {
351     /* smooth and apply channel gains */
352     FIXP_DBL prevChannelGain[8];
353     for (c = 0; c < numChannels; c++) {
354       prevChannelGain[c] = hGainDec->channelGain[c];
355     }
356 
357     _setChannelGains(hGainDec, numChannels, channelGainDb);
358 
359     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
360       for (c = 0; c < numChannels; c++)
361         prevChannelGain[c] = hGainDec->channelGain[c];
362       hGainDec->status = 1;
363     }
364 
365     for (c = 0; c < numChannels; c++) {
366       INT n_min = fMin(fMin(CntLeadingZeros(prevChannelGain[c]),
367                             CntLeadingZeros(hGainDec->channelGain[c])) -
368                            1,
369                        9);
370       FIXP_DBL gain = prevChannelGain[c] << n_min;
371       FIXP_DBL stepsize = ((hGainDec->channelGain[c] << n_min) - gain);
372       if (stepsize != (FIXP_DBL)0) {
373         if (frameSize == 1024)
374           stepsize = stepsize >> 10;
375         else
376           stepsize = (LONG)stepsize / frameSize;
377       }
378       n_min = 9 - n_min;
379 #ifdef FUNCTION_drcDec_GainDecoder_SetChannelGains_func1
380       drcDec_GainDecoder_SetChannelGains_func1(audioBuffer, gain, stepsize,
381                                                n_min, frameSize);
382 #else
383       for (i = 0; i < frameSize; i++) {
384         audioBuffer[i] = fMultDiv2(audioBuffer[i], gain) << n_min;
385         gain += stepsize;
386       }
387 #endif
388       audioBuffer += audioBufferChannelOffset;
389     }
390   }
391 }
392 
393 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)394 drcDec_GainDecoder_ProcessTimeDomain(
395     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
396     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
397     const int drcChannelOffset, const int numChannelsProcessed,
398     const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer) {
399   DRC_ERROR err = DE_OK;
400   int a;
401 
402   if (!hGainDec->timeDomainSupported) {
403     return DE_NOT_OK;
404   }
405 
406   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
407     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
408 
409     /* Apply DRC */
410     err = processDrcTime(hGainDec, a, delaySamples, channelOffset,
411                          drcChannelOffset, numChannelsProcessed,
412                          timeDataChannelOffset, audioIOBuffer);
413     if (err) return err;
414   }
415 
416   return err;
417 }
418 
419 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[])420 drcDec_GainDecoder_ProcessSubbandDomain(
421     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
422     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
423     const int drcChannelOffset, const int numChannelsProcessed,
424     const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[],
425     FIXP_DBL* audioIOBufferImag[]) {
426   DRC_ERROR err = DE_OK;
427   int a;
428 
429   if (hGainDec->subbandDomainSupported == SDM_OFF) {
430     return DE_NOT_OK;
431   }
432 
433   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
434     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
435 
436     /* Apply DRC */
437     err = processDrcSubband(hGainDec, a, delaySamples, channelOffset,
438                             drcChannelOffset, numChannelsProcessed,
439                             processSingleTimeslot, audioIOBufferReal,
440                             audioIOBufferImag);
441     if (err) return err;
442   }
443 
444   return err;
445 }
446 
447 DRC_ERROR
drcDec_GainDecoder_SetLoudnessNormalizationGainDb(HANDLE_DRC_GAIN_DECODER hGainDec,FIXP_DBL loudnessNormalizationGainDb)448 drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
449     HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb) {
450   hGainDec->loudnessNormalisationGainDb = loudnessNormalizationGainDb;
451 
452   return DE_OK;
453 }
454 
drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec)455 int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec) {
456   if (hGainDec == NULL) return -1;
457 
458   return hGainDec->frameSize;
459 }
460 
drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec)461 int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec) {
462   if (hGainDec == NULL) return -1;
463 
464   return hGainDec->deltaTminDefault;
465 }
466