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