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