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