Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 
    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 
    176 static 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 
    216 DRC_DEC_ERROR
    217 FDK_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 
    248 DRC_DEC_ERROR
    249 FDK_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 
    323 DRC_DEC_ERROR
    324 FDK_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 
    356 DRC_DEC_ERROR
    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
    383 FDK_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 
    459 LONG 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 
    497 DRC_DEC_ERROR
    498 FDK_drcDec_SetInterfaceParameters(HANDLE_DRC_DECODER hDrcDec,
    499                                   HANDLE_UNI_DRC_INTERFACE hUniDrcInterface) {
    500   return DRC_DEC_UNSUPPORTED_FUNCTION;
    501 }
    502 
    503 DRC_DEC_ERROR
    504 FDK_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 
    510 DRC_DEC_ERROR
    511 FDK_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 
    518 void FDK_drcDec_SetSelectionProcessOutput(
    519     HANDLE_DRC_DECODER hDrcDec, HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {}
    520 
    521 HANDLE_SEL_PROC_OUTPUT
    522 FDK_drcDec_GetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec) {
    523   if (hDrcDec == NULL) return NULL;
    524 
    525   return &(hDrcDec->selProcOutput);
    526 }
    527 
    528 LONG /* FIXP_DBL, e = 7 */
    529 FDK_drcDec_GetGroupLoudness(HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
    530                             const int groupID, int* groupLoudnessAvailable) {
    531   return (LONG)0;
    532 }
    533 
    534 void 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 
    551 DRC_DEC_ERROR
    552 FDK_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 
    574 DRC_DEC_ERROR
    575 FDK_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 
    598 DRC_DEC_ERROR
    599 FDK_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 
    622 DRC_DEC_ERROR
    623 FDK_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 
    646 DRC_DEC_ERROR
    647 FDK_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 
    669 DRC_DEC_ERROR
    670 FDK_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 
    689 DRC_DEC_ERROR
    690 FDK_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 
    711 DRC_DEC_ERROR
    712 FDK_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 
    733 DRC_DEC_ERROR
    734 FDK_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 
    758 DRC_DEC_ERROR
    759 FDK_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 
    780 DRC_DEC_ERROR
    781 FDK_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 
    803 DRC_DEC_ERROR
    804 FDK_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. */
    866 DRC_DEC_ERROR
    867 FDK_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