1/* -----------------------------------------------------------------------------
2Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5Forschung e.V. All rights reserved.
6
7 1.    INTRODUCTION
8The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10scheme for digital audio. This FDK AAC Codec software is intended to be used on
11a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14general perceptual audio codecs. AAC-ELD is considered the best-performing
15full-bandwidth communications codec by independent studies and is widely
16deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17specifications.
18
19Patent licenses for necessary patent claims for the FDK AAC Codec (including
20those of Fraunhofer) may be obtained through Via Licensing
21(www.vialicensing.com) or through the respective patent owners individually for
22the purpose of encoding or decoding bit streams in products that are compliant
23with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24Android devices already license these patent claims through Via Licensing or
25directly from the patent owners, and therefore FDK AAC Codec software may
26already be covered under those patent licenses when it is used for those
27licensed purposes only.
28
29Commercially-licensed AAC software libraries, including floating-point versions
30with enhanced sound quality, are also available from Fraunhofer. Users are
31encouraged to check the Fraunhofer website for additional applications
32information and documentation.
33
342.    COPYRIGHT LICENSE
35
36Redistribution and use in source and binary forms, with or without modification,
37are permitted without payment of copyright license fees provided that you
38satisfy the following conditions:
39
40You must retain the complete text of this software license in redistributions of
41the FDK AAC Codec or your modifications thereto in source code form.
42
43You must retain the complete text of this software license in the documentation
44and/or other materials provided with redistributions of the FDK AAC Codec or
45your modifications thereto in binary form. You must make available free of
46charge copies of the complete source code of the FDK AAC Codec and your
47modifications thereto to recipients of copies in binary form.
48
49The name of Fraunhofer may not be used to endorse or promote products derived
50from this library without prior written permission.
51
52You may not charge copyright license fees for anyone to use, copy or distribute
53the FDK AAC Codec software or your modifications thereto.
54
55Your modified versions of the FDK AAC Codec must carry prominent notices stating
56that you changed the software and the date of any change. For modified versions
57of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59AAC Codec Library for Android."
60
613.    NO PATENT LICENSE
62
63NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65Fraunhofer provides no warranty of patent non-infringement with respect to this
66software.
67
68You may use this FDK AAC Codec software or modifications thereto only for
69purposes that are authorized by appropriate patent licenses.
70
714.    DISCLAIMER
72
73This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75including but not limited to the implied warranties of merchantability and
76fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78or consequential damages, including but not limited to procurement of substitute
79goods or services; loss of use, data, or profits, or business interruption,
80however caused and on any theory of liability, whether in contract, strict
81liability, or tort (including negligence), arising in any way out of the use of
82this software, even if advised of the possibility of such damage.
83
845.    CONTACT INFORMATION
85
86Fraunhofer Institute for Integrated Circuits IIS
87Attention: Audio and Multimedia Departments - FDK AAC LL
88Am Wolfsmantel 33
8991058 Erlangen, Germany
90
91www.iis.fraunhofer.de/amm
92amm-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
123typedef 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
130struct 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
148static 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
176static DRC_DEC_ERROR startSelectionProcess(HANDLE_DRC_DECODER hDrcDec) {
177  DRC_ERROR dErr = DE_OK;
178  DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
179  int uniDrcConfigHasChanged = 0;
180  SEL_PROC_OUTPUT oldSelProcOutput = hDrcDec->selProcOutput;
181
182  if (!hDrcDec->status) return DRC_DEC_NOT_READY;
183
184  if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
185    uniDrcConfigHasChanged = hDrcDec->uniDrcConfig.diff;
186    if (hDrcDec->uniDrcConfig.diff || hDrcDec->loudnessInfoSet.diff ||
187        hDrcDec->selProcInputDiff) {
188      /* in case of an error, signal that selection process was not successful
189       */
190      hDrcDec->selProcOutput.numSelectedDrcSets = 0;
191
192      sErr = drcDec_SelectionProcess_Process(
193          hDrcDec->hSelectionProc, &(hDrcDec->uniDrcConfig),
194          &(hDrcDec->loudnessInfoSet), &(hDrcDec->selProcOutput));
195      if (sErr) return DRC_DEC_OK;
196
197      hDrcDec->selProcInputDiff = 0;
198      hDrcDec->uniDrcConfig.diff = 0;
199      hDrcDec->loudnessInfoSet.diff = 0;
200    }
201  }
202
203  if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
204    if (isResetNeeded(hDrcDec, oldSelProcOutput) || uniDrcConfigHasChanged) {
205      dErr =
206          drcDec_GainDecoder_Config(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig),
207                                    hDrcDec->selProcOutput.numSelectedDrcSets,
208                                    hDrcDec->selProcOutput.selectedDrcSetIds,
209                                    hDrcDec->selProcOutput.selectedDownmixIds);
210      if (dErr) return DRC_DEC_OK;
211    }
212  }
213  return DRC_DEC_OK;
214}
215
216DRC_DEC_ERROR
217FDK_drcDec_Open(HANDLE_DRC_DECODER* phDrcDec,
218                const DRC_DEC_FUNCTIONAL_RANGE functionalRange) {
219  DRC_ERROR dErr = DE_OK;
220  DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
221  HANDLE_DRC_DECODER hDrcDec;
222
223  *phDrcDec = (HANDLE_DRC_DECODER)FDKcalloc(1, sizeof(DRC_DECODER));
224  if (!*phDrcDec) return DRC_DEC_OUT_OF_MEMORY;
225  hDrcDec = *phDrcDec;
226
227  hDrcDec->functionalRange = functionalRange;
228
229  hDrcDec->status = DRC_DEC_NOT_INITIALIZED;
230  hDrcDec->codecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
231
232  if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
233    sErr = drcDec_SelectionProcess_Create(&(hDrcDec->hSelectionProc));
234    if (sErr) return DRC_DEC_OUT_OF_MEMORY;
235    sErr = drcDec_SelectionProcess_Init(hDrcDec->hSelectionProc);
236    if (sErr) return DRC_DEC_NOT_OK;
237    hDrcDec->selProcInputDiff = 1;
238  }
239
240  if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
241    dErr = drcDec_GainDecoder_Open(&(hDrcDec->hGainDec));
242    if (dErr) return DRC_DEC_OUT_OF_MEMORY;
243  }
244
245  return DRC_DEC_OK;
246}
247
248DRC_DEC_ERROR
249FDK_drcDec_SetCodecMode(HANDLE_DRC_DECODER hDrcDec,
250                        const DRC_DEC_CODEC_MODE codecMode) {
251  DRC_ERROR dErr = DE_OK;
252  DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
253
254  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
255
256  if (hDrcDec->codecMode ==
257      DRC_DEC_CODEC_MODE_UNDEFINED) { /* Set codec mode, if it is set for the
258                                         first time */
259    hDrcDec->codecMode = codecMode;
260
261    if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
262      sErr = drcDec_SelectionProcess_SetCodecMode(
263          hDrcDec->hSelectionProc, (SEL_PROC_CODEC_MODE)codecMode);
264      if (sErr) return DRC_DEC_NOT_OK;
265      hDrcDec->selProcInputDiff = 1;
266    }
267
268    if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
269      DELAY_MODE delayMode;
270      int timeDomainSupported;
271      SUBBAND_DOMAIN_MODE subbandDomainSupported;
272
273      switch (hDrcDec->codecMode) {
274        case DRC_DEC_MPEG_4_AAC:
275        case DRC_DEC_MPEG_D_USAC:
276        case DRC_DEC_MPEG_H_3DA:
277        default:
278          delayMode = DM_REGULAR_DELAY;
279      }
280
281      switch (hDrcDec->codecMode) {
282        case DRC_DEC_MPEG_4_AAC:
283        case DRC_DEC_MPEG_D_USAC:
284          timeDomainSupported = 1;
285          subbandDomainSupported = SDM_OFF;
286          break;
287        case DRC_DEC_MPEG_H_3DA:
288          timeDomainSupported = 1;
289          subbandDomainSupported = SDM_STFT256;
290          break;
291
292        case DRC_DEC_TEST_TIME_DOMAIN:
293          timeDomainSupported = 1;
294          subbandDomainSupported = SDM_OFF;
295          break;
296        case DRC_DEC_TEST_QMF_DOMAIN:
297          timeDomainSupported = 0;
298          subbandDomainSupported = SDM_QMF64;
299          break;
300        case DRC_DEC_TEST_STFT_DOMAIN:
301          timeDomainSupported = 0;
302          subbandDomainSupported = SDM_STFT256;
303          break;
304
305        default:
306          timeDomainSupported = 0;
307          subbandDomainSupported = SDM_OFF;
308      }
309
310      dErr = drcDec_GainDecoder_SetCodecDependentParameters(
311          hDrcDec->hGainDec, delayMode, timeDomainSupported,
312          subbandDomainSupported);
313      if (dErr) return DRC_DEC_NOT_OK;
314    }
315  }
316
317  /* Don't allow changing codecMode if it has already been set. */
318  if (hDrcDec->codecMode != codecMode) return DRC_DEC_NOT_OK;
319
320  return DRC_DEC_OK;
321}
322
323DRC_DEC_ERROR
324FDK_drcDec_Init(HANDLE_DRC_DECODER hDrcDec, const int frameSize,
325                const int sampleRate, const int baseChannelCount) {
326  DRC_ERROR dErr = DE_OK;
327  DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
328
329  if (hDrcDec == NULL || frameSize == 0 || sampleRate == 0 ||
330      baseChannelCount == 0)
331    return DRC_DEC_OK; /* return without doing anything */
332
333  if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
334    sErr = drcDec_SelectionProcess_SetParam(
335        hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT,
336        (FIXP_DBL)baseChannelCount, &(hDrcDec->selProcInputDiff));
337    if (sErr) return DRC_DEC_NOT_OK;
338    sErr = drcDec_SelectionProcess_SetParam(
339        hDrcDec->hSelectionProc, SEL_PROC_SAMPLE_RATE, (FIXP_DBL)sampleRate,
340        &(hDrcDec->selProcInputDiff));
341    if (sErr) return DRC_DEC_NOT_OK;
342  }
343
344  if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
345    dErr = drcDec_GainDecoder_Init(hDrcDec->hGainDec, frameSize, sampleRate);
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
356DRC_DEC_ERROR
357FDK_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
382DRC_DEC_ERROR
383FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec,
384                    const DRC_DEC_USERPARAM requestType,
385                    const FIXP_DBL requestValue) {
386  DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
387
388  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
389
390  if (hDrcDec->functionalRange == DRC_DEC_GAIN)
391    return DRC_DEC_NOT_OK; /* not supported for DRC_DEC_GAIN. All parameters are
392                              handed over to selection process lib. */
393
394  switch (requestType) {
395    case DRC_DEC_BOOST:
396      sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
397                                              SEL_PROC_BOOST, requestValue,
398                                              &(hDrcDec->selProcInputDiff));
399      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
400      break;
401    case DRC_DEC_COMPRESS:
402      sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
403                                              SEL_PROC_COMPRESS, requestValue,
404                                              &(hDrcDec->selProcInputDiff));
405      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
406      break;
407    case DRC_DEC_LOUDNESS_NORMALIZATION_ON:
408      sErr = drcDec_SelectionProcess_SetParam(
409          hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON,
410          requestValue, &(hDrcDec->selProcInputDiff));
411      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
412      break;
413    case DRC_DEC_TARGET_LOUDNESS:
414      sErr = drcDec_SelectionProcess_SetParam(
415          hDrcDec->hSelectionProc, SEL_PROC_TARGET_LOUDNESS, requestValue,
416          &(hDrcDec->selProcInputDiff));
417      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
418      break;
419    case DRC_DEC_EFFECT_TYPE:
420      sErr = drcDec_SelectionProcess_SetParam(
421          hDrcDec->hSelectionProc, SEL_PROC_EFFECT_TYPE, requestValue,
422          &(hDrcDec->selProcInputDiff));
423      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
424      break;
425    case DRC_DEC_DOWNMIX_ID:
426      sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
427                                              SEL_PROC_DOWNMIX_ID, requestValue,
428                                              &(hDrcDec->selProcInputDiff));
429      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
430      break;
431    case DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED:
432      sErr = drcDec_SelectionProcess_SetParam(
433          hDrcDec->hSelectionProc, SEL_PROC_TARGET_CHANNEL_COUNT, requestValue,
434          &(hDrcDec->selProcInputDiff));
435      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
436      break;
437    case DRC_DEC_BASE_CHANNEL_COUNT:
438      sErr = drcDec_SelectionProcess_SetParam(
439          hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT, requestValue,
440          &(hDrcDec->selProcInputDiff));
441      if (sErr) return DRC_DEC_NOT_OK;
442      break;
443    case DRC_DEC_LOUDNESS_MEASUREMENT_METHOD:
444      sErr = drcDec_SelectionProcess_SetParam(
445          hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_MEASUREMENT_METHOD,
446          requestValue, &(hDrcDec->selProcInputDiff));
447      if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
448      break;
449    default:
450      return DRC_DEC_INVALID_PARAM;
451  }
452
453  /* All parameters need a new start of the selection process */
454  startSelectionProcess(hDrcDec);
455
456  return DRC_DEC_OK;
457}
458
459LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
460                         const DRC_DEC_USERPARAM requestType) {
461  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
462
463  switch (requestType) {
464    case DRC_DEC_BOOST:
465      return (LONG)hDrcDec->selProcOutput.boost;
466    case DRC_DEC_COMPRESS:
467      return (LONG)hDrcDec->selProcOutput.compress;
468    case DRC_DEC_IS_MULTIBAND_DRC_1:
469      return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0);
470    case DRC_DEC_IS_MULTIBAND_DRC_2:
471      return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0x7F);
472    case DRC_DEC_IS_ACTIVE: {
473      /* MPEG-D DRC is considered active (and overrides MPEG-4 DRC), if
474       * uniDrc payload is present (loudnessInfoSet and/or uniDrcConfig)
475       * at least one of DRC and Loudness Control is switched on */
476      int drcOn = drcDec_SelectionProcess_GetParam(
477          hDrcDec->hSelectionProc, SEL_PROC_DYNAMIC_RANGE_CONTROL_ON);
478      int lnOn = drcDec_SelectionProcess_GetParam(
479          hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON);
480      int uniDrcPayloadPresent =
481          (hDrcDec->loudnessInfoSet.loudnessInfoCount > 0);
482      uniDrcPayloadPresent |=
483          (hDrcDec->loudnessInfoSet.loudnessInfoAlbumCount > 0);
484      uniDrcPayloadPresent |=
485          (hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount > 0);
486      uniDrcPayloadPresent |=
487          (hDrcDec->uniDrcConfig.downmixInstructionsCount > 0);
488      return (LONG)(uniDrcPayloadPresent && (drcOn || lnOn));
489    }
490    case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
491      return (LONG)hDrcDec->selProcOutput.targetChannelCount;
492    default:
493      return 0;
494  }
495}
496
497DRC_DEC_ERROR
498FDK_drcDec_SetInterfaceParameters(HANDLE_DRC_DECODER hDrcDec,
499                                  HANDLE_UNI_DRC_INTERFACE hUniDrcInterface) {
500  return DRC_DEC_UNSUPPORTED_FUNCTION;
501}
502
503DRC_DEC_ERROR
504FDK_drcDec_SetSelectionProcessMpeghParameters_simple(
505    HANDLE_DRC_DECODER hDrcDec, const int groupPresetIdRequested,
506    const int numGroupIdsRequested, const int* groupIdsRequested) {
507  return DRC_DEC_UNSUPPORTED_FUNCTION;
508}
509
510DRC_DEC_ERROR
511FDK_drcDec_SetDownmixInstructions(HANDLE_DRC_DECODER hDrcDec,
512                                  const int numDownmixId, const int* downmixId,
513                                  const int* targetLayout,
514                                  const int* targetChannelCount) {
515  return DRC_DEC_UNSUPPORTED_FUNCTION;
516}
517
518void FDK_drcDec_SetSelectionProcessOutput(
519    HANDLE_DRC_DECODER hDrcDec, HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {}
520
521HANDLE_SEL_PROC_OUTPUT
522FDK_drcDec_GetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec) {
523  if (hDrcDec == NULL) return NULL;
524
525  return &(hDrcDec->selProcOutput);
526}
527
528LONG /* FIXP_DBL, e = 7 */
529FDK_drcDec_GetGroupLoudness(HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
530                            const int groupID, int* groupLoudnessAvailable) {
531  return (LONG)0;
532}
533
534void FDK_drcDec_SetChannelGains(HANDLE_DRC_DECODER hDrcDec,
535                                const int numChannels, const int frameSize,
536                                FIXP_DBL* channelGainDb, FIXP_DBL* audioBuffer,
537                                const int audioBufferChannelOffset) {
538  int err;
539
540  if (hDrcDec == NULL) return;
541
542  err = drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
543      hDrcDec->hGainDec, hDrcDec->selProcOutput.loudnessNormalizationGainDb);
544  if (err) return;
545
546  drcDec_GainDecoder_SetChannelGains(hDrcDec->hGainDec, numChannels, frameSize,
547                                     channelGainDb, audioBufferChannelOffset,
548                                     audioBuffer);
549}
550
551DRC_DEC_ERROR
552FDK_drcDec_ReadUniDrcConfig(HANDLE_DRC_DECODER hDrcDec,
553                            HANDLE_FDK_BITSTREAM hBitstream) {
554  DRC_ERROR dErr = DE_OK;
555
556  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
557
558  if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) {
559    dErr = drcDec_readUniDrcConfig(hBitstream, &(hDrcDec->uniDrcConfig));
560  } else
561    return DRC_DEC_NOT_OK;
562
563  if (dErr) {
564    /* clear config, if parsing error occured */
565    FDKmemclear(&hDrcDec->uniDrcConfig, sizeof(hDrcDec->uniDrcConfig));
566    hDrcDec->uniDrcConfig.diff = 1;
567  }
568
569  startSelectionProcess(hDrcDec);
570
571  return DRC_DEC_OK;
572}
573
574DRC_DEC_ERROR
575FDK_drcDec_ReadDownmixInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
576                                       HANDLE_FDK_BITSTREAM hBitstream) {
577  DRC_ERROR dErr = DE_OK;
578
579  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
580
581  return DRC_DEC_NOT_OK;
582
583  if (dErr) {
584    /* clear config, if parsing error occurred */
585    FDKmemclear(&hDrcDec->uniDrcConfig.downmixInstructions,
586                sizeof(hDrcDec->uniDrcConfig.downmixInstructions));
587    hDrcDec->uniDrcConfig.downmixInstructionsCount = 0;
588    hDrcDec->uniDrcConfig.downmixInstructionsCountV0 = 0;
589    hDrcDec->uniDrcConfig.downmixInstructionsCountV1 = 0;
590    hDrcDec->uniDrcConfig.diff = 1;
591  }
592
593  startSelectionProcess(hDrcDec);
594
595  return DRC_DEC_OK;
596}
597
598DRC_DEC_ERROR
599FDK_drcDec_ReadUniDrcInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
600                                      HANDLE_FDK_BITSTREAM hBitstream) {
601  DRC_ERROR dErr = DE_OK;
602
603  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
604
605  return DRC_DEC_NOT_OK;
606
607  if (dErr) {
608    /* clear config, if parsing error occurred */
609    FDKmemclear(&hDrcDec->uniDrcConfig.drcInstructionsUniDrc,
610                sizeof(hDrcDec->uniDrcConfig.drcInstructionsUniDrc));
611    hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount = 0;
612    hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV0 = 0;
613    hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV1 = 0;
614    hDrcDec->uniDrcConfig.diff = 1;
615  }
616
617  startSelectionProcess(hDrcDec);
618
619  return DRC_DEC_OK;
620}
621
622DRC_DEC_ERROR
623FDK_drcDec_ReadUniDrcCoefficients_Box(HANDLE_DRC_DECODER hDrcDec,
624                                      HANDLE_FDK_BITSTREAM hBitstream) {
625  DRC_ERROR dErr = DE_OK;
626
627  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
628
629  return DRC_DEC_NOT_OK;
630
631  if (dErr) {
632    /* clear config, if parsing error occurred */
633    FDKmemclear(&hDrcDec->uniDrcConfig.drcCoefficientsUniDrc,
634                sizeof(hDrcDec->uniDrcConfig.drcCoefficientsUniDrc));
635    hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCount = 0;
636    hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV0 = 0;
637    hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV1 = 0;
638    hDrcDec->uniDrcConfig.diff = 1;
639  }
640
641  startSelectionProcess(hDrcDec);
642
643  return DRC_DEC_OK;
644}
645
646DRC_DEC_ERROR
647FDK_drcDec_ReadLoudnessInfoSet(HANDLE_DRC_DECODER hDrcDec,
648                               HANDLE_FDK_BITSTREAM hBitstream) {
649  DRC_ERROR dErr = DE_OK;
650
651  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
652
653  if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) {
654    dErr = drcDec_readLoudnessInfoSet(hBitstream, &(hDrcDec->loudnessInfoSet));
655  } else
656    return DRC_DEC_NOT_OK;
657
658  if (dErr) {
659    /* clear config, if parsing error occurred */
660    FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet));
661    hDrcDec->loudnessInfoSet.diff = 1;
662  }
663
664  startSelectionProcess(hDrcDec);
665
666  return DRC_DEC_OK;
667}
668
669DRC_DEC_ERROR
670FDK_drcDec_ReadLoudnessBox(HANDLE_DRC_DECODER hDrcDec,
671                           HANDLE_FDK_BITSTREAM hBitstream) {
672  DRC_ERROR dErr = DE_OK;
673
674  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
675
676  return DRC_DEC_NOT_OK;
677
678  if (dErr) {
679    /* clear config, if parsing error occurred */
680    FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet));
681    hDrcDec->loudnessInfoSet.diff = 1;
682  }
683
684  startSelectionProcess(hDrcDec);
685
686  return DRC_DEC_OK;
687}
688
689DRC_DEC_ERROR
690FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,
691                          HANDLE_FDK_BITSTREAM hBitstream) {
692  DRC_ERROR dErr = DE_OK;
693
694  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
695  if (!hDrcDec->status) {
696    return DRC_DEC_OK;
697  }
698
699  dErr = drcDec_readUniDrcGain(
700      hBitstream, &(hDrcDec->uniDrcConfig),
701      drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec),
702      drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec),
703      &(hDrcDec->uniDrcGain));
704  if (dErr) return DRC_DEC_NOT_OK;
705
706  hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
707
708  return DRC_DEC_OK;
709}
710
711DRC_DEC_ERROR
712FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,
713                      HANDLE_FDK_BITSTREAM hBitstream) {
714  DRC_ERROR dErr = DE_OK;
715
716  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
717  if (!hDrcDec->status) return DRC_DEC_NOT_READY;
718
719  dErr = drcDec_readUniDrc(
720      hBitstream, &(hDrcDec->uniDrcConfig), &(hDrcDec->loudnessInfoSet),
721      drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec),
722      drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec),
723      &(hDrcDec->uniDrcGain));
724  if (dErr) return DRC_DEC_NOT_OK;
725
726  startSelectionProcess(hDrcDec);
727
728  hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
729
730  return DRC_DEC_OK;
731}
732
733DRC_DEC_ERROR
734FDK_drcDec_Preprocess(HANDLE_DRC_DECODER hDrcDec) {
735  DRC_ERROR dErr = DE_OK;
736
737  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
738  if (!hDrcDec->status) return DRC_DEC_NOT_READY;
739  if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
740
741  if (hDrcDec->status != DRC_DEC_NEW_GAIN_PAYLOAD) {
742    /* no new gain payload was read, e.g. during concalment or flushing.
743       Generate DRC gains based on the stored DRC gains of last frames */
744    drcDec_GainDecoder_Conceal(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig),
745                               &(hDrcDec->uniDrcGain));
746  }
747
748  dErr = drcDec_GainDecoder_Preprocess(
749      hDrcDec->hGainDec, &(hDrcDec->uniDrcGain),
750      hDrcDec->selProcOutput.loudnessNormalizationGainDb,
751      hDrcDec->selProcOutput.boost, hDrcDec->selProcOutput.compress);
752  if (dErr) return DRC_DEC_NOT_OK;
753  hDrcDec->status = DRC_DEC_INTERPOLATION_PREPARED;
754
755  return DRC_DEC_OK;
756}
757
758DRC_DEC_ERROR
759FDK_drcDec_ProcessTime(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
760                       const DRC_DEC_LOCATION drcLocation,
761                       const int channelOffset, const int drcChannelOffset,
762                       const int numChannelsProcessed, FIXP_DBL* realBuffer,
763                       const int timeDataChannelOffset) {
764  DRC_ERROR dErr = DE_OK;
765
766  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
767  if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
768  if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED)
769    return DRC_DEC_NOT_READY;
770
771  dErr = drcDec_GainDecoder_ProcessTimeDomain(
772      hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation,
773      channelOffset, drcChannelOffset, numChannelsProcessed,
774      timeDataChannelOffset, realBuffer);
775  if (dErr) return DRC_DEC_NOT_OK;
776
777  return DRC_DEC_OK;
778}
779
780DRC_DEC_ERROR
781FDK_drcDec_ProcessFreq(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
782                       const DRC_DEC_LOCATION drcLocation,
783                       const int channelOffset, const int drcChannelOffset,
784                       const int numChannelsProcessed,
785                       const int processSingleTimeslot, FIXP_DBL** realBuffer,
786                       FIXP_DBL** imagBuffer) {
787  DRC_ERROR dErr = DE_OK;
788
789  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
790  if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
791  if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED)
792    return DRC_DEC_NOT_READY;
793
794  dErr = drcDec_GainDecoder_ProcessSubbandDomain(
795      hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation,
796      channelOffset, drcChannelOffset, numChannelsProcessed,
797      processSingleTimeslot, realBuffer, imagBuffer);
798  if (dErr) return DRC_DEC_NOT_OK;
799
800  return DRC_DEC_OK;
801}
802
803DRC_DEC_ERROR
804FDK_drcDec_ApplyDownmix(HANDLE_DRC_DECODER hDrcDec, int* reverseInChannelMap,
805                        int* reverseOutChannelMap, FIXP_DBL* realBuffer,
806                        int* pNChannels) {
807  SEL_PROC_OUTPUT* pSelProcOutput = &(hDrcDec->selProcOutput);
808  int baseChCnt = pSelProcOutput->baseChannelCount;
809  int targetChCnt = pSelProcOutput->targetChannelCount;
810  int frameSize, n, ic, oc;
811  FIXP_DBL tmp_out[8];
812  FIXP_DBL* audioChannels[8];
813
814  if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
815  if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
816
817  /* only downmix is performed here, no upmix.
818     Downmix is only performed if downmix coefficients are provided.
819     All other cases of downmix and upmix are treated by pcmDmx library. */
820  if (pSelProcOutput->downmixMatrixPresent == 0)
821    return DRC_DEC_OK;                             /* no downmix */
822  if (targetChCnt >= baseChCnt) return DRC_DEC_OK; /* downmix only */
823
824  /* sanity checks */
825  if (realBuffer == NULL) return DRC_DEC_NOT_OK;
826  if (reverseInChannelMap == NULL) return DRC_DEC_NOT_OK;
827  if (reverseOutChannelMap == NULL) return DRC_DEC_NOT_OK;
828  if (baseChCnt > 8) return DRC_DEC_NOT_OK;
829  if (baseChCnt != *pNChannels) return DRC_DEC_NOT_OK;
830  if (targetChCnt > 8) return DRC_DEC_NOT_OK;
831
832  frameSize = drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec);
833
834  for (ic = 0; ic < baseChCnt; ic++) {
835    audioChannels[ic] = &(realBuffer[ic * frameSize]);
836  }
837
838  /* in-place downmix */
839  for (n = 0; n < frameSize; n++) {
840    for (oc = 0; oc < targetChCnt; oc++) {
841      tmp_out[oc] = (FIXP_DBL)0;
842      for (ic = 0; ic < baseChCnt; ic++) {
843        tmp_out[oc] +=
844            fMultDiv2(audioChannels[ic][n],
845                      pSelProcOutput->downmixMatrix[reverseInChannelMap[ic]]
846                                                   [reverseOutChannelMap[oc]])
847            << 3;
848      }
849    }
850    for (oc = 0; oc < targetChCnt; oc++) {
851      if (oc >= baseChCnt) break;
852      audioChannels[oc][n] = tmp_out[oc];
853    }
854  }
855
856  for (oc = targetChCnt; oc < baseChCnt; oc++) {
857    FDKmemset(audioChannels[oc], 0, frameSize * sizeof(FIXP_DBL));
858  }
859
860  *pNChannels = targetChCnt;
861
862  return DRC_DEC_OK;
863}
864
865/* Get library info for this module. */
866DRC_DEC_ERROR
867FDK_drcDec_GetLibInfo(LIB_INFO* info) {
868  int i;
869
870  if (info == NULL) {
871    return DRC_DEC_INVALID_PARAM;
872  }
873
874  /* Search for next free tab */
875  for (i = 0; i < FDK_MODULE_LAST; i++) {
876    if (info[i].module_id == FDK_NONE) break;
877  }
878  if (i == FDK_MODULE_LAST) {
879    return DRC_DEC_NOT_OK;
880  }
881
882  /* Add the library info */
883  info[i].module_id = FDK_UNIDRCDEC;
884  info[i].version = LIB_VERSION(DRCDEC_LIB_VL0, DRCDEC_LIB_VL1, DRCDEC_LIB_VL2);
885  LIB_VERSION_STRING(info + i);
886  info[i].build_date = DRCDEC_LIB_BUILD_DATE;
887  info[i].build_time = DRCDEC_LIB_BUILD_TIME;
888  info[i].title = DRCDEC_LIB_TITLE;
889
890  return DRC_DEC_OK;
891}
892