• 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 == NULL) return DE_OK;
301 
302   gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
303 
304   for (seq = 0; seq < gainSequenceCount; seq++) {
305     int lastNodeIndex = 0;
306     FIXP_SGL lastGainDb = (FIXP_SGL)0;
307 
308     lastNodeIndex = hUniDrcGain->nNodes[seq] - 1;
309     if ((lastNodeIndex >= 0) && (lastNodeIndex < 16)) {
310       lastGainDb = hUniDrcGain->gainNode[seq][lastNodeIndex].gainDb;
311     }
312 
313     hUniDrcGain->nNodes[seq] = 1;
314     if (lastGainDb > (FIXP_SGL)0) {
315       hUniDrcGain->gainNode[seq][0].gainDb =
316           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.9f), lastGainDb));
317     } else {
318       hUniDrcGain->gainNode[seq][0].gainDb =
319           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.98f), lastGainDb));
320     }
321     hUniDrcGain->gainNode[seq][0].time = hGainDec->frameSize - 1;
322   }
323   return DE_OK;
324 }
325 
drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,const int numChannels,const int frameSize,const FIXP_DBL * channelGainDb,const int audioBufferChannelOffset,FIXP_DBL * audioBuffer)326 void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
327                                         const int numChannels,
328                                         const int frameSize,
329                                         const FIXP_DBL* channelGainDb,
330                                         const int audioBufferChannelOffset,
331                                         FIXP_DBL* audioBuffer) {
332   int c, i;
333 
334   if (hGainDec->channelGainActiveDrcIndex >= 0) {
335     /* channel gains will be applied in drcDec_GainDecoder_ProcessTimeDomain or
336      * drcDec_GainDecoder_ProcessSubbandDomain, respectively. */
337     _setChannelGains(hGainDec, numChannels, channelGainDb);
338 
339     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
340       DRC_GAIN_BUFFERS* pDrcGainBuffers = &hGainDec->drcGainBuffers;
341       for (c = 0; c < numChannels; c++) {
342         for (i = 0; i < NUM_LNB_FRAMES; i++) {
343           pDrcGainBuffers->channelGain[c][i] = hGainDec->channelGain[c];
344         }
345       }
346       hGainDec->status = 1;
347     }
348   } else {
349     /* smooth and apply channel gains */
350     FIXP_DBL prevChannelGain[8];
351     for (c = 0; c < numChannels; c++) {
352       prevChannelGain[c] = hGainDec->channelGain[c];
353     }
354 
355     _setChannelGains(hGainDec, numChannels, channelGainDb);
356 
357     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
358       for (c = 0; c < numChannels; c++)
359         prevChannelGain[c] = hGainDec->channelGain[c];
360       hGainDec->status = 1;
361     }
362 
363     for (c = 0; c < numChannels; c++) {
364       INT n_min = fMin(fMin(CntLeadingZeros(prevChannelGain[c]),
365                             CntLeadingZeros(hGainDec->channelGain[c])) -
366                            1,
367                        9);
368       FIXP_DBL gain = prevChannelGain[c] << n_min;
369       FIXP_DBL stepsize = ((hGainDec->channelGain[c] << n_min) - gain);
370       if (stepsize != (FIXP_DBL)0) {
371         if (frameSize == 1024)
372           stepsize = stepsize >> 10;
373         else
374           stepsize = (LONG)stepsize / frameSize;
375       }
376       n_min = 9 - n_min;
377 #ifdef FUNCTION_drcDec_GainDecoder_SetChannelGains_func1
378       drcDec_GainDecoder_SetChannelGains_func1(audioBuffer, gain, stepsize,
379                                                n_min, frameSize);
380 #else
381       for (i = 0; i < frameSize; i++) {
382         audioBuffer[i] = fMultDiv2(audioBuffer[i], gain) << n_min;
383         gain += stepsize;
384       }
385 #endif
386       audioBuffer += audioBufferChannelOffset;
387     }
388   }
389 }
390 
391 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)392 drcDec_GainDecoder_ProcessTimeDomain(
393     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
394     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
395     const int drcChannelOffset, const int numChannelsProcessed,
396     const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer) {
397   DRC_ERROR err = DE_OK;
398   int a;
399 
400   if (!hGainDec->timeDomainSupported) {
401     return DE_NOT_OK;
402   }
403 
404   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
405     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
406 
407     /* Apply DRC */
408     err = processDrcTime(hGainDec, a, delaySamples, channelOffset,
409                          drcChannelOffset, numChannelsProcessed,
410                          timeDataChannelOffset, audioIOBuffer);
411     if (err) return err;
412   }
413 
414   return err;
415 }
416 
417 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[])418 drcDec_GainDecoder_ProcessSubbandDomain(
419     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
420     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
421     const int drcChannelOffset, const int numChannelsProcessed,
422     const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[],
423     FIXP_DBL* audioIOBufferImag[]) {
424   DRC_ERROR err = DE_OK;
425   int a;
426 
427   if (hGainDec->subbandDomainSupported == SDM_OFF) {
428     return DE_NOT_OK;
429   }
430 
431   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
432     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
433 
434     /* Apply DRC */
435     err = processDrcSubband(hGainDec, a, delaySamples, channelOffset,
436                             drcChannelOffset, numChannelsProcessed,
437                             processSingleTimeslot, audioIOBufferReal,
438                             audioIOBufferImag);
439     if (err) return err;
440   }
441 
442   return err;
443 }
444 
445 DRC_ERROR
drcDec_GainDecoder_SetLoudnessNormalizationGainDb(HANDLE_DRC_GAIN_DECODER hGainDec,FIXP_DBL loudnessNormalizationGainDb)446 drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
447     HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb) {
448   hGainDec->loudnessNormalisationGainDb = loudnessNormalizationGainDb;
449 
450   return DE_OK;
451 }
452 
drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec)453 int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec) {
454   if (hGainDec == NULL) return -1;
455 
456   return hGainDec->frameSize;
457 }
458 
drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec)459 int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec) {
460   if (hGainDec == NULL) return -1;
461 
462   return hGainDec->deltaTminDefault;
463 }
464