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