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 /**************************** AAC encoder library ******************************
     96 
     97    Author(s):   V. Bacigalupo
     98 
     99    Description: Metadata Encoder library interface functions
    100 
    101 *******************************************************************************/
    102 
    103 #include "metadata_main.h"
    104 #include "metadata_compressor.h"
    105 #include "FDK_bitstream.h"
    106 #include "FDK_audio.h"
    107 #include "genericStds.h"
    108 
    109 /*----------------- defines ----------------------*/
    110 #define MAX_DRC_BANDS (1 << 4)
    111 #define MAX_DRC_FRAMELEN (2 * 1024)
    112 #define MAX_DELAY_FRAMES (3)
    113 
    114 /*--------------- structure definitions --------------------*/
    115 
    116 typedef struct AAC_METADATA {
    117   /* MPEG: Dynamic Range Control */
    118   struct {
    119     UCHAR prog_ref_level_present;
    120     SCHAR prog_ref_level;
    121 
    122     UCHAR dyn_rng_sgn[MAX_DRC_BANDS];
    123     UCHAR dyn_rng_ctl[MAX_DRC_BANDS];
    124 
    125     UCHAR drc_bands_present;
    126     UCHAR drc_band_incr;
    127     UCHAR drc_band_top[MAX_DRC_BANDS];
    128     UCHAR drc_interpolation_scheme;
    129     AACENC_METADATA_DRC_PROFILE drc_profile;
    130     INT drc_TargetRefLevel; /* used for Limiter */
    131 
    132     /* excluded channels */
    133     UCHAR excluded_chns_present;
    134     UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */
    135   } mpegDrc;
    136 
    137   /* ETSI: addtl ancillary data */
    138   struct {
    139     /* Heavy Compression */
    140     UCHAR compression_on;    /* flag, if compression value should be written */
    141     UCHAR compression_value; /* compression value */
    142     AACENC_METADATA_DRC_PROFILE comp_profile;
    143     INT comp_TargetRefLevel; /* used for Limiter */
    144     INT timecode_coarse_status;
    145     INT timecode_fine_status;
    146 
    147     UCHAR extAncDataStatus;
    148 
    149     struct {
    150       UCHAR ext_downmix_lvl_status;
    151       UCHAR ext_downmix_gain_status;
    152       UCHAR ext_lfe_downmix_status;
    153       UCHAR
    154       ext_dmix_a_idx; /* extended downmix level (0..7, according to table)
    155                        */
    156       UCHAR
    157       ext_dmix_b_idx; /* extended downmix level (0..7, according to table)
    158                        */
    159       UCHAR dmx_gain_5_sgn;
    160       UCHAR dmx_gain_5_idx;
    161       UCHAR dmx_gain_2_sgn;
    162       UCHAR dmx_gain_2_idx;
    163       UCHAR ext_dmix_lfe_idx; /* extended downmix level for lfe (0..15,
    164                                  according to table) */
    165 
    166     } extAncData;
    167 
    168   } etsiAncData;
    169 
    170   SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */
    171   SCHAR
    172   surroundMixLevel; /* surround downmix level (0...7, according to table) */
    173   UCHAR WritePCEMixDwnIdx; /* flag */
    174   UCHAR DmxLvl_On;         /* flag */
    175 
    176   UCHAR dolbySurroundMode;
    177   UCHAR drcPresentationMode;
    178 
    179   UCHAR
    180   metadataMode; /* indicate meta data mode in current frame (delay line) */
    181 
    182 } AAC_METADATA;
    183 
    184 typedef struct FDK_METADATA_ENCODER {
    185   INT metadataMode;
    186   HDRC_COMP hDrcComp;
    187   AACENC_MetaData submittedMetaData;
    188 
    189   INT nAudioDataDelay; /* Additional delay to round up to next frame border (in
    190                           samples) */
    191   INT nMetaDataDelay;  /* Meta data delay (in frames) */
    192   INT nChannels;
    193   CHANNEL_MODE channelMode;
    194 
    195   INT_PCM* pAudioDelayBuffer;
    196 
    197   AAC_METADATA metaDataBuffer[MAX_DELAY_FRAMES];
    198   INT metaDataDelayIdx;
    199 
    200   UCHAR drcInfoPayload[12];
    201   UCHAR drcDsePayload[8];
    202 
    203   INT matrix_mixdown_idx;
    204 
    205   AACENC_EXT_PAYLOAD exPayload[2];
    206   INT nExtensions;
    207 
    208   UINT maxChannels; /* Maximum number of audio channels to be supported. */
    209 
    210   INT finalizeMetaData;   /* Delay switch off by one frame and write default
    211                              configuration to   finalize the metadata setup. */
    212   INT initializeMetaData; /* Fill up delay line with first meta data info. This
    213                              is required to have meta data already in first
    214                              frame. */
    215 } FDK_METADATA_ENCODER;
    216 
    217 /*---------------- constants -----------------------*/
    218 static const AACENC_MetaData defaultMetaDataSetup = {
    219     AACENC_METADATA_DRC_NONE,        /* drc_profile */
    220     AACENC_METADATA_DRC_NOT_PRESENT, /* comp_profile */
    221     -(31 << 16),                     /* drc_TargetRefLevel */
    222     -(23 << 16),                     /* comp_TargetRefLevel */
    223     0,                               /* prog_ref_level_present */
    224     -(23 << 16),                     /* prog_ref_level */
    225     0,                               /* PCE_mixdown_idx_present */
    226     0,                               /* ETSI_DmxLvl_present */
    227     0,                               /* centerMixLevel */
    228     0,                               /* surroundMixLevel */
    229     0,                               /* dolbySurroundMode */
    230     0,                               /* drcPresentationMode */
    231     {0, 0, 0, 0, 0, 0, 0, 0, 0}      /* ExtMetaData */
    232 };
    233 
    234 static const FIXP_DBL dmxTable[8] = {
    235     ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f),
    236     FL2FXCONST_DBL(0.596f), FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f),
    237     FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)};
    238 
    239 #define FL2DMXLFE(a) FL2FXCONST_DBL((a) / (1 << LFE_LEV_SCALE))
    240 static const FIXP_DBL dmxLfeTable[16] = {
    241     FL2DMXLFE(3.162f), FL2DMXLFE(2.000f), FL2DMXLFE(1.679f), FL2DMXLFE(1.413f),
    242     FL2DMXLFE(1.189f), FL2DMXLFE(1.000f), FL2DMXLFE(0.841f), FL2DMXLFE(0.707f),
    243     FL2DMXLFE(0.596f), FL2DMXLFE(0.500f), FL2DMXLFE(0.316f), FL2DMXLFE(0.178f),
    244     FL2DMXLFE(0.100f), FL2DMXLFE(0.032f), FL2DMXLFE(0.010f), FL2DMXLFE(0.000f)};
    245 
    246 static const UCHAR surmix2matrix_mixdown_idx[8] = {0, 0, 0, 1, 1, 2, 2, 3};
    247 
    248 /*--------------- function declarations --------------------*/
    249 static FDK_METADATA_ERROR WriteMetadataPayload(
    250     const HANDLE_FDK_METADATA_ENCODER hMetaData,
    251     const AAC_METADATA* const pMetadata);
    252 
    253 static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
    254                                         UCHAR* const pExtensionPayload);
    255 
    256 static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
    257                                          UCHAR* const pExtensionPayload);
    258 
    259 static FDK_METADATA_ERROR CompensateAudioDelay(
    260     HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
    261     const UINT audioSamplesBufSize, const INT nAudioSamples);
    262 
    263 static FDK_METADATA_ERROR LoadSubmittedMetadata(
    264     const AACENC_MetaData* const hMetadata, const INT nChannels,
    265     const INT metadataMode, AAC_METADATA* const pAacMetaData);
    266 
    267 static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
    268                                             HDRC_COMP hDrcComp,
    269                                             const INT_PCM* const pSamples,
    270                                             const UINT samplesBufSize,
    271                                             const INT nSamples);
    272 
    273 /*------------- function definitions ----------------*/
    274 
    275 static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) {
    276   DRC_PROFILE drcProfile = DRC_NONE;
    277 
    278   switch (aacProfile) {
    279     case AACENC_METADATA_DRC_NONE:
    280       drcProfile = DRC_NONE;
    281       break;
    282     case AACENC_METADATA_DRC_FILMSTANDARD:
    283       drcProfile = DRC_FILMSTANDARD;
    284       break;
    285     case AACENC_METADATA_DRC_FILMLIGHT:
    286       drcProfile = DRC_FILMLIGHT;
    287       break;
    288     case AACENC_METADATA_DRC_MUSICSTANDARD:
    289       drcProfile = DRC_MUSICSTANDARD;
    290       break;
    291     case AACENC_METADATA_DRC_MUSICLIGHT:
    292       drcProfile = DRC_MUSICLIGHT;
    293       break;
    294     case AACENC_METADATA_DRC_SPEECH:
    295       drcProfile = DRC_SPEECH;
    296       break;
    297     case AACENC_METADATA_DRC_NOT_PRESENT:
    298       drcProfile = DRC_NOT_PRESENT;
    299       break;
    300     default:
    301       drcProfile = DRC_NONE;
    302       break;
    303   }
    304   return drcProfile;
    305 }
    306 
    307 /* convert dialog normalization to program reference level */
    308 /* NOTE: this only is correct, if the decoder target level is set to -31dB for
    309  * line mode / -20dB for RF mode */
    310 static UCHAR dialnorm2progreflvl(const INT d) {
    311   return ((UCHAR)fMax(0, fMin((-d + (1 << 13)) >> 14, 127)));
    312 }
    313 
    314 /* convert program reference level to dialog normalization */
    315 static INT progreflvl2dialnorm(const UCHAR p) {
    316   return -((INT)(p << (16 - 2)));
    317 }
    318 
    319 /* encode downmix levels to Downmixing_levels_MPEG4 */
    320 static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) {
    321   SCHAR dmxLvls = 0;
    322   dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
    323   dmxLvls |= 0x08 | surmixlev;      /* surround_mix_level_on */
    324 
    325   return dmxLvls;
    326 }
    327 
    328 /* encode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
    329 static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl,
    330                          UCHAR* const dyn_rng_sgn) {
    331   if (gain < 0) {
    332     *dyn_rng_sgn = 1;
    333     gain = -gain;
    334   } else {
    335     *dyn_rng_sgn = 0;
    336   }
    337   gain = fMin(gain, (127 << 14));
    338 
    339   *dyn_rng_ctl = (UCHAR)((gain + (1 << 13)) >> 14);
    340 }
    341 
    342 /* decode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
    343 static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) {
    344   INT tmp = ((INT)dyn_rng_ctl << (16 - 2));
    345   if (dyn_rng_sgn) tmp = -tmp;
    346 
    347   return tmp;
    348 }
    349 
    350 /* encode AAC compression value (ETSI TS 101 154 page 99) */
    351 static UCHAR encodeCompr(INT gain) {
    352   UCHAR x, y;
    353   INT tmp;
    354 
    355   /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
    356   tmp = ((3156476 - gain) * 15 + 197283) / 394566;
    357 
    358   if (tmp >= 240) {
    359     return 0xFF;
    360   } else if (tmp < 0) {
    361     return 0;
    362   } else {
    363     x = tmp / 15;
    364     y = tmp % 15;
    365   }
    366 
    367   return (x << 4) | y;
    368 }
    369 
    370 /* decode AAC compression value (ETSI TS 101 154 page 99) */
    371 static INT decodeCompr(const UCHAR compr) {
    372   INT gain;
    373   SCHAR x = compr >> 4;     /* 4 MSB of compr */
    374   UCHAR y = (compr & 0x0F); /* 4 LSB of compr */
    375 
    376   /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
    377   gain = (INT)(
    378       scaleValue((FIXP_DBL)(((LONG)FL2FXCONST_DBL(6.0206f / 128.f) * (8 - x) -
    379                              (LONG)FL2FXCONST_DBL(0.4014f / 128.f) * y)),
    380                  -(DFRACT_BITS - 1 - 7 - 16)));
    381 
    382   return gain;
    383 }
    384 
    385 FDK_METADATA_ERROR FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER* phMetaData,
    386                                         const UINT maxChannels) {
    387   FDK_METADATA_ERROR err = METADATA_OK;
    388   HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;
    389 
    390   if (phMetaData == NULL) {
    391     err = METADATA_INVALID_HANDLE;
    392     goto bail;
    393   }
    394 
    395   /* allocate memory */
    396   if (NULL == (hMetaData = (HANDLE_FDK_METADATA_ENCODER)FDKcalloc(
    397                    1, sizeof(FDK_METADATA_ENCODER)))) {
    398     err = METADATA_MEMORY_ERROR;
    399     goto bail;
    400   }
    401   FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));
    402 
    403   if (NULL == (hMetaData->pAudioDelayBuffer = (INT_PCM*)FDKcalloc(
    404                    maxChannels * MAX_DRC_FRAMELEN, sizeof(INT_PCM)))) {
    405     err = METADATA_MEMORY_ERROR;
    406     goto bail;
    407   }
    408   FDKmemclear(hMetaData->pAudioDelayBuffer,
    409               maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
    410   hMetaData->maxChannels = maxChannels;
    411 
    412   /* Allocate DRC Compressor. */
    413   if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp) != 0) {
    414     err = METADATA_MEMORY_ERROR;
    415     goto bail;
    416   }
    417   hMetaData->channelMode = MODE_UNKNOWN;
    418 
    419   /* Return metadata instance */
    420   *phMetaData = hMetaData;
    421 
    422   return err;
    423 
    424 bail:
    425   FDK_MetadataEnc_Close(&hMetaData);
    426   return err;
    427 }
    428 
    429 FDK_METADATA_ERROR FDK_MetadataEnc_Close(
    430     HANDLE_FDK_METADATA_ENCODER* phMetaData) {
    431   FDK_METADATA_ERROR err = METADATA_OK;
    432 
    433   if (phMetaData == NULL) {
    434     err = METADATA_INVALID_HANDLE;
    435     goto bail;
    436   }
    437 
    438   if (*phMetaData != NULL) {
    439     FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
    440     FDKfree((*phMetaData)->pAudioDelayBuffer);
    441     FDKfree(*phMetaData);
    442     *phMetaData = NULL;
    443   }
    444 bail:
    445   return err;
    446 }
    447 
    448 FDK_METADATA_ERROR FDK_MetadataEnc_Init(
    449     HANDLE_FDK_METADATA_ENCODER hMetaData, const INT resetStates,
    450     const INT metadataMode, const INT audioDelay, const UINT frameLength,
    451     const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode,
    452     const CHANNEL_ORDER channelOrder) {
    453   FDK_METADATA_ERROR err = METADATA_OK;
    454   int i, nFrames, delay;
    455 
    456   if (hMetaData == NULL) {
    457     err = METADATA_INVALID_HANDLE;
    458     goto bail;
    459   }
    460 
    461   /* Determine values for delay compensation. */
    462   for (nFrames = 0, delay = audioDelay - (INT)frameLength; delay > 0;
    463        delay -= (INT)frameLength, nFrames++)
    464     ;
    465 
    466   if ((nChannels > (8)) || (nChannels > hMetaData->maxChannels) ||
    467       ((-delay) > MAX_DRC_FRAMELEN) || nFrames >= MAX_DELAY_FRAMES) {
    468     err = METADATA_INIT_ERROR;
    469     goto bail;
    470   }
    471 
    472   /* Initialize with default setup. */
    473   FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup,
    474             sizeof(AACENC_MetaData));
    475 
    476   hMetaData->finalizeMetaData =
    477       0; /* finalize meta data only while on/off switching, else disabled */
    478   hMetaData->initializeMetaData =
    479       0; /* fill up meta data delay line only at a reset otherwise disabled */
    480 
    481   /* Reset delay lines. */
    482   if (resetStates || (hMetaData->nAudioDataDelay != -delay) ||
    483       (hMetaData->channelMode != channelMode)) {
    484     if (resetStates || (hMetaData->channelMode == MODE_UNKNOWN)) {
    485       /* clear delay buffer */
    486       FDKmemclear(hMetaData->pAudioDelayBuffer,
    487                   hMetaData->maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
    488     } else {
    489       /* if possible, keep static audio channels for seamless channel
    490        * reconfiguration */
    491       FDK_channelMapDescr mapDescrPrev, mapDescr;
    492       int c, src[2] = {-1, -1}, dst[2] = {-1, -1};
    493 
    494       FDK_chMapDescr_init(&mapDescrPrev, NULL, 0,
    495                           (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
    496       FDK_chMapDescr_init(&mapDescr, NULL, 0,
    497                           (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
    498 
    499       switch (channelMode) {
    500         case MODE_1:
    501           if ((INT)nChannels != 2) {
    502             /* preserve center channel */
    503             src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0,
    504                                                 hMetaData->channelMode);
    505             dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode);
    506           }
    507           break;
    508         case MODE_2:
    509         case MODE_1_2:
    510         case MODE_1_2_1:
    511         case MODE_1_2_2:
    512         case MODE_1_2_2_1:
    513           if (hMetaData->nChannels >= 2) {
    514             /* preserve left/right channel */
    515             src[0] = FDK_chMapDescr_getMapValue(
    516                 &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1),
    517                 hMetaData->channelMode);
    518             src[1] = FDK_chMapDescr_getMapValue(
    519                 &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2),
    520                 hMetaData->channelMode);
    521             dst[0] = FDK_chMapDescr_getMapValue(
    522                 &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode);
    523             dst[1] = FDK_chMapDescr_getMapValue(
    524                 &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode);
    525           }
    526           break;
    527         default:;
    528       }
    529       C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8));
    530       FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM));
    531 
    532       i = (hMetaData->nChannels > (INT)nChannels)
    533               ? 0
    534               : hMetaData->nAudioDataDelay - 1;
    535       do {
    536         for (c = 0; c < 2; c++) {
    537           if (src[c] != -1 && dst[c] != -1) {
    538             scratch_audioDelayBuffer[dst[c]] =
    539                 hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]];
    540           }
    541         }
    542         FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels],
    543                   scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM));
    544         i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1;
    545       } while ((i < hMetaData->nAudioDataDelay) && (i >= 0));
    546 
    547       C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8));
    548     }
    549     FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
    550     hMetaData->metaDataDelayIdx = 0;
    551     hMetaData->initializeMetaData =
    552         1; /* fill up delay line with first meta data info */
    553   } else {
    554     /* Enable meta data. */
    555     if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) {
    556       /* disable meta data in all delay lines */
    557       for (i = 0;
    558            i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA));
    559            i++) {
    560         LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0,
    561                               &hMetaData->metaDataBuffer[i]);
    562       }
    563     }
    564 
    565     /* Disable meta data.*/
    566     if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) {
    567       hMetaData->finalizeMetaData = hMetaData->metadataMode;
    568     }
    569   }
    570 
    571   /* Initialize delay. */
    572   hMetaData->nAudioDataDelay = -delay;
    573   hMetaData->nMetaDataDelay = nFrames;
    574   hMetaData->nChannels = nChannels;
    575   hMetaData->channelMode = channelMode;
    576   hMetaData->metadataMode = metadataMode;
    577 
    578   /* Initialize compressor. */
    579   if ((metadataMode == 1) || (metadataMode == 2)) {
    580     if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE,
    581                                      frameLength, sampleRate, channelMode,
    582                                      channelOrder, 1) != 0) {
    583       err = METADATA_INIT_ERROR;
    584     }
    585   }
    586 bail:
    587   return err;
    588 }
    589 
    590 static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
    591                                             HDRC_COMP hDrcComp,
    592                                             const INT_PCM* const pSamples,
    593                                             const UINT samplesBufSize,
    594                                             const INT nSamples) {
    595   FDK_METADATA_ERROR err = METADATA_OK;
    596 
    597   INT dynrng, compr;
    598   INT dmxGain5, dmxGain2;
    599   DRC_PROFILE profileDrc;
    600   DRC_PROFILE profileComp;
    601 
    602   if ((pMetadata == NULL) || (hDrcComp == NULL)) {
    603     err = METADATA_INVALID_HANDLE;
    604     return err;
    605   }
    606 
    607   profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
    608   profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
    609 
    610   /* first, check if profile is same as last frame
    611    * otherwise, update setup */
    612   if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) ||
    613       (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) {
    614     FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
    615   }
    616 
    617   /* Sanity check */
    618   if (profileComp == DRC_NONE) {
    619     pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external
    620                                                         values will be written
    621                                                         if not configured */
    622   }
    623 
    624   /* in case of embedding external values, copy this now (limiter may overwrite
    625    * them) */
    626   dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0],
    627                         pMetadata->mpegDrc.dyn_rng_sgn[0]);
    628   compr = decodeCompr(pMetadata->etsiAncData.compression_value);
    629 
    630   dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
    631                           pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn);
    632   dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
    633                           pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn);
    634 
    635   /* Call compressor */
    636   if (FDK_DRC_Generator_Calc(
    637           hDrcComp, pSamples, samplesBufSize,
    638           progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
    639           pMetadata->mpegDrc.drc_TargetRefLevel,
    640           pMetadata->etsiAncData.comp_TargetRefLevel,
    641           dmxTable[pMetadata->centerMixLevel],
    642           dmxTable[pMetadata->surroundMixLevel],
    643           dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx],
    644           dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx],
    645           pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status
    646               ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx]
    647               : (FIXP_DBL)0,
    648           dmxGain5, dmxGain2, &dynrng, &compr) != 0) {
    649     err = METADATA_ENCODE_ERROR;
    650     goto bail;
    651   }
    652 
    653   /* Write DRC values */
    654   pMetadata->mpegDrc.drc_band_incr = 0;
    655   encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl,
    656                pMetadata->mpegDrc.dyn_rng_sgn);
    657   pMetadata->etsiAncData.compression_value = encodeCompr(compr);
    658 
    659 bail:
    660   return err;
    661 }
    662 
    663 FDK_METADATA_ERROR FDK_MetadataEnc_Process(
    664     HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
    665     const UINT audioSamplesBufSize, const INT nAudioSamples,
    666     const AACENC_MetaData* const pMetadata,
    667     AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions,
    668     INT* matrix_mixdown_idx) {
    669   FDK_METADATA_ERROR err = METADATA_OK;
    670   int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
    671 
    672   /* Where to write new meta data info */
    673   metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
    674 
    675   /* How to write the data */
    676   metadataMode = hMetaDataEnc->metadataMode;
    677 
    678   /* Compensate meta data delay. */
    679   hMetaDataEnc->metaDataDelayIdx++;
    680   if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay)
    681     hMetaDataEnc->metaDataDelayIdx = 0;
    682 
    683   /* Where to read pending meta data info from. */
    684   metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
    685 
    686   /* Submit new data if available. */
    687   if (pMetadata != NULL) {
    688     FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata,
    689               sizeof(AACENC_MetaData));
    690   }
    691 
    692   /* Write one additional frame with default configuration of meta data. Ensure
    693    * defined behaviour on decoder side. */
    694   if ((hMetaDataEnc->finalizeMetaData != 0) &&
    695       (hMetaDataEnc->metadataMode == 0)) {
    696     FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,
    697               sizeof(AACENC_MetaData));
    698     metadataMode = hMetaDataEnc->finalizeMetaData;
    699     hMetaDataEnc->finalizeMetaData = 0;
    700   }
    701 
    702   /* Get last submitted data. */
    703   if ((err = LoadSubmittedMetadata(
    704            &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
    705            metadataMode,
    706            &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) !=
    707       METADATA_OK) {
    708     goto bail;
    709   }
    710 
    711   /* Calculate compressor if necessary and updata meta data info */
    712   if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) ||
    713       (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) {
    714     if ((err = ProcessCompressor(
    715              &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
    716              hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize,
    717              nAudioSamples)) != METADATA_OK) {
    718       /* Get last submitted data again. */
    719       LoadSubmittedMetadata(
    720           &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
    721           metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
    722     }
    723   }
    724 
    725   /* Fill up delay line with initial meta data info.*/
    726   if ((hMetaDataEnc->initializeMetaData != 0) &&
    727       (hMetaDataEnc->metadataMode != 0)) {
    728     int i;
    729     for (i = 0;
    730          i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA));
    731          i++) {
    732       if (i != metaDataDelayWriteIdx) {
    733         FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i],
    734                   &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
    735                   sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]));
    736       }
    737     }
    738     hMetaDataEnc->initializeMetaData = 0;
    739   }
    740 
    741   /* Convert Meta Data side info to bitstream data. */
    742   FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES);
    743   if ((err = WriteMetadataPayload(
    744            hMetaDataEnc,
    745            &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) !=
    746       METADATA_OK) {
    747     goto bail;
    748   }
    749 
    750   /* Assign meta data to output */
    751   *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
    752   *nMetaDataExtensions = hMetaDataEnc->nExtensions;
    753   *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
    754 
    755 bail:
    756   /* Compensate audio delay, reset err status. */
    757   err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize,
    758                              nAudioSamples / hMetaDataEnc->nChannels);
    759 
    760   return err;
    761 }
    762 
    763 static FDK_METADATA_ERROR CompensateAudioDelay(
    764     HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
    765     const UINT audioSamplesBufSize, const INT nAudioSamples) {
    766   FDK_METADATA_ERROR err = METADATA_OK;
    767 
    768   if (hMetaDataEnc->nAudioDataDelay) {
    769     C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024);
    770 
    771     for (int c = 0; c < hMetaDataEnc->nChannels; c++) {
    772       int M = 1024;
    773       INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize;
    774       int delayIdx = hMetaDataEnc->nAudioDataDelay;
    775 
    776       do {
    777         M = fMin(M, delayIdx);
    778         delayIdx -= M;
    779 
    780         FDKmemcpy(&scratch_audioDelayBuffer[0],
    781                   &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M);
    782         FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0],
    783                    sizeof(INT_PCM) * (nAudioSamples - M));
    784         FDKmemcpy(
    785             &pAudioSamples2[0],
    786             &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
    787                                              c * hMetaDataEnc->nAudioDataDelay],
    788             sizeof(INT_PCM) * M);
    789         FDKmemcpy(
    790             &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
    791                                              c * hMetaDataEnc->nAudioDataDelay],
    792             &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M);
    793 
    794       } while (delayIdx > 0);
    795     }
    796 
    797     C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024);
    798   }
    799 
    800   return err;
    801 }
    802 
    803 /*-----------------------------------------------------------------------------
    804 
    805   functionname: WriteMetadataPayload
    806   description:  fills anc data and extension payload
    807   returns:      Error status
    808 
    809  ------------------------------------------------------------------------------*/
    810 static FDK_METADATA_ERROR WriteMetadataPayload(
    811     const HANDLE_FDK_METADATA_ENCODER hMetaData,
    812     const AAC_METADATA* const pMetadata) {
    813   FDK_METADATA_ERROR err = METADATA_OK;
    814 
    815   if ((hMetaData == NULL) || (pMetadata == NULL)) {
    816     err = METADATA_INVALID_HANDLE;
    817     goto bail;
    818   }
    819 
    820   hMetaData->nExtensions = 0;
    821   hMetaData->matrix_mixdown_idx = -1;
    822 
    823   if (pMetadata->metadataMode != 0) {
    824     /* AAC-DRC */
    825     if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) {
    826       hMetaData->exPayload[hMetaData->nExtensions].pData =
    827           hMetaData->drcInfoPayload;
    828       hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
    829       hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
    830 
    831       hMetaData->exPayload[hMetaData->nExtensions].dataSize =
    832           WriteDynamicRangeInfoPayload(
    833               pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
    834 
    835       hMetaData->nExtensions++;
    836     } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */
    837 
    838     /* Matrix Mixdown Coefficient in PCE */
    839     if (pMetadata->WritePCEMixDwnIdx) {
    840       hMetaData->matrix_mixdown_idx =
    841           surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
    842     }
    843 
    844     /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
    845     if ((pMetadata->metadataMode == 2) ||
    846         (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */
    847     {
    848       hMetaData->exPayload[hMetaData->nExtensions].pData =
    849           hMetaData->drcDsePayload;
    850       hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
    851       hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
    852 
    853       hMetaData->exPayload[hMetaData->nExtensions].dataSize =
    854           WriteEtsiAncillaryDataPayload(
    855               pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
    856 
    857       hMetaData->nExtensions++;
    858     } /* metadataMode==2 || metadataMode==3 */
    859 
    860   } /* metadataMode != 0 */
    861 
    862 bail:
    863   return err;
    864 }
    865 
    866 static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
    867                                         UCHAR* const pExtensionPayload) {
    868   const INT pce_tag_present = 0; /* yet fixed setting! */
    869   const INT prog_ref_lev_res_bits = 0;
    870   INT i, drc_num_bands = 1;
    871 
    872   FDK_BITSTREAM bsWriter;
    873   FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
    874 
    875   /* dynamic_range_info() */
    876   FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
    877   if (pce_tag_present) {
    878     FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
    879     FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
    880   }
    881 
    882   /* Exclude channels */
    883   FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0,
    884                1); /* excluded_chns_present*/
    885 
    886   /* Multiband DRC */
    887   FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0,
    888                1); /* drc_bands_present */
    889   if (pMetadata->mpegDrc.drc_bands_present) {
    890     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr,
    891                  4); /* drc_band_incr */
    892     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme,
    893                  4); /* drc_interpolation_scheme */
    894     drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
    895     for (i = 0; i < drc_num_bands; i++) {
    896       FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i],
    897                    8); /* drc_band_top */
    898     }
    899   }
    900 
    901   /* Program Reference Level */
    902   FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present,
    903                1); /* prog_ref_level_present */
    904   if (pMetadata->mpegDrc.prog_ref_level_present) {
    905     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level,
    906                  7); /* prog_ref_level */
    907     FDKwriteBits(&bsWriter, prog_ref_lev_res_bits,
    908                  1); /* prog_ref_level_reserved_bits */
    909   }
    910 
    911   /* DRC Values */
    912   for (i = 0; i < drc_num_bands; i++) {
    913     FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0,
    914                  1); /* dyn_rng_sgn[ */
    915     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i],
    916                  7); /* dyn_rng_ctl */
    917   }
    918 
    919   /* return number of valid bits in extension payload. */
    920   return FDKgetValidBits(&bsWriter);
    921 }
    922 
    923 static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
    924                                          UCHAR* const pExtensionPayload) {
    925   FDK_BITSTREAM bsWriter;
    926   FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
    927 
    928   /* ancillary_data_sync */
    929   FDKwriteBits(&bsWriter, 0xBC, 8);
    930 
    931   /* bs_info */
    932   FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
    933   FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode,
    934                2); /* dolby_surround_mode */
    935   FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode,
    936                2);                 /* DRC presentation mode */
    937   FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */
    938   FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */
    939 
    940   /* ancillary_data_status */
    941   FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
    942   FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0,
    943                1); /* downmixing_levels_MPEG4_status */
    944   FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus,
    945                1); /* ext_anc_data_status */
    946   FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0,
    947                1); /* audio_coding_mode_and_compression status */
    948   FDKwriteBits(&bsWriter,
    949                (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0,
    950                1); /* coarse_grain_timecode_status */
    951   FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0,
    952                1); /* fine_grain_timecode_status */
    953 
    954   /* downmixing_levels_MPEG4_status */
    955   if (pMetadata->DmxLvl_On) {
    956     FDKwriteBits(
    957         &bsWriter,
    958         encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel),
    959         8);
    960   }
    961 
    962   /* audio_coding_mode_and_compression_status */
    963   if (pMetadata->etsiAncData.compression_on) {
    964     FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
    965     FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value,
    966                  8); /* compression value */
    967   }
    968 
    969   /* grain-timecode coarse/fine */
    970   if (pMetadata->etsiAncData.timecode_coarse_status) {
    971     FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
    972   }
    973 
    974   if (pMetadata->etsiAncData.timecode_fine_status) {
    975     FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
    976   }
    977 
    978   /* extended ancillary data structure */
    979   if (pMetadata->etsiAncData.extAncDataStatus) {
    980     /* ext_ancillary_data_status */
    981     FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
    982     FDKwriteBits(&bsWriter,
    983                  pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status,
    984                  1); /* ext_downmixing_levels_status */
    985     FDKwriteBits(&bsWriter,
    986                  pMetadata->etsiAncData.extAncData.ext_downmix_gain_status,
    987                  1); /* ext_downmixing_global_gains_status */
    988     FDKwriteBits(&bsWriter,
    989                  pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status,
    990                  1);               /* ext_downmixing_lfe_level_status" */
    991     FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
    992 
    993     /* ext_downmixing_levels */
    994     if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) {
    995       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx,
    996                    3); /* dmix_a_idx */
    997       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx,
    998                    3);               /* dmix_b_idx */
    999       FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */
   1000     }
   1001 
   1002     /* ext_downmixing_gains */
   1003     if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) {
   1004       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn,
   1005                    1); /* dmx_gain_5_sign */
   1006       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
   1007                    6);               /* dmx_gain_5_idx */
   1008       FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
   1009       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn,
   1010                    1); /* dmx_gain_2_sign */
   1011       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
   1012                    6);               /* dmx_gain_2_idx */
   1013       FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
   1014     }
   1015 
   1016     if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) {
   1017       FDKwriteBits(&bsWriter,
   1018                    pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx,
   1019                    4);               /* dmix_lfe_idx */
   1020       FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
   1021     }
   1022   }
   1023 
   1024   return FDKgetValidBits(&bsWriter);
   1025 }
   1026 
   1027 static FDK_METADATA_ERROR LoadSubmittedMetadata(
   1028     const AACENC_MetaData* const hMetadata, const INT nChannels,
   1029     const INT metadataMode, AAC_METADATA* const pAacMetaData) {
   1030   FDK_METADATA_ERROR err = METADATA_OK;
   1031 
   1032   if (pAacMetaData == NULL) {
   1033     err = METADATA_INVALID_HANDLE;
   1034   } else {
   1035     /* init struct */
   1036     FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
   1037 
   1038     if (hMetadata != NULL) {
   1039       /* convert data */
   1040       pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
   1041       pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
   1042       pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
   1043       pAacMetaData->etsiAncData.comp_TargetRefLevel =
   1044           hMetadata->comp_TargetRefLevel;
   1045       pAacMetaData->mpegDrc.prog_ref_level_present =
   1046           hMetadata->prog_ref_level_present;
   1047       pAacMetaData->mpegDrc.prog_ref_level =
   1048           dialnorm2progreflvl(hMetadata->prog_ref_level);
   1049 
   1050       pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
   1051       pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
   1052       pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
   1053       pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
   1054 
   1055       pAacMetaData->etsiAncData.compression_on =
   1056           (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1);
   1057 
   1058       if (pAacMetaData->mpegDrc.drc_profile ==
   1059           AACENC_METADATA_DRC_NOT_PRESENT) {
   1060         pAacMetaData->mpegDrc.drc_profile =
   1061             AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are
   1062                                          always present in BS
   1063                                          syntax */
   1064         /* we should give a warning, but ErrorHandler does not support this */
   1065       }
   1066 
   1067       if (nChannels == 2) {
   1068         pAacMetaData->dolbySurroundMode =
   1069             hMetadata->dolbySurroundMode; /* dolby_surround_mode */
   1070       } else {
   1071         pAacMetaData->dolbySurroundMode = 0;
   1072       }
   1073 
   1074       pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode;
   1075       /* override external values if DVB DRC presentation mode is given */
   1076       if (pAacMetaData->drcPresentationMode == 1) {
   1077         pAacMetaData->mpegDrc.drc_TargetRefLevel =
   1078             fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
   1079         pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax(
   1080             -(20 << 16),
   1081             pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */
   1082       }
   1083       if (pAacMetaData->drcPresentationMode == 2) {
   1084         pAacMetaData->mpegDrc.drc_TargetRefLevel =
   1085             fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
   1086         pAacMetaData->etsiAncData.comp_TargetRefLevel =
   1087             fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel);
   1088       }
   1089       if (pAacMetaData->etsiAncData.comp_profile ==
   1090           AACENC_METADATA_DRC_NOT_PRESENT) {
   1091         /* DVB defines to revert to Light DRC if heavy is not present */
   1092         if (pAacMetaData->drcPresentationMode != 0) {
   1093           /* we exclude the "not indicated" mode as this requires the user to
   1094            * define desired levels anyway */
   1095           pAacMetaData->mpegDrc.drc_TargetRefLevel =
   1096               fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel,
   1097                    pAacMetaData->mpegDrc.drc_TargetRefLevel);
   1098         }
   1099       }
   1100 
   1101       pAacMetaData->etsiAncData.timecode_coarse_status =
   1102           0; /* not yet supported - attention: Update
   1103                 GetEstMetadataBytesPerFrame() if enable this! */
   1104       pAacMetaData->etsiAncData.timecode_fine_status =
   1105           0; /* not yet supported - attention: Update
   1106                 GetEstMetadataBytesPerFrame() if enable this! */
   1107 
   1108       /* extended ancillary data */
   1109       pAacMetaData->etsiAncData.extAncDataStatus =
   1110           ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0);
   1111 
   1112       if (pAacMetaData->etsiAncData.extAncDataStatus) {
   1113         pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status =
   1114             (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0);
   1115         pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status =
   1116             (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0);
   1117         pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status =
   1118             (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0);
   1119 
   1120         pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx =
   1121             hMetadata->ExtMetaData.extDownmixLevel_A;
   1122         pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx =
   1123             hMetadata->ExtMetaData.extDownmixLevel_B;
   1124 
   1125         if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) {
   1126           encodeDynrng(hMetadata->ExtMetaData.dmxGain5,
   1127                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
   1128                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
   1129           encodeDynrng(hMetadata->ExtMetaData.dmxGain2,
   1130                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
   1131                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
   1132         } else {
   1133           encodeDynrng(1 << 16,
   1134                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
   1135                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
   1136           encodeDynrng(1 << 16,
   1137                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
   1138                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
   1139         }
   1140 
   1141         if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) {
   1142           pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
   1143               hMetadata->ExtMetaData.lfeDmxLevel;
   1144         } else {
   1145           pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
   1146               15; /* -inf dB */
   1147         }
   1148       } else {
   1149         pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0;
   1150         pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0;
   1151         pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0;
   1152 
   1153         pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */
   1154         pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */
   1155 
   1156         encodeDynrng(1 << 16,
   1157                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
   1158                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
   1159         encodeDynrng(1 << 16,
   1160                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
   1161                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
   1162 
   1163         pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
   1164             15; /* -inf dB */
   1165       }
   1166 
   1167       pAacMetaData->metadataMode = metadataMode;
   1168     } else {
   1169       pAacMetaData->metadataMode = 0; /* there is no configuration available */
   1170     }
   1171   }
   1172 
   1173   return err;
   1174 }
   1175 
   1176 INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) {
   1177   INT delay = 0;
   1178 
   1179   if (hMetadataEnc != NULL) {
   1180     delay = hMetadataEnc->nAudioDataDelay;
   1181   }
   1182 
   1183   return delay;
   1184 }
   1185