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): Bernhard Neugebauer
98
99 Description: MPEG-D DRC Decoder
100
101 *******************************************************************************/
102
103 #include "drcDec_reader.h"
104 #include "drcDec_gainDecoder.h"
105 #include "FDK_drcDecLib.h"
106
107 #include "drcDec_selectionProcess.h"
108 #include "drcDec_tools.h"
109
110 /* Decoder library info */
111 #define DRCDEC_LIB_VL0 2
112 #define DRCDEC_LIB_VL1 1
113 #define DRCDEC_LIB_VL2 0
114 #define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib"
115 #ifdef __ANDROID__
116 #define DRCDEC_LIB_BUILD_DATE ""
117 #define DRCDEC_LIB_BUILD_TIME ""
118 #else
119 #define DRCDEC_LIB_BUILD_DATE __DATE__
120 #define DRCDEC_LIB_BUILD_TIME __TIME__
121 #endif
122
123 typedef enum {
124 DRC_DEC_NOT_INITIALIZED = 0,
125 DRC_DEC_INITIALIZED,
126 DRC_DEC_NEW_GAIN_PAYLOAD,
127 DRC_DEC_INTERPOLATION_PREPARED
128 } DRC_DEC_STATUS;
129
130 struct s_drc_decoder {
131 DRC_DEC_CODEC_MODE codecMode;
132 DRC_DEC_FUNCTIONAL_RANGE functionalRange;
133 DRC_DEC_STATUS status;
134
135 /* handles of submodules */
136 HANDLE_DRC_GAIN_DECODER hGainDec;
137 HANDLE_DRC_SELECTION_PROCESS hSelectionProc;
138 int selProcInputDiff;
139
140 /* data structs */
141 UNI_DRC_CONFIG uniDrcConfig;
142 LOUDNESS_INFO_SET loudnessInfoSet;
143 UNI_DRC_GAIN uniDrcGain;
144
145 SEL_PROC_OUTPUT selProcOutput;
146 } DRC_DECODER;
147
isResetNeeded(HANDLE_DRC_DECODER hDrcDec,const SEL_PROC_OUTPUT oldSelProcOutput)148 static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec,
149 const SEL_PROC_OUTPUT oldSelProcOutput) {
150 int i, resetNeeded = 0;
151
152 if (hDrcDec->selProcOutput.numSelectedDrcSets !=
153 oldSelProcOutput.numSelectedDrcSets) {
154 resetNeeded = 1;
155 } else {
156 for (i = 0; i < hDrcDec->selProcOutput.numSelectedDrcSets; i++) {
157 if (hDrcDec->selProcOutput.selectedDrcSetIds[i] !=
158 oldSelProcOutput.selectedDrcSetIds[i])
159 resetNeeded = 1;
160 if (hDrcDec->selProcOutput.selectedDownmixIds[i] !=
161 oldSelProcOutput.selectedDownmixIds[i])
162 resetNeeded = 1;
163 }
164 }
165
166 if (hDrcDec->selProcOutput.boost != oldSelProcOutput.boost) resetNeeded = 1;
167 if (hDrcDec->selProcOutput.compress != oldSelProcOutput.compress)
168 resetNeeded = 1;
169
170 /* Note: Changes in downmix matrix are not caught, as they don't affect the
171 * DRC gain decoder */
172
173 return resetNeeded;
174 }
175
startSelectionProcess(HANDLE_DRC_DECODER hDrcDec)176 static void startSelectionProcess(HANDLE_DRC_DECODER hDrcDec) {
177 int uniDrcConfigHasChanged = 0;
178 SEL_PROC_OUTPUT oldSelProcOutput = hDrcDec->selProcOutput;
179
180 if (!hDrcDec->status) return;
181
182 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
183 uniDrcConfigHasChanged = hDrcDec->uniDrcConfig.diff;
184 if (hDrcDec->uniDrcConfig.diff || hDrcDec->loudnessInfoSet.diff ||
185 hDrcDec->selProcInputDiff) {
186 /* in case of an error, signal that selection process was not successful
187 */
188 hDrcDec->selProcOutput.numSelectedDrcSets = 0;
189
190 drcDec_SelectionProcess_Process(
191 hDrcDec->hSelectionProc, &(hDrcDec->uniDrcConfig),
192 &(hDrcDec->loudnessInfoSet), &(hDrcDec->selProcOutput));
193
194 hDrcDec->selProcInputDiff = 0;
195 hDrcDec->uniDrcConfig.diff = 0;
196 hDrcDec->loudnessInfoSet.diff = 0;
197 }
198 }
199
200 if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
201 if (isResetNeeded(hDrcDec, oldSelProcOutput) || uniDrcConfigHasChanged) {
202 drcDec_GainDecoder_Config(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig),
203 hDrcDec->selProcOutput.numSelectedDrcSets,
204 hDrcDec->selProcOutput.selectedDrcSetIds,
205 hDrcDec->selProcOutput.selectedDownmixIds);
206 }
207 }
208 }
209
210 DRC_DEC_ERROR
FDK_drcDec_Open(HANDLE_DRC_DECODER * phDrcDec,const DRC_DEC_FUNCTIONAL_RANGE functionalRange)211 FDK_drcDec_Open(HANDLE_DRC_DECODER* phDrcDec,
212 const DRC_DEC_FUNCTIONAL_RANGE functionalRange) {
213 DRC_ERROR dErr = DE_OK;
214 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
215 HANDLE_DRC_DECODER hDrcDec;
216
217 *phDrcDec = (HANDLE_DRC_DECODER)FDKcalloc(1, sizeof(DRC_DECODER));
218 if (!*phDrcDec) return DRC_DEC_OUT_OF_MEMORY;
219 hDrcDec = *phDrcDec;
220
221 hDrcDec->functionalRange = functionalRange;
222
223 hDrcDec->status = DRC_DEC_NOT_INITIALIZED;
224 hDrcDec->codecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
225
226 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
227 sErr = drcDec_SelectionProcess_Create(&(hDrcDec->hSelectionProc));
228 if (sErr) return DRC_DEC_OUT_OF_MEMORY;
229 sErr = drcDec_SelectionProcess_Init(hDrcDec->hSelectionProc);
230 if (sErr) return DRC_DEC_NOT_OK;
231 hDrcDec->selProcInputDiff = 1;
232 }
233
234 if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
235 dErr = drcDec_GainDecoder_Open(&(hDrcDec->hGainDec));
236 if (dErr) return DRC_DEC_OUT_OF_MEMORY;
237 }
238
239 return DRC_DEC_OK;
240 }
241
242 DRC_DEC_ERROR
FDK_drcDec_SetCodecMode(HANDLE_DRC_DECODER hDrcDec,const DRC_DEC_CODEC_MODE codecMode)243 FDK_drcDec_SetCodecMode(HANDLE_DRC_DECODER hDrcDec,
244 const DRC_DEC_CODEC_MODE codecMode) {
245 DRC_ERROR dErr = DE_OK;
246 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
247
248 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
249
250 if (hDrcDec->codecMode ==
251 DRC_DEC_CODEC_MODE_UNDEFINED) { /* Set codec mode, if it is set for the
252 first time */
253 hDrcDec->codecMode = codecMode;
254
255 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
256 sErr = drcDec_SelectionProcess_SetCodecMode(
257 hDrcDec->hSelectionProc, (SEL_PROC_CODEC_MODE)codecMode);
258 if (sErr) return DRC_DEC_NOT_OK;
259 hDrcDec->selProcInputDiff = 1;
260 }
261
262 if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
263 DELAY_MODE delayMode;
264 int timeDomainSupported;
265 SUBBAND_DOMAIN_MODE subbandDomainSupported;
266
267 switch (hDrcDec->codecMode) {
268 case DRC_DEC_MPEG_4_AAC:
269 case DRC_DEC_MPEG_D_USAC:
270 case DRC_DEC_MPEG_H_3DA:
271 default:
272 delayMode = DM_REGULAR_DELAY;
273 }
274
275 switch (hDrcDec->codecMode) {
276 case DRC_DEC_MPEG_4_AAC:
277 case DRC_DEC_MPEG_D_USAC:
278 timeDomainSupported = 1;
279 subbandDomainSupported = SDM_OFF;
280 break;
281 case DRC_DEC_MPEG_H_3DA:
282 timeDomainSupported = 1;
283 subbandDomainSupported = SDM_STFT256;
284 break;
285
286 case DRC_DEC_TEST_TIME_DOMAIN:
287 timeDomainSupported = 1;
288 subbandDomainSupported = SDM_OFF;
289 break;
290 case DRC_DEC_TEST_QMF_DOMAIN:
291 timeDomainSupported = 0;
292 subbandDomainSupported = SDM_QMF64;
293 break;
294 case DRC_DEC_TEST_STFT_DOMAIN:
295 timeDomainSupported = 0;
296 subbandDomainSupported = SDM_STFT256;
297 break;
298
299 default:
300 timeDomainSupported = 0;
301 subbandDomainSupported = SDM_OFF;
302 }
303
304 dErr = drcDec_GainDecoder_SetCodecDependentParameters(
305 hDrcDec->hGainDec, delayMode, timeDomainSupported,
306 subbandDomainSupported);
307 if (dErr) return DRC_DEC_NOT_OK;
308 }
309 }
310
311 /* Don't allow changing codecMode if it has already been set. */
312 if (hDrcDec->codecMode != codecMode) return DRC_DEC_NOT_OK;
313
314 return DRC_DEC_OK;
315 }
316
317 DRC_DEC_ERROR
FDK_drcDec_Init(HANDLE_DRC_DECODER hDrcDec,const int frameSize,const int sampleRate,const int baseChannelCount)318 FDK_drcDec_Init(HANDLE_DRC_DECODER hDrcDec, const int frameSize,
319 const int sampleRate, const int baseChannelCount) {
320 DRC_ERROR dErr = DE_OK;
321 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
322
323 if (hDrcDec == NULL || frameSize == 0 || sampleRate == 0 ||
324 baseChannelCount == 0)
325 return DRC_DEC_OK; /* return without doing anything */
326
327 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
328 sErr = drcDec_SelectionProcess_SetParam(
329 hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT,
330 (FIXP_DBL)baseChannelCount, &(hDrcDec->selProcInputDiff));
331 if (sErr) return DRC_DEC_NOT_OK;
332 sErr = drcDec_SelectionProcess_SetParam(
333 hDrcDec->hSelectionProc, SEL_PROC_SAMPLE_RATE, (FIXP_DBL)sampleRate,
334 &(hDrcDec->selProcInputDiff));
335 if (sErr) return DRC_DEC_NOT_OK;
336 }
337
338 if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
339 dErr = drcDec_GainDecoder_SetParam(hDrcDec->hGainDec, GAIN_DEC_FRAME_SIZE,
340 frameSize);
341 if (dErr) return DRC_DEC_NOT_OK;
342 dErr = drcDec_GainDecoder_SetParam(hDrcDec->hGainDec, GAIN_DEC_SAMPLE_RATE,
343 sampleRate);
344 if (dErr) return DRC_DEC_NOT_OK;
345 dErr = drcDec_GainDecoder_Init(hDrcDec->hGainDec);
346 if (dErr) return DRC_DEC_NOT_OK;
347 }
348
349 hDrcDec->status = DRC_DEC_INITIALIZED;
350
351 startSelectionProcess(hDrcDec);
352
353 return DRC_DEC_OK;
354 }
355
356 DRC_DEC_ERROR
FDK_drcDec_Close(HANDLE_DRC_DECODER * phDrcDec)357 FDK_drcDec_Close(HANDLE_DRC_DECODER* phDrcDec) {
358 HANDLE_DRC_DECODER hDrcDec;
359
360 if (phDrcDec == NULL) {
361 return DRC_DEC_OK;
362 }
363
364 hDrcDec = *phDrcDec;
365
366 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
367
368 if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
369 drcDec_GainDecoder_Close(&(hDrcDec->hGainDec));
370 }
371
372 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
373 drcDec_SelectionProcess_Delete(&(hDrcDec->hSelectionProc));
374 }
375
376 FDKfree(*phDrcDec);
377 *phDrcDec = NULL;
378
379 return DRC_DEC_OK;
380 }
381
382 DRC_DEC_ERROR
FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec,const DRC_DEC_USERPARAM requestType,const FIXP_DBL requestValue)383 FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec,
384 const DRC_DEC_USERPARAM requestType,
385 const FIXP_DBL requestValue) {
386 DRC_ERROR dErr = DE_OK;
387 DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
388 int invalidParameter = 0;
389
390 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
391
392 if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
393 switch (requestType) {
394 case DRC_DEC_SAMPLE_RATE:
395 dErr = drcDec_GainDecoder_SetParam(
396 hDrcDec->hGainDec, GAIN_DEC_SAMPLE_RATE, (int)requestValue);
397 if (dErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
398 break;
399 case DRC_DEC_FRAME_SIZE:
400 dErr = drcDec_GainDecoder_SetParam(
401 hDrcDec->hGainDec, GAIN_DEC_FRAME_SIZE, (int)requestValue);
402 if (dErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
403 break;
404 default:
405 invalidParameter |= DRC_DEC_GAIN;
406 }
407 }
408
409 if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
410 switch (requestType) {
411 case DRC_DEC_BOOST:
412 sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
413 SEL_PROC_BOOST, requestValue,
414 &(hDrcDec->selProcInputDiff));
415 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
416 break;
417 case DRC_DEC_COMPRESS:
418 sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
419 SEL_PROC_COMPRESS, requestValue,
420 &(hDrcDec->selProcInputDiff));
421 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
422 break;
423 case DRC_DEC_LOUDNESS_NORMALIZATION_ON:
424 sErr = drcDec_SelectionProcess_SetParam(
425 hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON,
426 requestValue, &(hDrcDec->selProcInputDiff));
427 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
428 break;
429 case DRC_DEC_TARGET_LOUDNESS:
430 sErr = drcDec_SelectionProcess_SetParam(
431 hDrcDec->hSelectionProc, SEL_PROC_TARGET_LOUDNESS, requestValue,
432 &(hDrcDec->selProcInputDiff));
433 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
434 break;
435 case DRC_DEC_EFFECT_TYPE:
436 sErr = drcDec_SelectionProcess_SetParam(
437 hDrcDec->hSelectionProc, SEL_PROC_EFFECT_TYPE, requestValue,
438 &(hDrcDec->selProcInputDiff));
439 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
440 break;
441 case DRC_DEC_DOWNMIX_ID:
442 sErr = drcDec_SelectionProcess_SetParam(
443 hDrcDec->hSelectionProc, SEL_PROC_DOWNMIX_ID, requestValue,
444 &(hDrcDec->selProcInputDiff));
445 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
446 break;
447 case DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED:
448 sErr = drcDec_SelectionProcess_SetParam(
449 hDrcDec->hSelectionProc, SEL_PROC_TARGET_CHANNEL_COUNT,
450 requestValue, &(hDrcDec->selProcInputDiff));
451 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
452 break;
453 case DRC_DEC_BASE_CHANNEL_COUNT:
454 sErr = drcDec_SelectionProcess_SetParam(
455 hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT, requestValue,
456 &(hDrcDec->selProcInputDiff));
457 if (sErr) return DRC_DEC_NOT_OK;
458 break;
459 case DRC_DEC_LOUDNESS_MEASUREMENT_METHOD:
460 sErr = drcDec_SelectionProcess_SetParam(
461 hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_MEASUREMENT_METHOD,
462 requestValue, &(hDrcDec->selProcInputDiff));
463 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
464 break;
465 case DRC_DEC_ALBUM_MODE:
466 sErr = drcDec_SelectionProcess_SetParam(
467 hDrcDec->hSelectionProc, SEL_PROC_ALBUM_MODE, requestValue,
468 &(hDrcDec->selProcInputDiff));
469 if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
470 break;
471 default:
472 invalidParameter |= DRC_DEC_SELECTION;
473 }
474 }
475
476 if (invalidParameter == hDrcDec->functionalRange)
477 return DRC_DEC_INVALID_PARAM;
478
479 /* All parameters need a new start of the selection process */
480 startSelectionProcess(hDrcDec);
481
482 return DRC_DEC_OK;
483 }
484
FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,const DRC_DEC_USERPARAM requestType)485 LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
486 const DRC_DEC_USERPARAM requestType) {
487 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
488
489 switch (requestType) {
490 case DRC_DEC_BOOST:
491 return (LONG)hDrcDec->selProcOutput.boost;
492 case DRC_DEC_COMPRESS:
493 return (LONG)hDrcDec->selProcOutput.compress;
494 case DRC_DEC_IS_MULTIBAND_DRC_1:
495 return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0);
496 case DRC_DEC_IS_MULTIBAND_DRC_2:
497 return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0x7F);
498 case DRC_DEC_IS_ACTIVE: {
499 /* MPEG-D DRC is considered active (and overrides MPEG-4 DRC), if
500 * uniDrc payload is present (loudnessInfoSet and/or uniDrcConfig)
501 * at least one of DRC and Loudness Control is switched on */
502 int drcOn = drcDec_SelectionProcess_GetParam(
503 hDrcDec->hSelectionProc, SEL_PROC_DYNAMIC_RANGE_CONTROL_ON);
504 int lnOn = drcDec_SelectionProcess_GetParam(
505 hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON);
506 int uniDrcPayloadPresent =
507 (hDrcDec->loudnessInfoSet.loudnessInfoCount > 0);
508 uniDrcPayloadPresent |=
509 (hDrcDec->loudnessInfoSet.loudnessInfoAlbumCount > 0);
510 uniDrcPayloadPresent |=
511 (hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount > 0);
512 uniDrcPayloadPresent |=
513 (hDrcDec->uniDrcConfig.downmixInstructionsCount > 0);
514 return (LONG)(uniDrcPayloadPresent && (drcOn || lnOn));
515 }
516 case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
517 return (LONG)hDrcDec->selProcOutput.targetChannelCount;
518 default:
519 return 0;
520 }
521 }
522
523 DRC_DEC_ERROR
FDK_drcDec_SetInterfaceParameters(HANDLE_DRC_DECODER hDrcDec,HANDLE_UNI_DRC_INTERFACE hUniDrcInterface)524 FDK_drcDec_SetInterfaceParameters(HANDLE_DRC_DECODER hDrcDec,
525 HANDLE_UNI_DRC_INTERFACE hUniDrcInterface) {
526 return DRC_DEC_UNSUPPORTED_FUNCTION;
527 }
528
529 DRC_DEC_ERROR
FDK_drcDec_SetSelectionProcessMpeghParameters_simple(HANDLE_DRC_DECODER hDrcDec,const int groupPresetIdRequested,const int numGroupIdsRequested,const int * groupIdsRequested)530 FDK_drcDec_SetSelectionProcessMpeghParameters_simple(
531 HANDLE_DRC_DECODER hDrcDec, const int groupPresetIdRequested,
532 const int numGroupIdsRequested, const int* groupIdsRequested) {
533 return DRC_DEC_UNSUPPORTED_FUNCTION;
534 }
535
536 DRC_DEC_ERROR
FDK_drcDec_SetDownmixInstructions(HANDLE_DRC_DECODER hDrcDec,const int numDownmixId,const int * downmixId,const int * targetLayout,const int * targetChannelCount)537 FDK_drcDec_SetDownmixInstructions(HANDLE_DRC_DECODER hDrcDec,
538 const int numDownmixId, const int* downmixId,
539 const int* targetLayout,
540 const int* targetChannelCount) {
541 return DRC_DEC_UNSUPPORTED_FUNCTION;
542 }
543
FDK_drcDec_SetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec,HANDLE_SEL_PROC_OUTPUT hSelProcOutput)544 void FDK_drcDec_SetSelectionProcessOutput(
545 HANDLE_DRC_DECODER hDrcDec, HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {}
546
547 HANDLE_SEL_PROC_OUTPUT
FDK_drcDec_GetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec)548 FDK_drcDec_GetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec) {
549 if (hDrcDec == NULL) return NULL;
550
551 return &(hDrcDec->selProcOutput);
552 }
553
554 LONG /* FIXP_DBL, e = 7 */
FDK_drcDec_GetGroupLoudness(HANDLE_SEL_PROC_OUTPUT hSelProcOutput,const int groupID,int * groupLoudnessAvailable)555 FDK_drcDec_GetGroupLoudness(HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
556 const int groupID, int* groupLoudnessAvailable) {
557 return (LONG)0;
558 }
559
FDK_drcDec_SetChannelGains(HANDLE_DRC_DECODER hDrcDec,const int numChannels,const int frameSize,FIXP_DBL * channelGainDb,FIXP_DBL * audioBuffer,const int audioBufferChannelOffset)560 void FDK_drcDec_SetChannelGains(HANDLE_DRC_DECODER hDrcDec,
561 const int numChannels, const int frameSize,
562 FIXP_DBL* channelGainDb, FIXP_DBL* audioBuffer,
563 const int audioBufferChannelOffset) {
564 int err;
565
566 if (hDrcDec == NULL) return;
567
568 err = drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
569 hDrcDec->hGainDec, hDrcDec->selProcOutput.loudnessNormalizationGainDb);
570 if (err) return;
571
572 drcDec_GainDecoder_SetChannelGains(hDrcDec->hGainDec, numChannels, frameSize,
573 channelGainDb, audioBufferChannelOffset,
574 audioBuffer);
575 }
576
577 DRC_DEC_ERROR
FDK_drcDec_ReadUniDrcConfig(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)578 FDK_drcDec_ReadUniDrcConfig(HANDLE_DRC_DECODER hDrcDec,
579 HANDLE_FDK_BITSTREAM hBitstream) {
580 DRC_ERROR dErr = DE_OK;
581
582 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
583
584 if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) {
585 dErr = drcDec_readUniDrcConfig(hBitstream, &(hDrcDec->uniDrcConfig));
586 } else
587 return DRC_DEC_NOT_OK;
588
589 if (dErr) {
590 /* clear config, if parsing error occured */
591 FDKmemclear(&hDrcDec->uniDrcConfig, sizeof(hDrcDec->uniDrcConfig));
592 hDrcDec->uniDrcConfig.diff = 1;
593 }
594
595 startSelectionProcess(hDrcDec);
596
597 return DRC_DEC_OK;
598 }
599
600 DRC_DEC_ERROR
FDK_drcDec_ReadDownmixInstructions_Box(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)601 FDK_drcDec_ReadDownmixInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
602 HANDLE_FDK_BITSTREAM hBitstream) {
603 DRC_ERROR dErr = DE_OK;
604
605 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
606
607 return DRC_DEC_NOT_OK;
608
609 if (dErr) {
610 /* clear config, if parsing error occurred */
611 FDKmemclear(&hDrcDec->uniDrcConfig.downmixInstructions,
612 sizeof(hDrcDec->uniDrcConfig.downmixInstructions));
613 hDrcDec->uniDrcConfig.downmixInstructionsCount = 0;
614 hDrcDec->uniDrcConfig.downmixInstructionsCountV0 = 0;
615 hDrcDec->uniDrcConfig.downmixInstructionsCountV1 = 0;
616 hDrcDec->uniDrcConfig.diff = 1;
617 }
618
619 startSelectionProcess(hDrcDec);
620
621 return DRC_DEC_OK;
622 }
623
624 DRC_DEC_ERROR
FDK_drcDec_ReadUniDrcInstructions_Box(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)625 FDK_drcDec_ReadUniDrcInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
626 HANDLE_FDK_BITSTREAM hBitstream) {
627 DRC_ERROR dErr = DE_OK;
628
629 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
630
631 return DRC_DEC_NOT_OK;
632
633 if (dErr) {
634 /* clear config, if parsing error occurred */
635 FDKmemclear(&hDrcDec->uniDrcConfig.drcInstructionsUniDrc,
636 sizeof(hDrcDec->uniDrcConfig.drcInstructionsUniDrc));
637 hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount = 0;
638 hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV0 = 0;
639 hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV1 = 0;
640 hDrcDec->uniDrcConfig.diff = 1;
641 }
642
643 startSelectionProcess(hDrcDec);
644
645 return DRC_DEC_OK;
646 }
647
648 DRC_DEC_ERROR
FDK_drcDec_ReadUniDrcCoefficients_Box(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)649 FDK_drcDec_ReadUniDrcCoefficients_Box(HANDLE_DRC_DECODER hDrcDec,
650 HANDLE_FDK_BITSTREAM hBitstream) {
651 DRC_ERROR dErr = DE_OK;
652
653 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
654
655 return DRC_DEC_NOT_OK;
656
657 if (dErr) {
658 /* clear config, if parsing error occurred */
659 FDKmemclear(&hDrcDec->uniDrcConfig.drcCoefficientsUniDrc,
660 sizeof(hDrcDec->uniDrcConfig.drcCoefficientsUniDrc));
661 hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCount = 0;
662 hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV0 = 0;
663 hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV1 = 0;
664 hDrcDec->uniDrcConfig.diff = 1;
665 }
666
667 startSelectionProcess(hDrcDec);
668
669 return DRC_DEC_OK;
670 }
671
672 DRC_DEC_ERROR
FDK_drcDec_ReadLoudnessInfoSet(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)673 FDK_drcDec_ReadLoudnessInfoSet(HANDLE_DRC_DECODER hDrcDec,
674 HANDLE_FDK_BITSTREAM hBitstream) {
675 DRC_ERROR dErr = DE_OK;
676
677 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
678
679 if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) {
680 dErr = drcDec_readLoudnessInfoSet(hBitstream, &(hDrcDec->loudnessInfoSet));
681 } else
682 return DRC_DEC_NOT_OK;
683
684 if (dErr) {
685 /* clear config, if parsing error occurred */
686 FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet));
687 hDrcDec->loudnessInfoSet.diff = 1;
688 }
689
690 startSelectionProcess(hDrcDec);
691
692 return DRC_DEC_OK;
693 }
694
695 DRC_DEC_ERROR
FDK_drcDec_ReadLoudnessBox(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)696 FDK_drcDec_ReadLoudnessBox(HANDLE_DRC_DECODER hDrcDec,
697 HANDLE_FDK_BITSTREAM hBitstream) {
698 DRC_ERROR dErr = DE_OK;
699
700 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
701
702 return DRC_DEC_NOT_OK;
703
704 if (dErr) {
705 /* clear config, if parsing error occurred */
706 FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet));
707 hDrcDec->loudnessInfoSet.diff = 1;
708 }
709
710 startSelectionProcess(hDrcDec);
711
712 return DRC_DEC_OK;
713 }
714
715 DRC_DEC_ERROR
FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)716 FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,
717 HANDLE_FDK_BITSTREAM hBitstream) {
718 DRC_ERROR dErr = DE_OK;
719
720 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
721 if (!hDrcDec->status) {
722 return DRC_DEC_OK;
723 }
724
725 dErr = drcDec_readUniDrcGain(
726 hBitstream, &(hDrcDec->uniDrcConfig),
727 drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec),
728 drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec),
729 &(hDrcDec->uniDrcGain));
730 if (dErr) return DRC_DEC_NOT_OK;
731
732 hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
733
734 return DRC_DEC_OK;
735 }
736
737 DRC_DEC_ERROR
FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,HANDLE_FDK_BITSTREAM hBitstream)738 FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,
739 HANDLE_FDK_BITSTREAM hBitstream) {
740 DRC_ERROR dErr = DE_OK;
741
742 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
743 if (!hDrcDec->status) return DRC_DEC_NOT_READY;
744
745 dErr = drcDec_readUniDrc(
746 hBitstream, &(hDrcDec->uniDrcConfig), &(hDrcDec->loudnessInfoSet),
747 drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec),
748 drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec),
749 &(hDrcDec->uniDrcGain));
750
751 startSelectionProcess(hDrcDec);
752 if (dErr) return DRC_DEC_NOT_OK;
753
754 hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
755
756 return DRC_DEC_OK;
757 }
758
759 DRC_DEC_ERROR
FDK_drcDec_Preprocess(HANDLE_DRC_DECODER hDrcDec)760 FDK_drcDec_Preprocess(HANDLE_DRC_DECODER hDrcDec) {
761 DRC_ERROR dErr = DE_OK;
762
763 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
764 if (!hDrcDec->status) return DRC_DEC_NOT_READY;
765 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
766
767 if (hDrcDec->status != DRC_DEC_NEW_GAIN_PAYLOAD) {
768 /* no new gain payload was read, e.g. during concalment or flushing.
769 Generate DRC gains based on the stored DRC gains of last frames */
770 drcDec_GainDecoder_Conceal(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig),
771 &(hDrcDec->uniDrcGain));
772 }
773
774 dErr = drcDec_GainDecoder_Preprocess(
775 hDrcDec->hGainDec, &(hDrcDec->uniDrcGain),
776 hDrcDec->selProcOutput.loudnessNormalizationGainDb,
777 hDrcDec->selProcOutput.boost, hDrcDec->selProcOutput.compress);
778 if (dErr) return DRC_DEC_NOT_OK;
779 hDrcDec->status = DRC_DEC_INTERPOLATION_PREPARED;
780
781 return DRC_DEC_OK;
782 }
783
784 DRC_DEC_ERROR
FDK_drcDec_ProcessTime(HANDLE_DRC_DECODER hDrcDec,const int delaySamples,const DRC_DEC_LOCATION drcLocation,const int channelOffset,const int drcChannelOffset,const int numChannelsProcessed,FIXP_DBL * realBuffer,const int timeDataChannelOffset)785 FDK_drcDec_ProcessTime(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
786 const DRC_DEC_LOCATION drcLocation,
787 const int channelOffset, const int drcChannelOffset,
788 const int numChannelsProcessed, FIXP_DBL* realBuffer,
789 const int timeDataChannelOffset) {
790 DRC_ERROR dErr = DE_OK;
791
792 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
793 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
794 if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED)
795 return DRC_DEC_NOT_READY;
796
797 dErr = drcDec_GainDecoder_ProcessTimeDomain(
798 hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation,
799 channelOffset, drcChannelOffset, numChannelsProcessed,
800 timeDataChannelOffset, realBuffer);
801 if (dErr) return DRC_DEC_NOT_OK;
802
803 return DRC_DEC_OK;
804 }
805
806 DRC_DEC_ERROR
FDK_drcDec_ProcessFreq(HANDLE_DRC_DECODER hDrcDec,const int delaySamples,const DRC_DEC_LOCATION drcLocation,const int channelOffset,const int drcChannelOffset,const int numChannelsProcessed,const int processSingleTimeslot,FIXP_DBL ** realBuffer,FIXP_DBL ** imagBuffer)807 FDK_drcDec_ProcessFreq(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
808 const DRC_DEC_LOCATION drcLocation,
809 const int channelOffset, const int drcChannelOffset,
810 const int numChannelsProcessed,
811 const int processSingleTimeslot, FIXP_DBL** realBuffer,
812 FIXP_DBL** imagBuffer) {
813 DRC_ERROR dErr = DE_OK;
814
815 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
816 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
817 if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED)
818 return DRC_DEC_NOT_READY;
819
820 dErr = drcDec_GainDecoder_ProcessSubbandDomain(
821 hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation,
822 channelOffset, drcChannelOffset, numChannelsProcessed,
823 processSingleTimeslot, realBuffer, imagBuffer);
824 if (dErr) return DRC_DEC_NOT_OK;
825
826 return DRC_DEC_OK;
827 }
828
829 DRC_DEC_ERROR
FDK_drcDec_ApplyDownmix(HANDLE_DRC_DECODER hDrcDec,int * reverseInChannelMap,int * reverseOutChannelMap,FIXP_DBL * realBuffer,int * pNChannels)830 FDK_drcDec_ApplyDownmix(HANDLE_DRC_DECODER hDrcDec, int* reverseInChannelMap,
831 int* reverseOutChannelMap, FIXP_DBL* realBuffer,
832 int* pNChannels) {
833 SEL_PROC_OUTPUT* pSelProcOutput = &(hDrcDec->selProcOutput);
834 int baseChCnt = pSelProcOutput->baseChannelCount;
835 int targetChCnt = pSelProcOutput->targetChannelCount;
836 int frameSize, n, ic, oc;
837 FIXP_DBL tmp_out[8];
838 FIXP_DBL* audioChannels[8];
839
840 if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
841 if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
842
843 /* only downmix is performed here, no upmix.
844 Downmix is only performed if downmix coefficients are provided.
845 All other cases of downmix and upmix are treated by pcmDmx library. */
846 if (pSelProcOutput->downmixMatrixPresent == 0)
847 return DRC_DEC_OK; /* no downmix */
848 if (targetChCnt >= baseChCnt) return DRC_DEC_OK; /* downmix only */
849
850 /* sanity checks */
851 if (realBuffer == NULL) return DRC_DEC_NOT_OK;
852 if (reverseInChannelMap == NULL) return DRC_DEC_NOT_OK;
853 if (reverseOutChannelMap == NULL) return DRC_DEC_NOT_OK;
854 if (baseChCnt > 8) return DRC_DEC_NOT_OK;
855 if (baseChCnt != *pNChannels) return DRC_DEC_NOT_OK;
856 if (targetChCnt > 8) return DRC_DEC_NOT_OK;
857
858 frameSize = drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec);
859
860 for (ic = 0; ic < baseChCnt; ic++) {
861 audioChannels[ic] = &(realBuffer[ic * frameSize]);
862 }
863
864 /* in-place downmix */
865 for (n = 0; n < frameSize; n++) {
866 for (oc = 0; oc < targetChCnt; oc++) {
867 tmp_out[oc] = (FIXP_DBL)0;
868 for (ic = 0; ic < baseChCnt; ic++) {
869 tmp_out[oc] +=
870 fMultDiv2(audioChannels[ic][n],
871 pSelProcOutput->downmixMatrix[reverseInChannelMap[ic]]
872 [reverseOutChannelMap[oc]])
873 << 3;
874 }
875 }
876 for (oc = 0; oc < targetChCnt; oc++) {
877 if (oc >= baseChCnt) break;
878 audioChannels[oc][n] = tmp_out[oc];
879 }
880 }
881
882 for (oc = targetChCnt; oc < baseChCnt; oc++) {
883 FDKmemset(audioChannels[oc], 0, frameSize * sizeof(FIXP_DBL));
884 }
885
886 *pNChannels = targetChCnt;
887
888 return DRC_DEC_OK;
889 }
890
891 /* Get library info for this module. */
892 DRC_DEC_ERROR
FDK_drcDec_GetLibInfo(LIB_INFO * info)893 FDK_drcDec_GetLibInfo(LIB_INFO* info) {
894 int i;
895
896 if (info == NULL) {
897 return DRC_DEC_INVALID_PARAM;
898 }
899
900 /* Search for next free tab */
901 for (i = 0; i < FDK_MODULE_LAST; i++) {
902 if (info[i].module_id == FDK_NONE) break;
903 }
904 if (i == FDK_MODULE_LAST) {
905 return DRC_DEC_NOT_OK;
906 }
907
908 /* Add the library info */
909 info[i].module_id = FDK_UNIDRCDEC;
910 info[i].version = LIB_VERSION(DRCDEC_LIB_VL0, DRCDEC_LIB_VL1, DRCDEC_LIB_VL2);
911 LIB_VERSION_STRING(info + i);
912 info[i].build_date = DRCDEC_LIB_BUILD_DATE;
913 info[i].build_time = DRCDEC_LIB_BUILD_TIME;
914 info[i].title = DRCDEC_LIB_TITLE;
915
916 return DRC_DEC_OK;
917 }
918