/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:

You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.

You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------- */

/**************************** AAC encoder library ******************************

   Author(s):   V. Bacigalupo

   Description: Metadata Encoder library interface functions

*******************************************************************************/

#include "metadata_main.h"
#include "metadata_compressor.h"
#include "FDK_bitstream.h"
#include "FDK_audio.h"
#include "genericStds.h"

/*----------------- defines ----------------------*/
#define MAX_DRC_BANDS (1 << 4)
#define MAX_DRC_FRAMELEN (2 * 1024)
#define MAX_DELAY_FRAMES (3)

/*--------------- structure definitions --------------------*/

typedef struct AAC_METADATA {
  /* MPEG: Dynamic Range Control */
  struct {
    UCHAR prog_ref_level_present;
    SCHAR prog_ref_level;

    UCHAR dyn_rng_sgn[MAX_DRC_BANDS];
    UCHAR dyn_rng_ctl[MAX_DRC_BANDS];

    UCHAR drc_bands_present;
    UCHAR drc_band_incr;
    UCHAR drc_band_top[MAX_DRC_BANDS];
    UCHAR drc_interpolation_scheme;
    AACENC_METADATA_DRC_PROFILE drc_profile;
    INT drc_TargetRefLevel; /* used for Limiter */

    /* excluded channels */
    UCHAR excluded_chns_present;
    UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */
  } mpegDrc;

  /* ETSI: addtl ancillary data */
  struct {
    /* Heavy Compression */
    UCHAR compression_on;    /* flag, if compression value should be written */
    UCHAR compression_value; /* compression value */
    AACENC_METADATA_DRC_PROFILE comp_profile;
    INT comp_TargetRefLevel; /* used for Limiter */
    INT timecode_coarse_status;
    INT timecode_fine_status;

    UCHAR extAncDataStatus;

    struct {
      UCHAR ext_downmix_lvl_status;
      UCHAR ext_downmix_gain_status;
      UCHAR ext_lfe_downmix_status;
      UCHAR
      ext_dmix_a_idx; /* extended downmix level (0..7, according to table)
                       */
      UCHAR
      ext_dmix_b_idx; /* extended downmix level (0..7, according to table)
                       */
      UCHAR dmx_gain_5_sgn;
      UCHAR dmx_gain_5_idx;
      UCHAR dmx_gain_2_sgn;
      UCHAR dmx_gain_2_idx;
      UCHAR ext_dmix_lfe_idx; /* extended downmix level for lfe (0..15,
                                 according to table) */

    } extAncData;

  } etsiAncData;

  SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */
  SCHAR
  surroundMixLevel; /* surround downmix level (0...7, according to table) */
  UCHAR WritePCEMixDwnIdx; /* flag */
  UCHAR DmxLvl_On;         /* flag */

  UCHAR dolbySurroundMode;
  UCHAR drcPresentationMode;

  UCHAR
  metadataMode; /* indicate meta data mode in current frame (delay line) */

} AAC_METADATA;

typedef struct FDK_METADATA_ENCODER {
  INT metadataMode;
  HDRC_COMP hDrcComp;
  AACENC_MetaData submittedMetaData;

  INT nAudioDataDelay; /* Additional delay to round up to next frame border (in
                          samples) */
  INT nMetaDataDelay;  /* Meta data delay (in frames) */
  INT nChannels;
  CHANNEL_MODE channelMode;

  INT_PCM* pAudioDelayBuffer;

  AAC_METADATA metaDataBuffer[MAX_DELAY_FRAMES];
  INT metaDataDelayIdx;

  UCHAR drcInfoPayload[12];
  UCHAR drcDsePayload[8];

  INT matrix_mixdown_idx;

  AACENC_EXT_PAYLOAD exPayload[2];
  INT nExtensions;

  UINT maxChannels; /* Maximum number of audio channels to be supported. */

  INT finalizeMetaData;   /* Delay switch off by one frame and write default
                             configuration to   finalize the metadata setup. */
  INT initializeMetaData; /* Fill up delay line with first meta data info. This
                             is required to have meta data already in first
                             frame. */
} FDK_METADATA_ENCODER;

/*---------------- constants -----------------------*/
static const AACENC_MetaData defaultMetaDataSetup = {
    AACENC_METADATA_DRC_NONE,        /* drc_profile */
    AACENC_METADATA_DRC_NOT_PRESENT, /* comp_profile */
    -(31 << 16),                     /* drc_TargetRefLevel */
    -(23 << 16),                     /* comp_TargetRefLevel */
    0,                               /* prog_ref_level_present */
    -(23 << 16),                     /* prog_ref_level */
    0,                               /* PCE_mixdown_idx_present */
    0,                               /* ETSI_DmxLvl_present */
    0,                               /* centerMixLevel */
    0,                               /* surroundMixLevel */
    0,                               /* dolbySurroundMode */
    0,                               /* drcPresentationMode */
    {0, 0, 0, 0, 0, 0, 0, 0, 0}      /* ExtMetaData */
};

static const FIXP_DBL dmxTable[8] = {
    ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f),
    FL2FXCONST_DBL(0.596f), FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f),
    FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)};

#define FL2DMXLFE(a) FL2FXCONST_DBL((a) / (1 << LFE_LEV_SCALE))
static const FIXP_DBL dmxLfeTable[16] = {
    FL2DMXLFE(3.162f), FL2DMXLFE(2.000f), FL2DMXLFE(1.679f), FL2DMXLFE(1.413f),
    FL2DMXLFE(1.189f), FL2DMXLFE(1.000f), FL2DMXLFE(0.841f), FL2DMXLFE(0.707f),
    FL2DMXLFE(0.596f), FL2DMXLFE(0.500f), FL2DMXLFE(0.316f), FL2DMXLFE(0.178f),
    FL2DMXLFE(0.100f), FL2DMXLFE(0.032f), FL2DMXLFE(0.010f), FL2DMXLFE(0.000f)};

static const UCHAR surmix2matrix_mixdown_idx[8] = {0, 0, 0, 1, 1, 2, 2, 3};

/*--------------- function declarations --------------------*/
static FDK_METADATA_ERROR WriteMetadataPayload(
    const HANDLE_FDK_METADATA_ENCODER hMetaData,
    const AAC_METADATA* const pMetadata);

static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
                                        UCHAR* const pExtensionPayload);

static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
                                         UCHAR* const pExtensionPayload);

static FDK_METADATA_ERROR CompensateAudioDelay(
    HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
    const UINT audioSamplesBufSize, const INT nAudioSamples);

static FDK_METADATA_ERROR LoadSubmittedMetadata(
    const AACENC_MetaData* const hMetadata, const INT nChannels,
    const INT metadataMode, AAC_METADATA* const pAacMetaData);

static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
                                            HDRC_COMP hDrcComp,
                                            const INT_PCM* const pSamples,
                                            const UINT samplesBufSize,
                                            const INT nSamples);

/*------------- function definitions ----------------*/

static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) {
  DRC_PROFILE drcProfile = DRC_NONE;

  switch (aacProfile) {
    case AACENC_METADATA_DRC_NONE:
      drcProfile = DRC_NONE;
      break;
    case AACENC_METADATA_DRC_FILMSTANDARD:
      drcProfile = DRC_FILMSTANDARD;
      break;
    case AACENC_METADATA_DRC_FILMLIGHT:
      drcProfile = DRC_FILMLIGHT;
      break;
    case AACENC_METADATA_DRC_MUSICSTANDARD:
      drcProfile = DRC_MUSICSTANDARD;
      break;
    case AACENC_METADATA_DRC_MUSICLIGHT:
      drcProfile = DRC_MUSICLIGHT;
      break;
    case AACENC_METADATA_DRC_SPEECH:
      drcProfile = DRC_SPEECH;
      break;
    case AACENC_METADATA_DRC_NOT_PRESENT:
      drcProfile = DRC_NOT_PRESENT;
      break;
    default:
      drcProfile = DRC_NONE;
      break;
  }
  return drcProfile;
}

/* convert dialog normalization to program reference level */
/* NOTE: this only is correct, if the decoder target level is set to -31dB for
 * line mode / -20dB for RF mode */
static UCHAR dialnorm2progreflvl(const INT d) {
  return ((UCHAR)fMax(0, fMin((-d + (1 << 13)) >> 14, 127)));
}

/* convert program reference level to dialog normalization */
static INT progreflvl2dialnorm(const UCHAR p) {
  return -((INT)(p << (16 - 2)));
}

/* encode downmix levels to Downmixing_levels_MPEG4 */
static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) {
  SCHAR dmxLvls = 0;
  dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
  dmxLvls |= 0x08 | surmixlev;      /* surround_mix_level_on */

  return dmxLvls;
}

/* encode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl,
                         UCHAR* const dyn_rng_sgn) {
  if (gain < 0) {
    *dyn_rng_sgn = 1;
    gain = -gain;
  } else {
    *dyn_rng_sgn = 0;
  }
  gain = fMin(gain, (127 << 14));

  *dyn_rng_ctl = (UCHAR)((gain + (1 << 13)) >> 14);
}

/* decode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) {
  INT tmp = ((INT)dyn_rng_ctl << (16 - 2));
  if (dyn_rng_sgn) tmp = -tmp;

  return tmp;
}

/* encode AAC compression value (ETSI TS 101 154 page 99) */
static UCHAR encodeCompr(INT gain) {
  UCHAR x, y;
  INT tmp;

  /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
  tmp = ((3156476 - gain) * 15 + 197283) / 394566;

  if (tmp >= 240) {
    return 0xFF;
  } else if (tmp < 0) {
    return 0;
  } else {
    x = tmp / 15;
    y = tmp % 15;
  }

  return (x << 4) | y;
}

/* decode AAC compression value (ETSI TS 101 154 page 99) */
static INT decodeCompr(const UCHAR compr) {
  INT gain;
  SCHAR x = compr >> 4;     /* 4 MSB of compr */
  UCHAR y = (compr & 0x0F); /* 4 LSB of compr */

  /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
  gain = (INT)(
      scaleValue((FIXP_DBL)(((LONG)FL2FXCONST_DBL(6.0206f / 128.f) * (8 - x) -
                             (LONG)FL2FXCONST_DBL(0.4014f / 128.f) * y)),
                 -(DFRACT_BITS - 1 - 7 - 16)));

  return gain;
}

FDK_METADATA_ERROR FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER* phMetaData,
                                        const UINT maxChannels) {
  FDK_METADATA_ERROR err = METADATA_OK;
  HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;

  if (phMetaData == NULL) {
    err = METADATA_INVALID_HANDLE;
    goto bail;
  }

  /* allocate memory */
  if (NULL == (hMetaData = (HANDLE_FDK_METADATA_ENCODER)FDKcalloc(
                   1, sizeof(FDK_METADATA_ENCODER)))) {
    err = METADATA_MEMORY_ERROR;
    goto bail;
  }
  FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));

  if (NULL == (hMetaData->pAudioDelayBuffer = (INT_PCM*)FDKcalloc(
                   maxChannels * MAX_DRC_FRAMELEN, sizeof(INT_PCM)))) {
    err = METADATA_MEMORY_ERROR;
    goto bail;
  }
  FDKmemclear(hMetaData->pAudioDelayBuffer,
              maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
  hMetaData->maxChannels = maxChannels;

  /* Allocate DRC Compressor. */
  if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp) != 0) {
    err = METADATA_MEMORY_ERROR;
    goto bail;
  }
  hMetaData->channelMode = MODE_UNKNOWN;

  /* Return metadata instance */
  *phMetaData = hMetaData;

  return err;

bail:
  FDK_MetadataEnc_Close(&hMetaData);
  return err;
}

FDK_METADATA_ERROR FDK_MetadataEnc_Close(
    HANDLE_FDK_METADATA_ENCODER* phMetaData) {
  FDK_METADATA_ERROR err = METADATA_OK;

  if (phMetaData == NULL) {
    err = METADATA_INVALID_HANDLE;
    goto bail;
  }

  if (*phMetaData != NULL) {
    FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
    FDKfree((*phMetaData)->pAudioDelayBuffer);
    FDKfree(*phMetaData);
    *phMetaData = NULL;
  }
bail:
  return err;
}

FDK_METADATA_ERROR FDK_MetadataEnc_Init(
    HANDLE_FDK_METADATA_ENCODER hMetaData, const INT resetStates,
    const INT metadataMode, const INT audioDelay, const UINT frameLength,
    const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode,
    const CHANNEL_ORDER channelOrder) {
  FDK_METADATA_ERROR err = METADATA_OK;
  int i, nFrames, delay;

  if (hMetaData == NULL) {
    err = METADATA_INVALID_HANDLE;
    goto bail;
  }

  /* Determine values for delay compensation. */
  for (nFrames = 0, delay = audioDelay - (INT)frameLength; delay > 0;
       delay -= (INT)frameLength, nFrames++)
    ;

  if ((nChannels > (8)) || (nChannels > hMetaData->maxChannels) ||
      ((-delay) > MAX_DRC_FRAMELEN) || nFrames >= MAX_DELAY_FRAMES) {
    err = METADATA_INIT_ERROR;
    goto bail;
  }

  /* Initialize with default setup. */
  FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup,
            sizeof(AACENC_MetaData));

  hMetaData->finalizeMetaData =
      0; /* finalize meta data only while on/off switching, else disabled */
  hMetaData->initializeMetaData =
      0; /* fill up meta data delay line only at a reset otherwise disabled */

  /* Reset delay lines. */
  if (resetStates || (hMetaData->nAudioDataDelay != -delay) ||
      (hMetaData->channelMode != channelMode)) {
    if (resetStates || (hMetaData->channelMode == MODE_UNKNOWN)) {
      /* clear delay buffer */
      FDKmemclear(hMetaData->pAudioDelayBuffer,
                  hMetaData->maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
    } else {
      /* if possible, keep static audio channels for seamless channel
       * reconfiguration */
      FDK_channelMapDescr mapDescrPrev, mapDescr;
      int c, src[2] = {-1, -1}, dst[2] = {-1, -1};

      FDK_chMapDescr_init(&mapDescrPrev, NULL, 0,
                          (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
      FDK_chMapDescr_init(&mapDescr, NULL, 0,
                          (channelOrder == CH_ORDER_MPEG) ? 1 : 0);

      switch (channelMode) {
        case MODE_1:
          if ((INT)nChannels != 2) {
            /* preserve center channel */
            src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0,
                                                hMetaData->channelMode);
            dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode);
          }
          break;
        case MODE_2:
        case MODE_1_2:
        case MODE_1_2_1:
        case MODE_1_2_2:
        case MODE_1_2_2_1:
          if (hMetaData->nChannels >= 2) {
            /* preserve left/right channel */
            src[0] = FDK_chMapDescr_getMapValue(
                &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1),
                hMetaData->channelMode);
            src[1] = FDK_chMapDescr_getMapValue(
                &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2),
                hMetaData->channelMode);
            dst[0] = FDK_chMapDescr_getMapValue(
                &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode);
            dst[1] = FDK_chMapDescr_getMapValue(
                &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode);
          }
          break;
        default:;
      }
      C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8));
      FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM));

      i = (hMetaData->nChannels > (INT)nChannels)
              ? 0
              : hMetaData->nAudioDataDelay - 1;
      do {
        for (c = 0; c < 2; c++) {
          if (src[c] != -1 && dst[c] != -1) {
            scratch_audioDelayBuffer[dst[c]] =
                hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]];
          }
        }
        FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels],
                  scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM));
        i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1;
      } while ((i < hMetaData->nAudioDataDelay) && (i >= 0));

      C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8));
    }
    FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
    hMetaData->metaDataDelayIdx = 0;
    hMetaData->initializeMetaData =
        1; /* fill up delay line with first meta data info */
  } else {
    /* Enable meta data. */
    if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) {
      /* disable meta data in all delay lines */
      for (i = 0;
           i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA));
           i++) {
        LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0,
                              &hMetaData->metaDataBuffer[i]);
      }
    }

    /* Disable meta data.*/
    if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) {
      hMetaData->finalizeMetaData = hMetaData->metadataMode;
    }
  }

  /* Initialize delay. */
  hMetaData->nAudioDataDelay = -delay;
  hMetaData->nMetaDataDelay = nFrames;
  hMetaData->nChannels = nChannels;
  hMetaData->channelMode = channelMode;
  hMetaData->metadataMode = metadataMode;

  /* Initialize compressor. */
  if ((metadataMode == 1) || (metadataMode == 2)) {
    if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE,
                                     frameLength, sampleRate, channelMode,
                                     channelOrder, 1) != 0) {
      err = METADATA_INIT_ERROR;
    }
  }
bail:
  return err;
}

static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
                                            HDRC_COMP hDrcComp,
                                            const INT_PCM* const pSamples,
                                            const UINT samplesBufSize,
                                            const INT nSamples) {
  FDK_METADATA_ERROR err = METADATA_OK;

  INT dynrng, compr;
  INT dmxGain5, dmxGain2;
  DRC_PROFILE profileDrc;
  DRC_PROFILE profileComp;

  if ((pMetadata == NULL) || (hDrcComp == NULL)) {
    err = METADATA_INVALID_HANDLE;
    return err;
  }

  profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
  profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);

  /* first, check if profile is same as last frame
   * otherwise, update setup */
  if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) ||
      (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) {
    FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
  }

  /* Sanity check */
  if (profileComp == DRC_NONE) {
    pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external
                                                        values will be written
                                                        if not configured */
  }

  /* in case of embedding external values, copy this now (limiter may overwrite
   * them) */
  dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0],
                        pMetadata->mpegDrc.dyn_rng_sgn[0]);
  compr = decodeCompr(pMetadata->etsiAncData.compression_value);

  dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
                          pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn);
  dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
                          pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn);

  /* Call compressor */
  if (FDK_DRC_Generator_Calc(
          hDrcComp, pSamples, samplesBufSize,
          progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
          pMetadata->mpegDrc.drc_TargetRefLevel,
          pMetadata->etsiAncData.comp_TargetRefLevel,
          dmxTable[pMetadata->centerMixLevel],
          dmxTable[pMetadata->surroundMixLevel],
          dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx],
          dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx],
          pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status
              ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx]
              : (FIXP_DBL)0,
          dmxGain5, dmxGain2, &dynrng, &compr) != 0) {
    err = METADATA_ENCODE_ERROR;
    goto bail;
  }

  /* Write DRC values */
  pMetadata->mpegDrc.drc_band_incr = 0;
  encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl,
               pMetadata->mpegDrc.dyn_rng_sgn);
  pMetadata->etsiAncData.compression_value = encodeCompr(compr);

bail:
  return err;
}

FDK_METADATA_ERROR FDK_MetadataEnc_Process(
    HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
    const UINT audioSamplesBufSize, const INT nAudioSamples,
    const AACENC_MetaData* const pMetadata,
    AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions,
    INT* matrix_mixdown_idx) {
  FDK_METADATA_ERROR err = METADATA_OK;
  int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;

  /* Where to write new meta data info */
  metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;

  /* How to write the data */
  metadataMode = hMetaDataEnc->metadataMode;

  /* Compensate meta data delay. */
  hMetaDataEnc->metaDataDelayIdx++;
  if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay)
    hMetaDataEnc->metaDataDelayIdx = 0;

  /* Where to read pending meta data info from. */
  metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;

  /* Submit new data if available. */
  if (pMetadata != NULL) {
    FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata,
              sizeof(AACENC_MetaData));
  }

  /* Write one additional frame with default configuration of meta data. Ensure
   * defined behaviour on decoder side. */
  if ((hMetaDataEnc->finalizeMetaData != 0) &&
      (hMetaDataEnc->metadataMode == 0)) {
    FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,
              sizeof(AACENC_MetaData));
    metadataMode = hMetaDataEnc->finalizeMetaData;
    hMetaDataEnc->finalizeMetaData = 0;
  }

  /* Get last submitted data. */
  if ((err = LoadSubmittedMetadata(
           &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
           metadataMode,
           &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) !=
      METADATA_OK) {
    goto bail;
  }

  /* Calculate compressor if necessary and updata meta data info */
  if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) ||
      (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) {
    if ((err = ProcessCompressor(
             &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
             hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize,
             nAudioSamples)) != METADATA_OK) {
      /* Get last submitted data again. */
      LoadSubmittedMetadata(
          &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
          metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
    }
  }

  /* Fill up delay line with initial meta data info.*/
  if ((hMetaDataEnc->initializeMetaData != 0) &&
      (hMetaDataEnc->metadataMode != 0)) {
    int i;
    for (i = 0;
         i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA));
         i++) {
      if (i != metaDataDelayWriteIdx) {
        FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i],
                  &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
                  sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]));
      }
    }
    hMetaDataEnc->initializeMetaData = 0;
  }

  /* Convert Meta Data side info to bitstream data. */
  FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES);
  if ((err = WriteMetadataPayload(
           hMetaDataEnc,
           &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) !=
      METADATA_OK) {
    goto bail;
  }

  /* Assign meta data to output */
  *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
  *nMetaDataExtensions = hMetaDataEnc->nExtensions;
  *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;

bail:
  /* Compensate audio delay, reset err status. */
  err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize,
                             nAudioSamples / hMetaDataEnc->nChannels);

  return err;
}

static FDK_METADATA_ERROR CompensateAudioDelay(
    HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
    const UINT audioSamplesBufSize, const INT nAudioSamples) {
  FDK_METADATA_ERROR err = METADATA_OK;

  if (hMetaDataEnc->nAudioDataDelay) {
    C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024);

    for (int c = 0; c < hMetaDataEnc->nChannels; c++) {
      int M = 1024;
      INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize;
      int delayIdx = hMetaDataEnc->nAudioDataDelay;

      do {
        M = fMin(M, delayIdx);
        delayIdx -= M;

        FDKmemcpy(&scratch_audioDelayBuffer[0],
                  &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M);
        FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0],
                   sizeof(INT_PCM) * (nAudioSamples - M));
        FDKmemcpy(
            &pAudioSamples2[0],
            &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
                                             c * hMetaDataEnc->nAudioDataDelay],
            sizeof(INT_PCM) * M);
        FDKmemcpy(
            &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
                                             c * hMetaDataEnc->nAudioDataDelay],
            &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M);

      } while (delayIdx > 0);
    }

    C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024);
  }

  return err;
}

/*-----------------------------------------------------------------------------

  functionname: WriteMetadataPayload
  description:  fills anc data and extension payload
  returns:      Error status

 ------------------------------------------------------------------------------*/
static FDK_METADATA_ERROR WriteMetadataPayload(
    const HANDLE_FDK_METADATA_ENCODER hMetaData,
    const AAC_METADATA* const pMetadata) {
  FDK_METADATA_ERROR err = METADATA_OK;

  if ((hMetaData == NULL) || (pMetadata == NULL)) {
    err = METADATA_INVALID_HANDLE;
    goto bail;
  }

  hMetaData->nExtensions = 0;
  hMetaData->matrix_mixdown_idx = -1;

  if (pMetadata->metadataMode != 0) {
    /* AAC-DRC */
    if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) {
      hMetaData->exPayload[hMetaData->nExtensions].pData =
          hMetaData->drcInfoPayload;
      hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
      hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;

      hMetaData->exPayload[hMetaData->nExtensions].dataSize =
          WriteDynamicRangeInfoPayload(
              pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);

      hMetaData->nExtensions++;
    } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */

    /* Matrix Mixdown Coefficient in PCE */
    if (pMetadata->WritePCEMixDwnIdx) {
      hMetaData->matrix_mixdown_idx =
          surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
    }

    /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
    if ((pMetadata->metadataMode == 2) ||
        (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */
    {
      hMetaData->exPayload[hMetaData->nExtensions].pData =
          hMetaData->drcDsePayload;
      hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
      hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;

      hMetaData->exPayload[hMetaData->nExtensions].dataSize =
          WriteEtsiAncillaryDataPayload(
              pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);

      hMetaData->nExtensions++;
    } /* metadataMode==2 || metadataMode==3 */

  } /* metadataMode != 0 */

bail:
  return err;
}

static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
                                        UCHAR* const pExtensionPayload) {
  const INT pce_tag_present = 0; /* yet fixed setting! */
  const INT prog_ref_lev_res_bits = 0;
  INT i, drc_num_bands = 1;

  FDK_BITSTREAM bsWriter;
  FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);

  /* dynamic_range_info() */
  FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
  if (pce_tag_present) {
    FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
    FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
  }

  /* Exclude channels */
  FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0,
               1); /* excluded_chns_present*/

  /* Multiband DRC */
  FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0,
               1); /* drc_bands_present */
  if (pMetadata->mpegDrc.drc_bands_present) {
    FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr,
                 4); /* drc_band_incr */
    FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme,
                 4); /* drc_interpolation_scheme */
    drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
    for (i = 0; i < drc_num_bands; i++) {
      FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i],
                   8); /* drc_band_top */
    }
  }

  /* Program Reference Level */
  FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present,
               1); /* prog_ref_level_present */
  if (pMetadata->mpegDrc.prog_ref_level_present) {
    FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level,
                 7); /* prog_ref_level */
    FDKwriteBits(&bsWriter, prog_ref_lev_res_bits,
                 1); /* prog_ref_level_reserved_bits */
  }

  /* DRC Values */
  for (i = 0; i < drc_num_bands; i++) {
    FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0,
                 1); /* dyn_rng_sgn[ */
    FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i],
                 7); /* dyn_rng_ctl */
  }

  /* return number of valid bits in extension payload. */
  return FDKgetValidBits(&bsWriter);
}

static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
                                         UCHAR* const pExtensionPayload) {
  FDK_BITSTREAM bsWriter;
  FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);

  /* ancillary_data_sync */
  FDKwriteBits(&bsWriter, 0xBC, 8);

  /* bs_info */
  FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
  FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode,
               2); /* dolby_surround_mode */
  FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode,
               2);                 /* DRC presentation mode */
  FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */
  FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */

  /* ancillary_data_status */
  FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
  FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0,
               1); /* downmixing_levels_MPEG4_status */
  FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus,
               1); /* ext_anc_data_status */
  FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0,
               1); /* audio_coding_mode_and_compression status */
  FDKwriteBits(&bsWriter,
               (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0,
               1); /* coarse_grain_timecode_status */
  FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0,
               1); /* fine_grain_timecode_status */

  /* downmixing_levels_MPEG4_status */
  if (pMetadata->DmxLvl_On) {
    FDKwriteBits(
        &bsWriter,
        encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel),
        8);
  }

  /* audio_coding_mode_and_compression_status */
  if (pMetadata->etsiAncData.compression_on) {
    FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
    FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value,
                 8); /* compression value */
  }

  /* grain-timecode coarse/fine */
  if (pMetadata->etsiAncData.timecode_coarse_status) {
    FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
  }

  if (pMetadata->etsiAncData.timecode_fine_status) {
    FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
  }

  /* extended ancillary data structure */
  if (pMetadata->etsiAncData.extAncDataStatus) {
    /* ext_ancillary_data_status */
    FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
    FDKwriteBits(&bsWriter,
                 pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status,
                 1); /* ext_downmixing_levels_status */
    FDKwriteBits(&bsWriter,
                 pMetadata->etsiAncData.extAncData.ext_downmix_gain_status,
                 1); /* ext_downmixing_global_gains_status */
    FDKwriteBits(&bsWriter,
                 pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status,
                 1);               /* ext_downmixing_lfe_level_status" */
    FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */

    /* ext_downmixing_levels */
    if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) {
      FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx,
                   3); /* dmix_a_idx */
      FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx,
                   3);               /* dmix_b_idx */
      FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */
    }

    /* ext_downmixing_gains */
    if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) {
      FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn,
                   1); /* dmx_gain_5_sign */
      FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
                   6);               /* dmx_gain_5_idx */
      FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
      FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn,
                   1); /* dmx_gain_2_sign */
      FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
                   6);               /* dmx_gain_2_idx */
      FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
    }

    if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) {
      FDKwriteBits(&bsWriter,
                   pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx,
                   4);               /* dmix_lfe_idx */
      FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
    }
  }

  return FDKgetValidBits(&bsWriter);
}

static FDK_METADATA_ERROR LoadSubmittedMetadata(
    const AACENC_MetaData* const hMetadata, const INT nChannels,
    const INT metadataMode, AAC_METADATA* const pAacMetaData) {
  FDK_METADATA_ERROR err = METADATA_OK;

  if (pAacMetaData == NULL) {
    err = METADATA_INVALID_HANDLE;
  } else {
    /* init struct */
    FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));

    if (hMetadata != NULL) {
      /* convert data */
      pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
      pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
      pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
      pAacMetaData->etsiAncData.comp_TargetRefLevel =
          hMetadata->comp_TargetRefLevel;
      pAacMetaData->mpegDrc.prog_ref_level_present =
          hMetadata->prog_ref_level_present;
      pAacMetaData->mpegDrc.prog_ref_level =
          dialnorm2progreflvl(hMetadata->prog_ref_level);

      pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
      pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
      pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
      pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;

      pAacMetaData->etsiAncData.compression_on =
          (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1);

      if (pAacMetaData->mpegDrc.drc_profile ==
          AACENC_METADATA_DRC_NOT_PRESENT) {
        pAacMetaData->mpegDrc.drc_profile =
            AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are
                                         always present in BS
                                         syntax */
        /* we should give a warning, but ErrorHandler does not support this */
      }

      if (nChannels == 2) {
        pAacMetaData->dolbySurroundMode =
            hMetadata->dolbySurroundMode; /* dolby_surround_mode */
      } else {
        pAacMetaData->dolbySurroundMode = 0;
      }

      pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode;
      /* override external values if DVB DRC presentation mode is given */
      if (pAacMetaData->drcPresentationMode == 1) {
        pAacMetaData->mpegDrc.drc_TargetRefLevel =
            fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
        pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax(
            -(20 << 16),
            pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */
      }
      if (pAacMetaData->drcPresentationMode == 2) {
        pAacMetaData->mpegDrc.drc_TargetRefLevel =
            fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
        pAacMetaData->etsiAncData.comp_TargetRefLevel =
            fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel);
      }
      if (pAacMetaData->etsiAncData.comp_profile ==
          AACENC_METADATA_DRC_NOT_PRESENT) {
        /* DVB defines to revert to Light DRC if heavy is not present */
        if (pAacMetaData->drcPresentationMode != 0) {
          /* we exclude the "not indicated" mode as this requires the user to
           * define desired levels anyway */
          pAacMetaData->mpegDrc.drc_TargetRefLevel =
              fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel,
                   pAacMetaData->mpegDrc.drc_TargetRefLevel);
        }
      }

      pAacMetaData->etsiAncData.timecode_coarse_status =
          0; /* not yet supported - attention: Update
                GetEstMetadataBytesPerFrame() if enable this! */
      pAacMetaData->etsiAncData.timecode_fine_status =
          0; /* not yet supported - attention: Update
                GetEstMetadataBytesPerFrame() if enable this! */

      /* extended ancillary data */
      pAacMetaData->etsiAncData.extAncDataStatus =
          ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0);

      if (pAacMetaData->etsiAncData.extAncDataStatus) {
        pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status =
            (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0);
        pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status =
            (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0);
        pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status =
            (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0);

        pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx =
            hMetadata->ExtMetaData.extDownmixLevel_A;
        pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx =
            hMetadata->ExtMetaData.extDownmixLevel_B;

        if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) {
          encodeDynrng(hMetadata->ExtMetaData.dmxGain5,
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
          encodeDynrng(hMetadata->ExtMetaData.dmxGain2,
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
        } else {
          encodeDynrng(1 << 16,
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
          encodeDynrng(1 << 16,
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
                       &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
        }

        if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) {
          pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
              hMetadata->ExtMetaData.lfeDmxLevel;
        } else {
          pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
              15; /* -inf dB */
        }
      } else {
        pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0;
        pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0;
        pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0;

        pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */
        pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */

        encodeDynrng(1 << 16,
                     &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
                     &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
        encodeDynrng(1 << 16,
                     &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
                     &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));

        pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
            15; /* -inf dB */
      }

      pAacMetaData->metadataMode = metadataMode;
    } else {
      pAacMetaData->metadataMode = 0; /* there is no configuration available */
    }
  }

  return err;
}

INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) {
  INT delay = 0;

  if (hMetadataEnc != NULL) {
    delay = hMetadataEnc->nAudioDataDelay;
  }

  return delay;
}
