• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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