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

© Copyright  1995 - 2019 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):   M. Lohwasser

   Description: FDK HE-AAC Encoder interface library functions

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

#include "aacenc_lib.h"
#include "FDK_audio.h"
#include "aacenc.h"

#include "aacEnc_ram.h"
#include "FDK_core.h" /* FDK_tools versioning info */

/* Encoder library info */
#define AACENCODER_LIB_VL0 4
#define AACENCODER_LIB_VL1 0
#define AACENCODER_LIB_VL2 0
#define AACENCODER_LIB_TITLE "AAC Encoder"
#ifdef SUPPRESS_BUILD_DATE_INFO
#define AACENCODER_LIB_BUILD_DATE ""
#define AACENCODER_LIB_BUILD_TIME ""
#else
#define AACENCODER_LIB_BUILD_DATE __DATE__
#define AACENCODER_LIB_BUILD_TIME __TIME__
#endif

#include "pcm_utils.h"

#include "sbr_encoder.h"
#include "../src/sbrenc_ram.h"
#include "channel_map.h"

#include "psy_const.h"
#include "bitenc.h"

#include "tpenc_lib.h"

#include "metadata_main.h"
#include "mps_main.h"
#include "sacenc_lib.h"

#define SBL(fl) \
  (fl /         \
   8) /*!< Short block length (hardcoded to 8 short blocks per long block) */
#define BSLA(fl) \
  (4 * SBL(fl) + SBL(fl) / 2)         /*!< AAC block switching look-ahead */
#define DELAY_AAC(fl) (fl + BSLA(fl)) /*!< MDCT + blockswitching */
#define DELAY_AACLD(fl) (fl) /*!< MDCT delay (no framing delay included) */
#define DELAY_AACELD(fl) \
  ((fl) / 2) /*!< ELD FB delay (no framing delay included) */

#define MAX_DS_DELAY (100) /*!< Maximum downsampler delay in SBR. */
#define INPUTBUFFER_SIZE                                                    \
  (2 * (1024) + MAX_DS_DELAY + 1537) /*!< Audio input samples + downsampler \
                                        delay + sbr/aac delay compensation */

#define DEFAULT_HEADER_PERIOD_REPETITION_RATE                                  \
  10 /*!< Default header repetition rate used in transport library and for SBR \
        header. */

////////////////////////////////////////////////////////////////////////////////////
/**
 * Flags to characterize encoder modules to be supported in present instance.
 */
enum {
  ENC_MODE_FLAG_AAC = 0x0001,
  ENC_MODE_FLAG_SBR = 0x0002,
  ENC_MODE_FLAG_PS = 0x0004,
  ENC_MODE_FLAG_SAC = 0x0008,
  ENC_MODE_FLAG_META = 0x0010
};

////////////////////////////////////////////////////////////////////////////////////
typedef struct {
  AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type.             */
  UINT userSamplerate;       /*!< Sampling frequency.            */
  UINT nChannels;            /*!< will be set via channelMode.   */
  CHANNEL_MODE userChannelMode;
  UINT userBitrate;
  UINT userBitrateMode;
  UINT userBandwidth;
  UINT userAfterburner;
  UINT userFramelength;
  UINT userAncDataRate;
  UINT userPeakBitrate;

  UCHAR userTns;       /*!< Use TNS coding. */
  UCHAR userPns;       /*!< Use PNS coding. */
  UCHAR userIntensity; /*!< Use Intensity coding. */

  TRANSPORT_TYPE userTpType; /*!< Transport type */
  UCHAR userTpSignaling;     /*!< Extension AOT signaling mode. */
  UCHAR userTpNsubFrames;    /*!< Number of sub frames in a transport frame for
                                LOAS/LATM or ADTS (default 1). */
  UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */
  UCHAR userTpProtection;
  UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate.
                               Moreover this parameters is used to configure
                               repetition rate of PCE in raw_data_block. */

  UCHAR userErTools;     /*!< Use VCB11, HCR and/or RVLC ER tool. */
  UINT userPceAdditions; /*!< Configure additional bits in PCE. */

  UCHAR userMetaDataMode; /*!< Meta data library configuration. */

  UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */
  UINT userSbrRatio;    /*!< SBR sampling rate ratio. Dual- or single-rate. */

  UINT userDownscaleFactor;

} USER_PARAM;

/**
 *  SBR extenxion payload struct provides buffers to be filled in SBR encoder
 * library.
 */
typedef struct {
  UCHAR data[(1)][(8)][MAX_PAYLOAD_SIZE]; /*!< extension payload data buffer */
  UINT dataSize[(1)][(8)]; /*!< extension payload data size in bits */
} SBRENC_EXT_PAYLOAD;

////////////////////////////////////////////////////////////////////////////////////

/****************************************************************************
                           Structure Definitions
****************************************************************************/

typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG;

struct AACENCODER {
  USER_PARAM extParam;
  CODER_CONFIG coderConfig;

  /* AAC */
  AACENC_CONFIG aacConfig;
  HANDLE_AAC_ENC hAacEnc;

  /* SBR */
  HANDLE_SBR_ENCODER hEnvEnc;      /* SBR encoder */
  SBRENC_EXT_PAYLOAD *pSbrPayload; /* SBR extension payload */

  /* Meta Data */
  HANDLE_FDK_METADATA_ENCODER hMetadataEnc;
  INT metaDataAllowed; /* Signal whether chosen configuration allows metadata.
                          Necessary for delay compensation. Metadata mode is a
                          separate parameter. */

  HANDLE_MPS_ENCODER hMpsEnc;

  /* Transport */
  HANDLE_TRANSPORTENC hTpEnc;

  INT_PCM
  *inputBuffer;     /* Internal input buffer. Input source for AAC encoder */
  UCHAR *outBuffer; /* Internal bitstream buffer */

  INT inputBufferSize;           /* Size of internal input buffer */
  INT inputBufferSizePerChannel; /* Size of internal input buffer per channel */
  INT outBufferInBytes;          /* Size of internal bitstream buffer*/

  INT inputBufferOffset; /* Where to write new input samples. */

  INT nSamplesToRead; /* number of input samples neeeded for encoding one frame
                       */
  INT nSamplesRead;   /* number of input samples already in input buffer */
  INT nZerosAppended; /* appended zeros at end of file*/
  INT nDelay;         /* codec delay */
  INT nDelayCore;     /* codec delay, w/o the SBR decoder delay */

  AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS];

  ULONG InitFlags; /* internal status to treggier re-initialization */

  /* Memory allocation info. */
  INT nMaxAacElements;
  INT nMaxAacChannels;
  INT nMaxSbrElements;
  INT nMaxSbrChannels;

  UINT encoder_modis;

  /* Capability flags */
  UINT CAPF_tpEnc;
};

typedef struct {
  /* input */
  ULONG nChannels;    /*!< Number of audio channels. */
  ULONG samplingRate; /*!< Encoder output sampling rate. */
  ULONG bitrateRange; /*!< Lower bitrate range for config entry. */

  /* output*/
  UCHAR sbrMode;       /*!< 0: ELD sbr off,
                            1: ELD with downsampled sbr,
                            2: ELD with dualrate sbr. */
  CHANNEL_MODE chMode; /*!< Channel mode. */

} ELD_SBR_CONFIGURATOR;

/**
 * \brief  This table defines ELD/SBR default configurations.
 */
static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = {
    {1, 48000, 0, 2, MODE_1},      {1, 48000, 64000, 0, MODE_1},

    {1, 44100, 0, 2, MODE_1},      {1, 44100, 64000, 0, MODE_1},

    {1, 32000, 0, 2, MODE_1},      {1, 32000, 28000, 1, MODE_1},
    {1, 32000, 56000, 0, MODE_1},

    {1, 24000, 0, 1, MODE_1},      {1, 24000, 40000, 0, MODE_1},

    {1, 16000, 0, 1, MODE_1},      {1, 16000, 28000, 0, MODE_1},

    {1, 15999, 0, 0, MODE_1},

    {2, 48000, 0, 2, MODE_2},      {2, 48000, 44000, 2, MODE_2},
    {2, 48000, 128000, 0, MODE_2},

    {2, 44100, 0, 2, MODE_2},      {2, 44100, 44000, 2, MODE_2},
    {2, 44100, 128000, 0, MODE_2},

    {2, 32000, 0, 2, MODE_2},      {2, 32000, 32000, 2, MODE_2},
    {2, 32000, 68000, 1, MODE_2},  {2, 32000, 96000, 0, MODE_2},

    {2, 24000, 0, 1, MODE_2},      {2, 24000, 48000, 1, MODE_2},
    {2, 24000, 80000, 0, MODE_2},

    {2, 16000, 0, 1, MODE_2},      {2, 16000, 32000, 1, MODE_2},
    {2, 16000, 64000, 0, MODE_2},

    {2, 15999, 0, 0, MODE_2}

};

/*
 * \brief  Configure SBR for ELD configuration.
 *
 * This function finds default SBR configuration for ELD based on number of
 * channels, sampling rate and bitrate.
 *
 * \param nChannels             Number of audio channels.
 * \param samplingRate          Audio signal sampling rate.
 * \param bitrate               Encoder bitrate.
 *
 * \return - pointer to eld sbr configuration.
 *         - NULL, on failure.
 */
static const ELD_SBR_CONFIGURATOR *eldSbrConfigurator(const ULONG nChannels,
                                                      const ULONG samplingRate,
                                                      const ULONG bitrate) {
  int i;
  const ELD_SBR_CONFIGURATOR *pSetup = NULL;

  for (i = 0;
       i < (int)(sizeof(eldSbrAutoConfigTab) / sizeof(ELD_SBR_CONFIGURATOR));
       i++) {
    if ((nChannels == eldSbrAutoConfigTab[i].nChannels) &&
        (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) &&
        (bitrate >= eldSbrAutoConfigTab[i].bitrateRange)) {
      pSetup = &eldSbrAutoConfigTab[i];
    }
  }

  return pSetup;
}

static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) {
  INT sbrUsed = 0;

  /* Note: Even if implicit signalling was selected, The AOT itself here is not
   * AOT_AAC_LC */
  if ((hAacConfig->audioObjectType == AOT_SBR) ||
      (hAacConfig->audioObjectType == AOT_PS) ||
      (hAacConfig->audioObjectType == AOT_MP2_SBR)) {
    sbrUsed = 1;
  }
  if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD &&
      (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) {
    sbrUsed = 1;
  }

  return (sbrUsed);
}

static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) {
  INT psUsed = 0;

  if (audioObjectType == AOT_PS) {
    psUsed = 1;
  }

  return (psUsed);
}

static CHANNEL_MODE GetCoreChannelMode(
    const CHANNEL_MODE channelMode, const AUDIO_OBJECT_TYPE audioObjectType) {
  CHANNEL_MODE mappedChannelMode = channelMode;
  if ((isPsActive(audioObjectType) && (channelMode == MODE_2)) ||
      (channelMode == MODE_212)) {
    mappedChannelMode = MODE_1;
  }
  return mappedChannelMode;
}

static SBR_PS_SIGNALING getSbrSignalingMode(
    const AUDIO_OBJECT_TYPE audioObjectType, const TRANSPORT_TYPE transportType,
    const UCHAR transportSignaling, const UINT sbrRatio)

{
  SBR_PS_SIGNALING sbrSignaling;

  if (transportType == TT_UNKNOWN || sbrRatio == 0) {
    sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */
    return sbrSignaling;
  } else {
    sbrSignaling =
        SIG_EXPLICIT_HIERARCHICAL; /* default: explicit hierarchical signaling
                                    */
  }

  if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) ||
      (audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) ||
      (audioObjectType == AOT_MP2_SBR)) {
    switch (transportType) {
      case TT_MP4_ADIF:
      case TT_MP4_ADTS:
        sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only
                                        implicit signaling is possible */
        break;

      case TT_MP4_RAW:
      case TT_MP4_LATM_MCP1:
      case TT_MP4_LATM_MCP0:
      case TT_MP4_LOAS:
      default:
        if (transportSignaling == 0xFF) {
          /* Defaults */
          sbrSignaling = SIG_EXPLICIT_HIERARCHICAL;
        } else {
          /* User set parameters */
          /* Attention: Backward compatible explicit signaling does only work
           * with AMV1 for LATM/LOAS */
          sbrSignaling = (SBR_PS_SIGNALING)transportSignaling;
        }
        break;
    }
  }

  return sbrSignaling;
}

/****************************************************************************
                               Allocate Encoder
****************************************************************************/

H_ALLOC_MEM(_AacEncoder, AACENCODER)
C_ALLOC_MEM(_AacEncoder, struct AACENCODER, 1)

/*
 * Map Encoder specific config structures to CODER_CONFIG.
 */
static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc,
                                const USER_PARAM *const extCfg,
                                const SBR_PS_SIGNALING sbrSignaling,
                                const HANDLE_AACENC_CONFIG hAacConfig) {
  AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT;
  FDKmemclear(cc, sizeof(CODER_CONFIG));

  cc->flags = 0;

  cc->samplesPerFrame = hAacConfig->framelength;
  cc->samplingRate = hAacConfig->sampleRate;
  cc->extSamplingRate = extCfg->userSamplerate;

  /* Map virtual aot to transport aot. */
  switch (hAacConfig->audioObjectType) {
    case AOT_MP2_AAC_LC:
      transport_AOT = AOT_AAC_LC;
      break;
    case AOT_MP2_SBR:
      transport_AOT = AOT_SBR;
      cc->flags |= CC_SBR;
      break;
    default:
      transport_AOT = hAacConfig->audioObjectType;
  }

  if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
    cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0;
    cc->flags |= (hAacConfig->syntaxFlags & AC_LD_MPS) ? CC_SAC : 0;
  }

  /* transport type is usually AAC-LC. */
  if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
    cc->aot = AOT_AAC_LC;
  } else {
    cc->aot = transport_AOT;
  }

  /* Configure extension aot. */
  if (sbrSignaling == SIG_IMPLICIT) {
    cc->extAOT = AOT_NULL_OBJECT; /* implicit */
  } else {
    if ((sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) &&
        ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS))) {
      cc->extAOT = AOT_SBR; /* explicit backward compatible */
    } else {
      cc->extAOT = transport_AOT; /* explicit hierarchical */
    }
  }

  if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
    cc->sbrPresent = 1;
    if (transport_AOT == AOT_PS) {
      cc->psPresent = 1;
    }
  }
  cc->sbrSignaling = sbrSignaling;

  if (hAacConfig->downscaleFactor > 1) {
    cc->downscaleSamplingRate = cc->samplingRate;
    cc->samplingRate *= hAacConfig->downscaleFactor;
    cc->extSamplingRate *= hAacConfig->downscaleFactor;
  }

  cc->bitRate = hAacConfig->bitRate;
  cc->noChannels = hAacConfig->nChannels;
  cc->flags |= CC_IS_BASELAYER;
  cc->channelMode = hAacConfig->channelMode;

  cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1)
                       ? hAacConfig->nSubFrames
                       : extCfg->userTpNsubFrames;

  cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0;

  if (extCfg->userTpHeaderPeriod != 0xFF) {
    cc->headerPeriod = extCfg->userTpHeaderPeriod;
  } else { /* auto-mode */
    switch (extCfg->userTpType) {
      case TT_MP4_ADTS:
      case TT_MP4_LOAS:
      case TT_MP4_LATM_MCP1:
        cc->headerPeriod = DEFAULT_HEADER_PERIOD_REPETITION_RATE;
        break;
      default:
        cc->headerPeriod = 0;
    }
  }

  /* Mpeg-4 signaling for transport library. */
  switch (hAacConfig->audioObjectType) {
    case AOT_MP2_AAC_LC:
    case AOT_MP2_SBR:
      cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
      cc->extAOT = AOT_NULL_OBJECT;
      break;
    default:
      cc->flags |= CC_MPEG_ID;
  }

  /* ER-tools signaling. */
  cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0;
  cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0;
  cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0;

  /* Matrix mixdown coefficient configuration. */
  if ((extCfg->userPceAdditions & 0x1) && (hAacConfig->epConfig == -1) &&
      ((cc->channelMode == MODE_1_2_2) || (cc->channelMode == MODE_1_2_2_1))) {
    cc->matrixMixdownA = ((extCfg->userPceAdditions >> 1) & 0x3) + 1;
    cc->flags |= (extCfg->userPceAdditions >> 3) & 0x1 ? CC_PSEUDO_SURROUND : 0;
  } else {
    cc->matrixMixdownA = 0;
  }

  cc->channelConfigZero = 0;
}

/*
 * Validate prefilled pointers within buffer descriptor.
 *
 * \param pBufDesc              Pointer to buffer descriptor

 * \return - AACENC_OK, all fine.
 *         - AACENC_INVALID_HANDLE, on missing pointer initializiation.
 *         - AACENC_UNSUPPORTED_PARAMETER, on incorrect buffer descriptor
 initialization.
 */
static AACENC_ERROR validateBufDesc(const AACENC_BufDesc *pBufDesc) {
  AACENC_ERROR err = AACENC_OK;

  if (pBufDesc != NULL) {
    int i;
    if ((pBufDesc->bufferIdentifiers == NULL) || (pBufDesc->bufSizes == NULL) ||
        (pBufDesc->bufElSizes == NULL) || (pBufDesc->bufs == NULL)) {
      err = AACENC_UNSUPPORTED_PARAMETER;
      goto bail;
    }
    for (i = 0; i < pBufDesc->numBufs; i++) {
      if (pBufDesc->bufs[i] == NULL) {
        err = AACENC_UNSUPPORTED_PARAMETER;
        goto bail;
      }
    }
  } else {
    err = AACENC_INVALID_HANDLE;
  }
bail:
  return err;
}

/*
 * Examine buffer descriptor regarding choosen identifier.
 *
 * \param pBufDesc              Pointer to buffer descriptor
 * \param identifier            Buffer identifier to look for.

 * \return - Buffer descriptor index.
 *         -1, if there is no entry available.
 */
static INT getBufDescIdx(const AACENC_BufDesc *pBufDesc,
                         const AACENC_BufferIdentifier identifier) {
  INT i, idx = -1;

  if (pBufDesc != NULL) {
    for (i = 0; i < pBufDesc->numBufs; i++) {
      if ((AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] ==
          identifier) {
        idx = i;
        break;
      }
    }
  }
  return idx;
}

/****************************************************************************
                          Function Declarations
****************************************************************************/

AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
                                      USER_PARAM *config) {
  /* make reasonable default settings */
  FDKaacEnc_AacInitDefaultConfig(hAacConfig);

  /* clear configuration structure and copy default settings */
  FDKmemclear(config, sizeof(USER_PARAM));

  /* copy encoder configuration settings */
  config->nChannels = hAacConfig->nChannels;
  config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC;
  config->userSamplerate = hAacConfig->sampleRate;
  config->userChannelMode = hAacConfig->channelMode;
  config->userBitrate = hAacConfig->bitRate;
  config->userBitrateMode = hAacConfig->bitrateMode;
  config->userPeakBitrate = (UINT)-1;
  config->userBandwidth = hAacConfig->bandWidth;
  config->userTns = hAacConfig->useTns;
  config->userPns = hAacConfig->usePns;
  config->userIntensity = hAacConfig->useIS;
  config->userAfterburner = hAacConfig->useRequant;
  config->userFramelength = (UINT)-1;

  config->userDownscaleFactor = 1;

  /* initialize transport parameters */
  config->userTpType = TT_UNKNOWN;
  config->userTpAmxv = 0;
  config->userTpSignaling = 0xFF; /* choose signaling automatically */
  config->userTpNsubFrames = 1;
  config->userTpProtection = 0;      /* not crc protected*/
  config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */
  config->userPceAdditions = 0;      /* no matrix mixdown coefficient */
  config->userMetaDataMode = 0;      /* do not embed any meta data info */

  config->userAncDataRate = 0;

  /* SBR rate is set to 0 here, which means it should be set automatically
     in FDKaacEnc_AdjustEncSettings() if the user did not set a rate
     expilicitely. */
  config->userSbrRatio = 0;

  /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable
   * configuration. */
  config->userSbrEnabled = (UCHAR)-1;

  return AAC_ENC_OK;
}

static void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping,
                                    SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) {
  INT codebits = bitRate;
  int el;

  /* Copy Element info */
  for (el = 0; el < channelMapping->nElements; el++) {
    sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0];
    sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1];
    sbrElInfo[el].elType = channelMapping->elInfo[el].elType;
    sbrElInfo[el].bitRate =
        fMultIfloor(channelMapping->elInfo[el].relativeBits, bitRate);
    sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag;
    sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl;
    sbrElInfo[el].fParametricStereo = 0;
    sbrElInfo[el].fDualMono = 0;

    codebits -= sbrElInfo[el].bitRate;
  }
  sbrElInfo[0].bitRate += codebits;
}

static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc,
                                   const INT samplingRate,
                                   const INT frameLength, const INT nChannels,
                                   const CHANNEL_MODE channelMode, INT bitRate,
                                   const INT nSubFrames, const INT sbrActive,
                                   const INT sbrDownSampleRate,
                                   const UINT syntaxFlags,
                                   const AUDIO_OBJECT_TYPE aot) {
  INT coreSamplingRate;
  CHANNEL_MAPPING cm;

  FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);

  if (sbrActive) {
    coreSamplingRate =
        samplingRate >>
        (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate - 1) : 1);
  } else {
    coreSamplingRate = samplingRate;
  }

  /* Limit bit rate in respect to the core coder */
  bitRate = FDKaacEnc_LimitBitrate(hTpEnc, aot, coreSamplingRate, frameLength,
                                   nChannels, cm.nChannelsEff, bitRate, -1,
                                   NULL, AACENC_BR_MODE_INVALID, nSubFrames);

  /* Limit bit rate in respect to available SBR modes if active */
  if (sbrActive) {
    int numIterations = 0;
    INT initialBitrate, adjustedBitrate;
    adjustedBitrate = bitRate;

    /* Find total bitrate which provides valid configuration for each SBR
     * element. */
    do {
      int e;
      SBR_ELEMENT_INFO sbrElInfo[((8))];
      FDK_ASSERT(cm.nElements <= ((8)));

      initialBitrate = adjustedBitrate;

      /* Get bit rate for each SBR element */
      aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate);

      for (e = 0; e < cm.nElements; e++) {
        INT sbrElementBitRateIn, sbrBitRateOut;

        if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) {
          continue;
        }
        sbrElementBitRateIn = sbrElInfo[e].bitRate;

        sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn,
                                                cm.elInfo[e].nChannelsInEl,
                                                coreSamplingRate, aot);

        if (sbrBitRateOut == 0) {
          return 0;
        }

        /* If bitrates don't match, distribution and limiting needs to be
           determined again. Abort element loop and restart with adapted
           bitrate. */
        if (sbrElementBitRateIn != sbrBitRateOut) {
          if (sbrElementBitRateIn < sbrBitRateOut) {
            adjustedBitrate = fMax(initialBitrate,
                                   (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut + 8),
                                                 cm.elInfo[e].relativeBits));
            break;
          }

          if (sbrElementBitRateIn > sbrBitRateOut) {
            adjustedBitrate = fMin(initialBitrate,
                                   (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut - 8),
                                                 cm.elInfo[e].relativeBits));
            break;
          }

        } /* sbrElementBitRateIn != sbrBitRateOut */

      } /* elements */

      numIterations++; /* restrict iteration to worst case of num elements */

    } while ((initialBitrate != adjustedBitrate) &&
             (numIterations <= cm.nElements));

    /* Unequal bitrates mean that no reasonable bitrate configuration found. */
    bitRate = (initialBitrate == adjustedBitrate) ? adjustedBitrate : 0;
  }

  /* Limit bit rate in respect to available MPS modes if active */
  if ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS) &&
      (channelMode == MODE_1)) {
    bitRate = FDK_MpegsEnc_GetClosestBitRate(
        aot, MODE_212, samplingRate, (sbrActive) ? sbrDownSampleRate : 0,
        bitRate);
  }

  return bitRate;
}

/*
 * \brief Get CBR bitrate
 *
 * \hAacConfig Internal encoder config
 * \return     Bitrate
 */
static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig,
                                   const INT userSbrRatio) {
  INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
                    ->nChannelsEff *
                hAacConfig->sampleRate;

  if (isPsActive(hAacConfig->audioObjectType)) {
    bitrate = 1 * bitrate; /* 0.5 bit per sample */
  } else if (isSbrActive(hAacConfig)) {
    if ((userSbrRatio == 2) ||
        ((userSbrRatio == 0) &&
         (hAacConfig->audioObjectType != AOT_ER_AAC_ELD))) {
      bitrate = (bitrate + (bitrate >> 2)) >> 1; /* 0.625 bits per sample */
    }
    if ((userSbrRatio == 1) ||
        ((userSbrRatio == 0) &&
         (hAacConfig->audioObjectType == AOT_ER_AAC_ELD))) {
      bitrate = (bitrate + (bitrate >> 3)); /* 1.125 bits per sample */
    }
  } else {
    bitrate = bitrate + (bitrate >> 1); /* 1.5 bits per sample */
  }

  return bitrate;
}

/*
 * \brief Consistency check of given USER_PARAM struct and
 *   copy back configuration from public struct into internal
 *   encoder configuration struct.
 *
 * \hAacEncoder Internal encoder config which is to be updated
 * \param config User provided config (public struct)
 * \return returns always AAC_ENC_OK
 */
static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
                                                USER_PARAM *config) {
  AACENC_ERROR err = AACENC_OK;

  /* Get struct pointers. */
  HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;

  /* Encoder settings update. */
  hAacConfig->sampleRate = config->userSamplerate;
  if (config->userDownscaleFactor > 1) {
    hAacConfig->useTns = 0;
    hAacConfig->usePns = 0;
    hAacConfig->useIS = 0;
  } else {
    hAacConfig->useTns = config->userTns;
    hAacConfig->usePns = config->userPns;
    hAacConfig->useIS = config->userIntensity;
  }

  hAacConfig->audioObjectType = config->userAOT;
  hAacConfig->channelMode =
      GetCoreChannelMode(config->userChannelMode, hAacConfig->audioObjectType);
  hAacConfig->nChannels =
      FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannels;
  hAacConfig->bitrateMode = (AACENC_BITRATE_MODE)config->userBitrateMode;
  hAacConfig->bandWidth = config->userBandwidth;
  hAacConfig->useRequant = config->userAfterburner;

  hAacConfig->anc_Rate = config->userAncDataRate;
  hAacConfig->syntaxFlags = 0;
  hAacConfig->epConfig = -1;

  if (hAacConfig->audioObjectType != AOT_ER_AAC_ELD &&
      config->userDownscaleFactor > 1) {
    return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
                                   */
  }
  if (config->userDownscaleFactor > 1 && config->userSbrEnabled == 1) {
    return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
                                     w/o SBR */
  }
  if (config->userDownscaleFactor > 1 && config->userChannelMode == 128) {
    return AACENC_INVALID_CONFIG; /* disallow downscaling for AAC-ELDv2 */
  }

  if (config->userTpType == TT_MP4_LATM_MCP1 ||
      config->userTpType == TT_MP4_LATM_MCP0 ||
      config->userTpType == TT_MP4_LOAS) {
    hAacConfig->audioMuxVersion = config->userTpAmxv;
  } else {
    hAacConfig->audioMuxVersion = -1;
  }

  /* Adapt internal AOT when necessary. */
  switch (config->userAOT) {
    case AOT_MP2_AAC_LC:
    case AOT_MP2_SBR:
      hAacConfig->usePns = 0;
      FDK_FALLTHROUGH;
    case AOT_AAC_LC:
    case AOT_SBR:
    case AOT_PS:
      config->userTpType =
          (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS;
      hAacConfig->framelength = (config->userFramelength != (UINT)-1)
                                    ? config->userFramelength
                                    : 1024;
      if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) {
        return AACENC_INVALID_CONFIG;
      }
      break;
    case AOT_ER_AAC_LD:
      hAacConfig->epConfig = 0;
      hAacConfig->syntaxFlags |= AC_ER | AC_LD;
      hAacConfig->syntaxFlags |=
          ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
      hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
      hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
      config->userTpType =
          (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
      hAacConfig->framelength =
          (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;
      if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) {
        return AACENC_INVALID_CONFIG;
      }
      break;
    case AOT_ER_AAC_ELD:
      hAacConfig->epConfig = 0;
      hAacConfig->syntaxFlags |= AC_ER | AC_ELD;
      hAacConfig->syntaxFlags |=
          ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
      hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
      hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
      hAacConfig->syntaxFlags |=
          ((config->userSbrEnabled == 1) ? AC_SBR_PRESENT : 0);
      hAacConfig->syntaxFlags |=
          ((config->userChannelMode == MODE_212) ? AC_LD_MPS : 0);
      config->userTpType =
          (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
      hAacConfig->framelength =
          (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;

      hAacConfig->downscaleFactor = config->userDownscaleFactor;

      switch (config->userDownscaleFactor) {
        case 1:
          break;
        case 2:
        case 4:
          hAacConfig->syntaxFlags |= AC_ELD_DOWNSCALE;
          break;
        default:
          return AACENC_INVALID_CONFIG;
      }

      if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480 &&
          hAacConfig->framelength != 256 && hAacConfig->framelength != 240 &&
          hAacConfig->framelength != 128 && hAacConfig->framelength != 120) {
        return AACENC_INVALID_CONFIG;
      }
      break;
    default:
      break;
  }

  /* Initialize SBR parameters */
  if ((config->userSbrRatio == 0) && (isSbrActive(hAacConfig))) {
    /* Automatic SBR ratio configuration
     * - downsampled SBR for ELD
     * - otherwise always dualrate SBR
     */
    if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
      hAacConfig->sbrRatio = ((hAacConfig->syntaxFlags & AC_LD_MPS) &&
                              (hAacConfig->sampleRate >= 27713))
                                 ? 2
                                 : 1;
    } else {
      hAacConfig->sbrRatio = 2;
    }
  } else {
    /* SBR ratio has been set by the user, so use it. */
    hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0;
  }

  /* Set default bitrate */
  hAacConfig->bitRate = config->userBitrate;

  switch (hAacConfig->bitrateMode) {
    case AACENC_BR_MODE_CBR:
      /* Set default bitrate if no external bitrate declared. */
      if (config->userBitrate == (UINT)-1) {
        hAacConfig->bitRate =
            FDKaacEnc_GetCBRBitrate(hAacConfig, config->userSbrRatio);
      }
      hAacConfig->averageBits = -1;
      break;
    case AACENC_BR_MODE_VBR_1:
    case AACENC_BR_MODE_VBR_2:
    case AACENC_BR_MODE_VBR_3:
    case AACENC_BR_MODE_VBR_4:
    case AACENC_BR_MODE_VBR_5:
      /* Get bitrate in VBR configuration */
      /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode.
       */
      hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode,
                                                    hAacConfig->channelMode);
      break;
    default:
      return AACENC_INVALID_CONFIG;
  }

  /* set bitreservoir size */
  switch (hAacConfig->bitrateMode) {
    case AACENC_BR_MODE_VBR_1:
    case AACENC_BR_MODE_VBR_2:
    case AACENC_BR_MODE_VBR_3:
    case AACENC_BR_MODE_VBR_4:
    case AACENC_BR_MODE_VBR_5:
    case AACENC_BR_MODE_CBR:
      if ((INT)config->userPeakBitrate != -1) {
        hAacConfig->maxBitsPerFrame =
            (FDKaacEnc_CalcBitsPerFrame(
                 fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate),
                 hAacConfig->framelength, hAacConfig->sampleRate) +
             7) &
            ~7;
      } else {
        hAacConfig->maxBitsPerFrame = -1;
      }
      if (hAacConfig->audioMuxVersion == 2) {
        hAacConfig->minBitsPerFrame =
            fMin(32 * 8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate,
                                                    hAacConfig->framelength,
                                                    hAacConfig->sampleRate)) &
            ~7;
      }
      break;
    default:
      return AACENC_INVALID_CONFIG;
  }

  /* Max bits per frame limitation depending on transport format. */
  if ((config->userTpNsubFrames > 1)) {
    int maxFrameLength = 8 * hAacEncoder->outBufferInBytes;
    switch (config->userTpType) {
      case TT_MP4_LOAS:
        maxFrameLength =
            fMin(maxFrameLength, 8 * (1 << 13)) / config->userTpNsubFrames;
        break;
      case TT_MP4_ADTS:
        maxFrameLength = fMin(maxFrameLength, 8 * ((1 << 13) - 1)) /
                         config->userTpNsubFrames;
        break;
      default:
        maxFrameLength = -1;
    }
    if (maxFrameLength != -1) {
      if (hAacConfig->maxBitsPerFrame > maxFrameLength) {
        return AACENC_INVALID_CONFIG;
      } else if (hAacConfig->maxBitsPerFrame == -1) {
        hAacConfig->maxBitsPerFrame = maxFrameLength;
      }
    }
  }

  if ((hAacConfig->audioObjectType == AOT_ER_AAC_ELD) &&
      !(hAacConfig->syntaxFlags & AC_ELD_DOWNSCALE) &&
      (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio == 0) &&
      ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0)) {
    const ELD_SBR_CONFIGURATOR *pConfig = NULL;

    if (NULL !=
        (pConfig = eldSbrConfigurator(
             FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
                 ->nChannels,
             hAacConfig->sampleRate, hAacConfig->bitRate))) {
      hAacConfig->syntaxFlags |= (pConfig->sbrMode == 0) ? 0 : AC_SBR_PRESENT;
      hAacConfig->syntaxFlags |= (pConfig->chMode == MODE_212) ? AC_LD_MPS : 0;
      hAacConfig->channelMode =
          GetCoreChannelMode(pConfig->chMode, hAacConfig->audioObjectType);
      hAacConfig->nChannels =
          FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
              ->nChannels;
      hAacConfig->sbrRatio =
          (pConfig->sbrMode == 0) ? 0 : (pConfig->sbrMode == 1) ? 1 : 2;
    }
  }

  {
    UCHAR tpSignaling =
        getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
                            config->userTpSignaling, hAacConfig->sbrRatio);

    if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
         hAacConfig->audioObjectType == AOT_SBR ||
         hAacConfig->audioObjectType == AOT_PS) &&
        (config->userTpType == TT_MP4_LATM_MCP1 ||
         config->userTpType == TT_MP4_LATM_MCP0 ||
         config->userTpType == TT_MP4_LOAS) &&
        (tpSignaling == 1) && (config->userTpAmxv == 0)) {
      /* For backward compatible explicit signaling, AMV1 has to be active */
      return AACENC_INVALID_CONFIG;
    }

    if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
         hAacConfig->audioObjectType == AOT_SBR ||
         hAacConfig->audioObjectType == AOT_PS) &&
        (tpSignaling == 0) && (hAacConfig->sbrRatio == 1)) {
      /* Downsampled SBR has to be signaled explicitely (for transmission of SBR
       * sampling fequency) */
      return AACENC_INVALID_CONFIG;
    }
  }

  switch (hAacConfig->bitrateMode) {
    case AACENC_BR_MODE_CBR:
    case AACENC_BR_MODE_VBR_1:
    case AACENC_BR_MODE_VBR_2:
    case AACENC_BR_MODE_VBR_3:
    case AACENC_BR_MODE_VBR_4:
    case AACENC_BR_MODE_VBR_5:
      /* We need the frame length to call aacEncoder_LimitBitrate() */
      if (0 >= (hAacConfig->bitRate = aacEncoder_LimitBitrate(
                    NULL, hAacConfig->sampleRate, hAacConfig->framelength,
                    hAacConfig->nChannels, hAacConfig->channelMode,
                    hAacConfig->bitRate, hAacConfig->nSubFrames,
                    isSbrActive(hAacConfig), hAacConfig->sbrRatio,
                    hAacConfig->syntaxFlags, hAacConfig->audioObjectType))) {
        return AACENC_INVALID_CONFIG;
      }
      break;
    default:
      break;
  }

  /* Configure PNS */
  if (AACENC_BR_MODE_IS_VBR(hAacConfig->bitrateMode) /* VBR without PNS. */
      || (hAacConfig->useTns == 0))                  /* TNS required.    */
  {
    hAacConfig->usePns = 0;
  }

  if (hAacConfig->epConfig >= 0) {
    hAacConfig->syntaxFlags |= AC_ER;
    if (((INT)hAacConfig->channelMode < 1) ||
        ((INT)hAacConfig->channelMode > 14)) {
      return AACENC_INVALID_CONFIG; /* Channel config 0 not supported. */
    }
  }

  if ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0) {
    if (FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode,
                                       hAacConfig->nChannels) != AAC_ENC_OK) {
      return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is
                                       just a check-up */
    }
  }

  if ((hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) ||
      ((FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
            ->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
       isSbrActive(hAacConfig))) {
    return AACENC_INVALID_CONFIG; /* not enough channels allocated */
  }

  /* Meta data restriction. */
  switch (hAacConfig->audioObjectType) {
    /* Allow metadata support */
    case AOT_AAC_LC:
    case AOT_SBR:
    case AOT_PS:
    case AOT_MP2_AAC_LC:
    case AOT_MP2_SBR:
      hAacEncoder->metaDataAllowed = 1;
      if (!((((INT)hAacConfig->channelMode >= 1) &&
             ((INT)hAacConfig->channelMode <= 14)) ||
            (MODE_7_1_REAR_SURROUND == hAacConfig->channelMode) ||
            (MODE_7_1_FRONT_CENTER == hAacConfig->channelMode))) {
        config->userMetaDataMode = 0;
      }
      break;
    /* Prohibit metadata support */
    default:
      hAacEncoder->metaDataAllowed = 0;
  }

  return err;
}

static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
                              const INT sampleRateIn, const INT sampleRateOut,
                              const INT samplesPerFrame,
                              const AUDIO_OBJECT_TYPE coreCodec,
                              const MP4_ELEMENT_ID elementID,
                              const INT elementIndex, const UCHAR harmonicSbr,
                              const UCHAR stereoConfigIndex,
                              const UCHAR configMode, UCHAR *configChanged,
                              const INT downscaleFactor) {
  HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;

  sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0);

  return 0;
}

INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
                       const AUDIO_OBJECT_TYPE coreCodec,
                       const INT samplingRate, const INT frameSize,
                       const INT stereoConfigIndex,
                       const INT coreSbrFrameLengthIndex, const INT configBytes,
                       const UCHAR configMode, UCHAR *configChanged) {
  HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;

  return (FDK_MpegsEnc_WriteSpatialSpecificConfig(hAacEncoder->hMpsEnc, hBs));
}

static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ULONG InitFlags,
                               USER_PARAM *config) {
  AACENC_ERROR err = AACENC_OK;

  INT aacBufferOffset = 0;
  HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc;
  HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;

  hAacEncoder->nZerosAppended = 0; /* count appended zeros */

  INT frameLength = hAacConfig->framelength;

  if ((InitFlags & AACENC_INIT_CONFIG)) {
    CHANNEL_MODE prevChMode = hAacConfig->channelMode;

    /* Verify settings and update: config -> heAacEncoder */
    if ((err = FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK) {
      return err;
    }
    frameLength = hAacConfig->framelength; /* adapt temporal framelength */

    /* Seamless channel reconfiguration in sbr not fully implemented */
    if ((prevChMode != hAacConfig->channelMode) && isSbrActive(hAacConfig)) {
      InitFlags |= AACENC_INIT_STATES;
    }
  }

  /* Clear input buffer */
  if (InitFlags == AACENC_INIT_ALL) {
    FDKmemclear(hAacEncoder->inputBuffer,
                sizeof(INT_PCM) * hAacEncoder->inputBufferSize);
  }

  if ((InitFlags & AACENC_INIT_CONFIG)) {
    aacBufferOffset = 0;
    switch (hAacConfig->audioObjectType) {
      case AOT_ER_AAC_LD:
        hAacEncoder->nDelay = DELAY_AACLD(hAacConfig->framelength);
        break;
      case AOT_ER_AAC_ELD:
        hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength);
        break;
      default:
        hAacEncoder->nDelay =
            DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */
    }

    hAacConfig->ancDataBitRate = 0;
  }

  if ((NULL != hAacEncoder->hEnvEnc) && isSbrActive(hAacConfig) &&
      ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
    INT sbrError;
    UINT initFlag = 0;
    SBR_ELEMENT_INFO sbrElInfo[(8)];
    CHANNEL_MAPPING channelMapping;
    CHANNEL_MODE channelMode = isPsActive(hAacConfig->audioObjectType)
                                   ? config->userChannelMode
                                   : hAacConfig->channelMode;
    INT numChannels = isPsActive(hAacConfig->audioObjectType)
                          ? config->nChannels
                          : hAacConfig->nChannels;

    if (FDKaacEnc_InitChannelMapping(channelMode, hAacConfig->channelOrder,
                                     &channelMapping) != AAC_ENC_OK) {
      return AACENC_INIT_ERROR;
    }

    /* Check return value and if the SBR encoder can handle enough elements */
    if (channelMapping.nElements > (8)) {
      return AACENC_INIT_ERROR;
    }

    aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate);

    initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0;

    /* Let the SBR encoder take a look at the configuration and change if
     * required. */
    sbrError = sbrEncoder_Init(
        *hSbrEncoder, sbrElInfo, channelMapping.nElements,
        hAacEncoder->inputBuffer, hAacEncoder->inputBufferSizePerChannel,
        &hAacConfig->bandWidth, &aacBufferOffset, &numChannels,
        hAacConfig->syntaxFlags, &hAacConfig->sampleRate, &hAacConfig->sbrRatio,
        &frameLength, hAacConfig->audioObjectType, &hAacEncoder->nDelay,
        (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC,
        (config->userTpHeaderPeriod != 0xFF)
            ? config->userTpHeaderPeriod
            : DEFAULT_HEADER_PERIOD_REPETITION_RATE,
        initFlag);

    /* Suppress AOT reconfiguration and check error status. */
    if ((sbrError) || (numChannels != hAacConfig->nChannels)) {
      return AACENC_INIT_SBR_ERROR;
    }

    if (numChannels == 1) {
      hAacConfig->channelMode = MODE_1;
    }

    /* Never use PNS if SBR is active */
    if (hAacConfig->usePns) {
      hAacConfig->usePns = 0;
    }

    /* estimated bitrate consumed by SBR or PS */
    hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder);

  } /* sbr initialization */

  if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
    int coreCoderDelay = DELAY_AACELD(hAacConfig->framelength);

    if (isSbrActive(hAacConfig)) {
      coreCoderDelay = hAacConfig->sbrRatio * coreCoderDelay +
                       sbrEncoder_GetInputDataDelay(*hSbrEncoder);
    }

    if (MPS_ENCODER_OK !=
        FDK_MpegsEnc_Init(hAacEncoder->hMpsEnc, hAacConfig->audioObjectType,
                          config->userSamplerate, hAacConfig->bitRate,
                          isSbrActive(hAacConfig) ? hAacConfig->sbrRatio : 0,
                          frameLength, /* for dual rate sbr this value is
                                          already multiplied by 2 */
                          hAacEncoder->inputBufferSizePerChannel,
                          coreCoderDelay)) {
      return AACENC_INIT_MPS_ERROR;
    }
  }
  hAacEncoder->nDelay =
      fMax(FDK_MpegsEnc_GetDelay(hAacEncoder->hMpsEnc), hAacEncoder->nDelay);

  /*
   * Initialize Transport - Module.
   */
  if ((InitFlags & AACENC_INIT_TRANSPORT)) {
    UINT flags = 0;

    FDKaacEnc_MapConfig(
        &hAacEncoder->coderConfig, config,
        getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
                            config->userTpSignaling, hAacConfig->sbrRatio),
        hAacConfig);

    /* create flags for transport encoder */
    if (config->userTpAmxv != 0) {
      flags |= TP_FLAG_LATM_AMV;
    }
    /* Clear output buffer */
    FDKmemclear(hAacEncoder->outBuffer,
                hAacEncoder->outBufferInBytes * sizeof(UCHAR));

    /* Initialize Bitstream encoder */
    if (transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer,
                          hAacEncoder->outBufferInBytes, config->userTpType,
                          &hAacEncoder->coderConfig, flags) != 0) {
      return AACENC_INIT_TP_ERROR;
    }

  } /* transport initialization */

  /*
   * Initialize AAC - Core.
   */
  if ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) {
    if (FDKaacEnc_Initialize(
            hAacEncoder->hAacEnc, hAacConfig, hAacEncoder->hTpEnc,
            (InitFlags & AACENC_INIT_STATES) ? 1 : 0) != AAC_ENC_OK) {
      return AACENC_INIT_AAC_ERROR;
    }

  } /* aac initialization */

  /*
   * Initialize Meta Data - Encoder.
   */
  if (hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed != 0) &&
      ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
    INT inputDataDelay = DELAY_AAC(hAacConfig->framelength);

    if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
      inputDataDelay = hAacConfig->sbrRatio * inputDataDelay +
                       sbrEncoder_GetInputDataDelay(*hSbrEncoder);
    }

    if (FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc,
                             ((InitFlags & AACENC_INIT_STATES) ? 1 : 0),
                             config->userMetaDataMode, inputDataDelay,
                             frameLength, config->userSamplerate,
                             config->nChannels, config->userChannelMode,
                             hAacConfig->channelOrder) != 0) {
      return AACENC_INIT_META_ERROR;
    }

    hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc);
  }

  /* Get custom delay, i.e. the codec delay w/o the decoder's SBR- or MPS delay
   */
  if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
    hAacEncoder->nDelayCore =
        hAacEncoder->nDelay -
        fMax(0, FDK_MpegsEnc_GetDecDelay(hAacEncoder->hMpsEnc));
  } else if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
    hAacEncoder->nDelayCore =
        hAacEncoder->nDelay -
        fMax(0, sbrEncoder_GetSbrDecDelay(hAacEncoder->hEnvEnc));
  } else {
    hAacEncoder->nDelayCore = hAacEncoder->nDelay;
  }

  /*
   * Update pointer to working buffer.
   */
  if ((InitFlags & AACENC_INIT_CONFIG)) {
    hAacEncoder->inputBufferOffset = aacBufferOffset;

    hAacEncoder->nSamplesToRead = frameLength * config->nChannels;

  } /* parameter changed */

  return AACENC_OK;
}

AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules,
                        const UINT maxChannels) {
  AACENC_ERROR err = AACENC_OK;
  HANDLE_AACENCODER hAacEncoder = NULL;

  if (phAacEncoder == NULL) {
    err = AACENC_INVALID_HANDLE;
    goto bail;
  }

  /* allocate memory */
  hAacEncoder = Get_AacEncoder();

  if (hAacEncoder == NULL) {
    err = AACENC_MEMORY_ERROR;
    goto bail;
  }

  FDKmemclear(hAacEncoder, sizeof(AACENCODER));

  /* Specify encoder modules to be allocated. */
  if (encModules == 0) {
    C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
    LIB_INFO(*pLibInfo)
    [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;
    FDKinitLibInfo(*pLibInfo);
    aacEncGetLibInfo(*pLibInfo);

    hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC;
    if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_HQ) {
      hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR;
    }
    if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_PS_MPEG) {
      hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS;
    }
    if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_AACENC) & CAPF_AAC_DRC) {
      hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META;
    }
    hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SAC;

    C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
  } else {
    hAacEncoder->encoder_modis = encModules;
  }

  /* Determine max channel configuration. */
  if (maxChannels == 0) {
    hAacEncoder->nMaxAacChannels = (8);
    hAacEncoder->nMaxSbrChannels = (8);
  } else {
    hAacEncoder->nMaxAacChannels = (maxChannels & 0x00FF);
    if ((hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR)) {
      hAacEncoder->nMaxSbrChannels = (maxChannels & 0xFF00)
                                         ? (maxChannels >> 8)
                                         : hAacEncoder->nMaxAacChannels;
    }

    if ((hAacEncoder->nMaxAacChannels > (8)) ||
        (hAacEncoder->nMaxSbrChannels > (8))) {
      err = AACENC_INVALID_CONFIG;
      goto bail;
    }
  } /* maxChannels==0 */

  /* Max number of elements could be tuned any more. */
  hAacEncoder->nMaxAacElements = fixMin(((8)), hAacEncoder->nMaxAacChannels);
  hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels);

  /* In case of memory overlay, allocate memory out of libraries */

  if (hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR | ENC_MODE_FLAG_PS))
    hAacEncoder->inputBufferSizePerChannel = INPUTBUFFER_SIZE;
  else
    hAacEncoder->inputBufferSizePerChannel = (1024);

  hAacEncoder->inputBufferSize =
      hAacEncoder->nMaxAacChannels * hAacEncoder->inputBufferSizePerChannel;

  if (NULL == (hAacEncoder->inputBuffer = (INT_PCM *)FDKcalloc(
                   hAacEncoder->inputBufferSize, sizeof(INT_PCM)))) {
    err = AACENC_MEMORY_ERROR;
    goto bail;
  }

  /* Open SBR Encoder */
  if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR) {
    if (sbrEncoder_Open(
            &hAacEncoder->hEnvEnc, hAacEncoder->nMaxSbrElements,
            hAacEncoder->nMaxSbrChannels,
            (hAacEncoder->encoder_modis & ENC_MODE_FLAG_PS) ? 1 : 0)) {
      err = AACENC_MEMORY_ERROR;
      goto bail;
    }

    if (NULL == (hAacEncoder->pSbrPayload = (SBRENC_EXT_PAYLOAD *)FDKcalloc(
                     1, sizeof(SBRENC_EXT_PAYLOAD)))) {
      err = AACENC_MEMORY_ERROR;
      goto bail;
    }
  } /* (encoder_modis&ENC_MODE_FLAG_SBR) */

  /* Open Aac Encoder */
  if (FDKaacEnc_Open(&hAacEncoder->hAacEnc, hAacEncoder->nMaxAacElements,
                     hAacEncoder->nMaxAacChannels, (1)) != AAC_ENC_OK) {
    err = AACENC_MEMORY_ERROR;
    goto bail;
  }

  /* Bitstream output buffer */
  hAacEncoder->outBufferInBytes =
      1 << (DFRACT_BITS - CntLeadingZeros(fixMax(
                              1, ((1) * hAacEncoder->nMaxAacChannels * 6144) >>
                                     3))); /* buffer has to be 2^n */
  if (NULL == (hAacEncoder->outBuffer = (UCHAR *)FDKcalloc(
                   hAacEncoder->outBufferInBytes, sizeof(UCHAR)))) {
    err = AACENC_MEMORY_ERROR;
    goto bail;
  }

  /* Open Meta Data Encoder */
  if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_META) {
    if (FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc,
                             (UINT)hAacEncoder->nMaxAacChannels)) {
      err = AACENC_MEMORY_ERROR;
      goto bail;
    }
  } /* (encoder_modis&ENC_MODE_FLAG_META) */

  /* Open MPEG Surround Encoder */
  if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SAC) {
    if (MPS_ENCODER_OK != FDK_MpegsEnc_Open(&hAacEncoder->hMpsEnc)) {
      err = AACENC_MEMORY_ERROR;
      goto bail;
    }
  } /* (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SAC) */

  /* Open Transport Encoder */
  if (transportEnc_Open(&hAacEncoder->hTpEnc) != 0) {
    err = AACENC_MEMORY_ERROR;
    goto bail;
  } else {
    C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)

    LIB_INFO(*pLibInfo)
    [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;

    FDKinitLibInfo(*pLibInfo);
    transportEnc_GetLibInfo(*pLibInfo);

    /* Get capabilty flag for transport encoder. */
    hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities(*pLibInfo, FDK_TPENC);

    C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
  }
  if (transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback,
                                       hAacEncoder) != 0) {
    err = AACENC_INIT_TP_ERROR;
    goto bail;
  }
  if (transportEnc_RegisterSscCallback(hAacEncoder->hTpEnc, aacenc_SscCallback,
                                       hAacEncoder) != 0) {
    err = AACENC_INIT_TP_ERROR;
    goto bail;
  }

  /* Initialize encoder instance with default parameters. */
  aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam);

  /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */
  hAacEncoder->coderConfig.headerPeriod =
      hAacEncoder->extParam.userTpHeaderPeriod;

  /* All encoder modules have to be initialized */
  hAacEncoder->InitFlags = AACENC_INIT_ALL;

  /* Return encoder instance */
  *phAacEncoder = hAacEncoder;

  return err;

bail:
  aacEncClose(&hAacEncoder);

  return err;
}

AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) {
  AACENC_ERROR err = AACENC_OK;

  if (phAacEncoder == NULL) {
    err = AACENC_INVALID_HANDLE;
    goto bail;
  }

  if (*phAacEncoder != NULL) {
    HANDLE_AACENCODER hAacEncoder = *phAacEncoder;

    if (hAacEncoder->inputBuffer != NULL) {
      FDKfree(hAacEncoder->inputBuffer);
      hAacEncoder->inputBuffer = NULL;
    }
    if (hAacEncoder->outBuffer != NULL) {
      FDKfree(hAacEncoder->outBuffer);
      hAacEncoder->outBuffer = NULL;
    }

    if (hAacEncoder->hEnvEnc) {
      sbrEncoder_Close(&hAacEncoder->hEnvEnc);
    }
    if (hAacEncoder->pSbrPayload != NULL) {
      FDKfree(hAacEncoder->pSbrPayload);
      hAacEncoder->pSbrPayload = NULL;
    }
    if (hAacEncoder->hAacEnc) {
      FDKaacEnc_Close(&hAacEncoder->hAacEnc);
    }

    transportEnc_Close(&hAacEncoder->hTpEnc);

    if (hAacEncoder->hMetadataEnc) {
      FDK_MetadataEnc_Close(&hAacEncoder->hMetadataEnc);
    }
    if (hAacEncoder->hMpsEnc) {
      FDK_MpegsEnc_Close(&hAacEncoder->hMpsEnc);
    }

    Free_AacEncoder(phAacEncoder);
  }

bail:
  return err;
}

AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
                          const AACENC_BufDesc *inBufDesc,
                          const AACENC_BufDesc *outBufDesc,
                          const AACENC_InArgs *inargs,
                          AACENC_OutArgs *outargs) {
  AACENC_ERROR err = AACENC_OK;
  INT i, nBsBytes = 0;
  INT outBytes[(1)];
  int nExtensions = 0;
  int ancDataExtIdx = -1;

  /* deal with valid encoder handle */
  if (hAacEncoder == NULL) {
    err = AACENC_INVALID_HANDLE;
    goto bail;
  }

  /*
   * Adjust user settings and trigger reinitialization.
   */
  if (hAacEncoder->InitFlags != 0) {
    err =
        aacEncInit(hAacEncoder, hAacEncoder->InitFlags, &hAacEncoder->extParam);

    if (err != AACENC_OK) {
      /* keep init flags alive! */
      goto bail;
    }
    hAacEncoder->InitFlags = AACENC_INIT_NONE;
  }

  if (outargs != NULL) {
    FDKmemclear(outargs, sizeof(AACENC_OutArgs));
  }

  if (outBufDesc != NULL) {
    for (i = 0; i < outBufDesc->numBufs; i++) {
      if (outBufDesc->bufs[i] != NULL) {
        FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]);
      }
    }
  }

  /*
   * If only encoder handle given, independent (re)initialization can be
   * triggered.
   */
  if ((inBufDesc == NULL) && (outBufDesc == NULL) && (inargs == NULL) &&
      (outargs == NULL)) {
    goto bail;
  }

  /* check if buffer descriptors are filled out properly. */
  if ((inargs == NULL) || (outargs == NULL) ||
      ((AACENC_OK != validateBufDesc(inBufDesc)) &&
       (inargs->numInSamples > 0)) ||
      (AACENC_OK != validateBufDesc(outBufDesc))) {
    err = AACENC_UNSUPPORTED_PARAMETER;
    goto bail;
  }

  /* reset buffer wich signals number of valid bytes in output bitstream buffer
   */
  FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames * sizeof(INT));

  /*
   * Manage incoming audio samples.
   */
  if ((inBufDesc != NULL) && (inargs->numInSamples > 0) &&
      (getBufDescIdx(inBufDesc, IN_AUDIO_DATA) != -1)) {
    /* Fetch data until nSamplesToRead reached */
    INT idx = getBufDescIdx(inBufDesc, IN_AUDIO_DATA);
    INT newSamples =
        fixMax(0, fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead -
                                                   hAacEncoder->nSamplesRead));
    INT_PCM *pIn =
        hAacEncoder->inputBuffer +
        (hAacEncoder->inputBufferOffset + hAacEncoder->nSamplesRead) /
            hAacEncoder->aacConfig.nChannels;
    newSamples -=
        (newSamples %
         hAacEncoder->extParam
             .nChannels); /* process multiple samples of input channels */

    /* Copy new input samples to internal buffer */
    if (inBufDesc->bufElSizes[idx] == (INT)sizeof(INT_PCM)) {
      FDK_deinterleave((INT_PCM *)inBufDesc->bufs[idx], pIn,
                       hAacEncoder->extParam.nChannels,
                       newSamples / hAacEncoder->extParam.nChannels,
                       hAacEncoder->inputBufferSizePerChannel);
    } else if (inBufDesc->bufElSizes[idx] > (INT)sizeof(INT_PCM)) {
      FDK_deinterleave((LONG *)inBufDesc->bufs[idx], pIn,
                       hAacEncoder->extParam.nChannels,
                       newSamples / hAacEncoder->extParam.nChannels,
                       hAacEncoder->inputBufferSizePerChannel);
    } else {
      FDK_deinterleave((SHORT *)inBufDesc->bufs[idx], pIn,
                       hAacEncoder->extParam.nChannels,
                       newSamples / hAacEncoder->extParam.nChannels,
                       hAacEncoder->inputBufferSizePerChannel);
    }
    hAacEncoder->nSamplesRead += newSamples;

    /* Number of fetched input buffer samples. */
    outargs->numInSamples = newSamples;
  }

  /* input buffer completely filled ? */
  if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) {
    /* - eof reached and flushing enabled, or
       - return to main and wait for further incoming audio samples */
    if (inargs->numInSamples == -1) {
      if ((hAacEncoder->nZerosAppended < hAacEncoder->nDelay)) {
        int nZeros = (hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead) /
                     hAacEncoder->extParam.nChannels;

        FDK_ASSERT(nZeros >= 0);

        /* clear out until end-of-buffer */
        if (nZeros) {
          for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) {
            FDKmemclear(hAacEncoder->inputBuffer +
                            i * hAacEncoder->inputBufferSizePerChannel +
                            (hAacEncoder->inputBufferOffset +
                             hAacEncoder->nSamplesRead) /
                                hAacEncoder->extParam.nChannels,
                        sizeof(INT_PCM) * nZeros);
          }
          hAacEncoder->nZerosAppended += nZeros;
          hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead;
        }
      } else {                   /* flushing completed */
        err = AACENC_ENCODE_EOF; /* eof reached */
        goto bail;
      }
    } else {     /* inargs->numInSamples!= -1 */
      goto bail; /* not enough samples in input buffer and no flushing enabled
                  */
    }
  }

  /* init payload */
  FDKmemclear(hAacEncoder->extPayload,
              sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS);
  for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) {
    hAacEncoder->extPayload[i].associatedChElement = -1;
  }
  if (hAacEncoder->pSbrPayload != NULL) {
    FDKmemclear(hAacEncoder->pSbrPayload, sizeof(*hAacEncoder->pSbrPayload));
  }

  /*
   * Calculate Meta Data info.
   */
  if ((hAacEncoder->hMetadataEnc != NULL) &&
      (hAacEncoder->metaDataAllowed != 0)) {
    const AACENC_MetaData *pMetaData = NULL;
    AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL;
    UINT nMetaDataExtensions = 0;
    INT matrix_mixdown_idx = 0;

    /* New meta data info available ? */
    if (getBufDescIdx(inBufDesc, IN_METADATA_SETUP) != -1) {
      pMetaData =
          (AACENC_MetaData *)
              inBufDesc->bufs[getBufDescIdx(inBufDesc, IN_METADATA_SETUP)];
    }

    FDK_MetadataEnc_Process(
        hAacEncoder->hMetadataEnc,
        hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
                                       hAacEncoder->coderConfig.noChannels,
        hAacEncoder->inputBufferSizePerChannel, hAacEncoder->nSamplesRead,
        pMetaData, &pMetaDataExtPayload, &nMetaDataExtensions,
        &matrix_mixdown_idx);

    for (i = 0; i < (INT)nMetaDataExtensions;
         i++) { /* Get meta data extension payload. */
      hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i];
    }

    if ((matrix_mixdown_idx != -1) &&
        ((hAacEncoder->extParam.userChannelMode == MODE_1_2_2) ||
         (hAacEncoder->extParam.userChannelMode == MODE_1_2_2_1))) {
      /* Set matrix mixdown coefficient. */
      UINT pceValue = (UINT)((0 << 3) | ((matrix_mixdown_idx & 0x3) << 1) | 1);
      if (hAacEncoder->extParam.userPceAdditions != pceValue) {
        hAacEncoder->extParam.userPceAdditions = pceValue;
        hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
      }
    }
  }

  /*
   * Encode MPS data.
   */
  if ((hAacEncoder->hMpsEnc != NULL) &&
      (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
    AACENC_EXT_PAYLOAD mpsExtensionPayload;
    FDKmemclear(&mpsExtensionPayload, sizeof(AACENC_EXT_PAYLOAD));

    if (MPS_ENCODER_OK !=
        FDK_MpegsEnc_Process(
            hAacEncoder->hMpsEnc,
            hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
                                           hAacEncoder->coderConfig.noChannels,
            hAacEncoder->nSamplesRead, &mpsExtensionPayload)) {
      err = AACENC_ENCODE_ERROR;
      goto bail;
    }

    if ((mpsExtensionPayload.pData != NULL) &&
        ((mpsExtensionPayload.dataSize != 0))) {
      hAacEncoder->extPayload[nExtensions++] = mpsExtensionPayload;
    }
  }

  if ((NULL != hAacEncoder->hEnvEnc) && (NULL != hAacEncoder->pSbrPayload) &&
      isSbrActive(&hAacEncoder->aacConfig)) {
    INT nPayload = 0;

    /*
     * Encode SBR data.
     */
    if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
                               hAacEncoder->inputBufferSizePerChannel,
                               hAacEncoder->pSbrPayload->dataSize[nPayload],
                               hAacEncoder->pSbrPayload->data[nPayload])) {
      err = AACENC_ENCODE_ERROR;
      goto bail;
    } else {
      /* Add SBR extension payload */
      for (i = 0; i < (8); i++) {
        if (hAacEncoder->pSbrPayload->dataSize[nPayload][i] > 0) {
          hAacEncoder->extPayload[nExtensions].pData =
              hAacEncoder->pSbrPayload->data[nPayload][i];
          {
            hAacEncoder->extPayload[nExtensions].dataSize =
                hAacEncoder->pSbrPayload->dataSize[nPayload][i];
            hAacEncoder->extPayload[nExtensions].associatedChElement = i;
          }
          hAacEncoder->extPayload[nExtensions].dataType =
              EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set
                               EXT_SBR_DATA_CRC */
          nExtensions++;    /* or EXT_SBR_DATA according to configuration. */
          FDK_ASSERT(nExtensions <= MAX_TOTAL_EXT_PAYLOADS);
        }
      }
      nPayload++;
    }
  } /* sbrEnabled */

  if ((inargs->numAncBytes > 0) &&
      (getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA) != -1)) {
    INT idx = getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA);
    hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8;
    hAacEncoder->extPayload[nExtensions].pData = (UCHAR *)inBufDesc->bufs[idx];
    hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT;
    hAacEncoder->extPayload[nExtensions].associatedChElement = -1;
    ancDataExtIdx = nExtensions; /* store index */
    nExtensions++;
  }

  /*
   * Encode AAC - Core.
   */
  if (FDKaacEnc_EncodeFrame(hAacEncoder->hAacEnc, hAacEncoder->hTpEnc,
                            hAacEncoder->inputBuffer,
                            hAacEncoder->inputBufferSizePerChannel, outBytes,
                            hAacEncoder->extPayload) != AAC_ENC_OK) {
    err = AACENC_ENCODE_ERROR;
    goto bail;
  }

  if (ancDataExtIdx >= 0) {
    outargs->numAncBytes =
        inargs->numAncBytes -
        (hAacEncoder->extPayload[ancDataExtIdx].dataSize >> 3);
  }

  /* samples exhausted */
  hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead;

  /*
   * Delay balancing buffer handling
   */
  if (isSbrActive(&hAacEncoder->aacConfig)) {
    sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
                             hAacEncoder->inputBufferSizePerChannel);
  }

  /*
   * Make bitstream public
   */
  if ((outBufDesc != NULL) && (outBufDesc->numBufs >= 1)) {
    INT bsIdx = getBufDescIdx(outBufDesc, OUT_BITSTREAM_DATA);
    INT auIdx = getBufDescIdx(outBufDesc, OUT_AU_SIZES);

    for (i = 0, nBsBytes = 0; i < hAacEncoder->aacConfig.nSubFrames; i++) {
      nBsBytes += outBytes[i];

      if (auIdx != -1) {
        ((INT *)outBufDesc->bufs[auIdx])[i] = outBytes[i];
      }
    }

    if ((bsIdx != -1) && (outBufDesc->bufSizes[bsIdx] >= nBsBytes)) {
      FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer,
                sizeof(UCHAR) * nBsBytes);
      outargs->numOutBytes = nBsBytes;
      outargs->bitResState =
          FDKaacEnc_GetBitReservoirState(hAacEncoder->hAacEnc);
    } else {
      /* output buffer too small, can't write valid bitstream */
      err = AACENC_ENCODE_ERROR;
      goto bail;
    }
  }

bail:
  if (err == AACENC_ENCODE_ERROR) {
    /* All encoder modules have to be initialized */
    hAacEncoder->InitFlags = AACENC_INIT_ALL;
  }

  return err;
}

static AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder,
                                       UINT *size, UCHAR *confBuffer) {
  FDK_BITSTREAM tmpConf;
  UINT confType;
  UCHAR buf[64];
  int err;

  /* Init bit buffer */
  FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER);

  /* write conf in tmp buffer */
  err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig,
                             &tmpConf, &confType);

  /* copy data to outbuffer: length in bytes */
  FDKbyteAlign(&tmpConf, 0);

  /* Check buffer size */
  if (FDKgetValidBits(&tmpConf) > ((*size) << 3)) return AAC_ENC_UNKNOWN;

  FDKfetchBuffer(&tmpConf, confBuffer, size);

  if (err != 0)
    return AAC_ENC_UNKNOWN;
  else
    return AAC_ENC_OK;
}

AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) {
  int i = 0;

  if (info == NULL) {
    return AACENC_INVALID_HANDLE;
  }

  FDK_toolsGetLibInfo(info);
  transportEnc_GetLibInfo(info);
  sbrEncoder_GetLibInfo(info);
  FDK_MpegsEnc_GetLibInfo(info);

  /* search for next free tab */
  for (i = 0; i < FDK_MODULE_LAST; i++) {
    if (info[i].module_id == FDK_NONE) break;
  }
  if (i == FDK_MODULE_LAST) {
    return AACENC_INIT_ERROR;
  }

  info[i].module_id = FDK_AACENC;
  info[i].build_date = AACENCODER_LIB_BUILD_DATE;
  info[i].build_time = AACENCODER_LIB_BUILD_TIME;
  info[i].title = AACENCODER_LIB_TITLE;
  info[i].version =
      LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2);
  ;
  LIB_VERSION_STRING(&info[i]);

  /* Capability flags */
  info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_512 |
                  CAPF_AAC_480 | CAPF_AAC_DRC | CAPF_AAC_ELD_DOWNSCALE;
  /* End of flags */

  return AACENC_OK;
}

AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
                                 const AACENC_PARAM param, const UINT value) {
  AACENC_ERROR err = AACENC_OK;
  USER_PARAM *settings = &hAacEncoder->extParam;

  /* check encoder handle */
  if (hAacEncoder == NULL) {
    err = AACENC_INVALID_HANDLE;
    goto bail;
  }

  /* apply param value */
  switch (param) {
    case AACENC_AOT:
      if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) {
        /* check if AOT matches the allocated modules */
        switch (value) {
          case AOT_PS:
            if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
              err = AACENC_INVALID_CONFIG;
              goto bail;
            }
            FDK_FALLTHROUGH;
          case AOT_SBR:
          case AOT_MP2_SBR:
            if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
              err = AACENC_INVALID_CONFIG;
              goto bail;
            }
            FDK_FALLTHROUGH;
          case AOT_AAC_LC:
          case AOT_MP2_AAC_LC:
          case AOT_ER_AAC_LD:
          case AOT_ER_AAC_ELD:
            if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
              err = AACENC_INVALID_CONFIG;
              goto bail;
            }
            break;
          default:
            err = AACENC_INVALID_CONFIG;
            goto bail;
        } /* switch value */
        settings->userAOT = (AUDIO_OBJECT_TYPE)value;
        hAacEncoder->InitFlags |=
            AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_BITRATE:
      if (settings->userBitrate != value) {
        settings->userBitrate = value;
        hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_BITRATEMODE:
      if (settings->userBitrateMode != value) {
        switch (value) {
          case 0:
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
            settings->userBitrateMode = value;
            hAacEncoder->InitFlags |=
                AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
            break;
          default:
            err = AACENC_INVALID_CONFIG;
            break;
        } /* switch value */
      }
      break;
    case AACENC_SAMPLERATE:
      if (settings->userSamplerate != value) {
        if (!((value == 8000) || (value == 11025) || (value == 12000) ||
              (value == 16000) || (value == 22050) || (value == 24000) ||
              (value == 32000) || (value == 44100) || (value == 48000) ||
              (value == 64000) || (value == 88200) || (value == 96000))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userSamplerate = value;
        hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
        hAacEncoder->InitFlags |=
            AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_CHANNELMODE:
      if (settings->userChannelMode != (CHANNEL_MODE)value) {
        if (((CHANNEL_MODE)value == MODE_212) &&
            (NULL != hAacEncoder->hMpsEnc)) {
          settings->userChannelMode = (CHANNEL_MODE)value;
          settings->nChannels = 2;
        } else {
          const CHANNEL_MODE_CONFIG_TAB *pConfig =
              FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value);
          if (pConfig == NULL) {
            err = AACENC_INVALID_CONFIG;
            break;
          }
          if ((pConfig->nElements > hAacEncoder->nMaxAacElements) ||
              (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels)) {
            err = AACENC_INVALID_CONFIG;
            break;
          }

          settings->userChannelMode = (CHANNEL_MODE)value;
          settings->nChannels = pConfig->nChannels;
        }
        hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
        hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
        if (!((value >= 1) && (value <= 6))) {
          hAacEncoder->InitFlags |= AACENC_INIT_STATES;
        }
      }
      break;
    case AACENC_BANDWIDTH:
      if (settings->userBandwidth != value) {
        settings->userBandwidth = value;
        hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
      }
      break;
    case AACENC_CHANNELORDER:
      if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) {
        if (!((value == 0) || (value == 1))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value;
        hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
        hAacEncoder->InitFlags |=
            AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_AFTERBURNER:
      if (settings->userAfterburner != value) {
        if (!((value == 0) || (value == 1))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userAfterburner = value;
        hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
      }
      break;
    case AACENC_GRANULE_LENGTH:
      if (settings->userFramelength != value) {
        switch (value) {
          case 1024:
          case 512:
          case 480:
          case 256:
          case 240:
          case 128:
          case 120:
            if ((value << 1) == 480 || (value << 1) == 512) {
              settings->userDownscaleFactor = 2;
            } else if ((value << 2) == 480 || (value << 2) == 512) {
              settings->userDownscaleFactor = 4;
            }
            settings->userFramelength = value;
            hAacEncoder->InitFlags |=
                AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
            break;
          default:
            err = AACENC_INVALID_CONFIG;
            break;
        }
      }
      break;
    case AACENC_SBR_RATIO:
      if (settings->userSbrRatio != value) {
        if (!((value == 0) || (value == 1) || (value == 2))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userSbrRatio = value;
        hAacEncoder->InitFlags |=
            AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_SBR_MODE:
      if ((settings->userSbrEnabled != value) &&
          (NULL != hAacEncoder->hEnvEnc)) {
        settings->userSbrEnabled = value;
        hAacEncoder->InitFlags |=
            AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_TRANSMUX:
      if (settings->userTpType != (TRANSPORT_TYPE)value) {
        TRANSPORT_TYPE type = (TRANSPORT_TYPE)value;
        UINT flags = hAacEncoder->CAPF_tpEnc;

        if (!(((type == TT_MP4_ADIF) && (flags & CAPF_ADIF)) ||
              ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) ||
              ((type == TT_MP4_LATM_MCP0) &&
               ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
              ((type == TT_MP4_LATM_MCP1) &&
               ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
              ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) ||
              ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userTpType = (TRANSPORT_TYPE)value;
        hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_SIGNALING_MODE:
      if (settings->userTpSignaling != value) {
        if (!((value == 0) || (value == 1) || (value == 2))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userTpSignaling = value;
        hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_PROTECTION:
      if (settings->userTpProtection != value) {
        if (!((value == 0) || (value == 1))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userTpProtection = value;
        hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_HEADER_PERIOD:
      if (settings->userTpHeaderPeriod != value) {
        if (!(((INT)value >= 0) && (value <= 255))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userTpHeaderPeriod = value;
        hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_AUDIOMUXVER:
      if (settings->userTpAmxv != value) {
        if (!((value == 0) || (value == 1) || (value == 2))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userTpAmxv = value;
        hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_TPSUBFRAMES:
      if (settings->userTpNsubFrames != value) {
        if (!((value >= 1) && (value <= 4))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userTpNsubFrames = value;
        hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
      }
      break;
    case AACENC_ANCILLARY_BITRATE:
      if (settings->userAncDataRate != value) {
        settings->userAncDataRate = value;
      }
      break;
    case AACENC_CONTROL_STATE:
      if (hAacEncoder->InitFlags != value) {
        if (value & AACENC_RESET_INBUFFER) {
          hAacEncoder->nSamplesRead = 0;
        }
        hAacEncoder->InitFlags = value;
      }
      break;
    case AACENC_METADATA_MODE:
      if ((UINT)settings->userMetaDataMode != value) {
        if (!(((INT)value >= 0) && ((INT)value <= 3))) {
          err = AACENC_INVALID_CONFIG;
          break;
        }
        settings->userMetaDataMode = value;
        hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
      }
      break;
    case AACENC_PEAK_BITRATE:
      if (settings->userPeakBitrate != value) {
        settings->userPeakBitrate = value;
        hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
      }
      break;
    default:
      err = AACENC_UNSUPPORTED_PARAMETER;
      break;
  } /* switch(param) */

bail:
  return err;
}

UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder,
                         const AACENC_PARAM param) {
  UINT value = 0;
  USER_PARAM *settings = &hAacEncoder->extParam;

  /* check encoder handle */
  if (hAacEncoder == NULL) {
    goto bail;
  }

  /* apply param value */
  switch (param) {
    case AACENC_AOT:
      value = (UINT)hAacEncoder->aacConfig.audioObjectType;
      break;
    case AACENC_BITRATE:
      switch (hAacEncoder->aacConfig.bitrateMode) {
        case AACENC_BR_MODE_CBR:
          value = (UINT)hAacEncoder->aacConfig.bitRate;
          break;
        default:
          value = (UINT)-1;
      }
      break;
    case AACENC_BITRATEMODE:
      value = (UINT)((hAacEncoder->aacConfig.bitrateMode != AACENC_BR_MODE_FF)
                         ? hAacEncoder->aacConfig.bitrateMode
                         : AACENC_BR_MODE_CBR);
      break;
    case AACENC_SAMPLERATE:
      value = (UINT)hAacEncoder->coderConfig.extSamplingRate;
      break;
    case AACENC_CHANNELMODE:
      if ((MODE_1 == hAacEncoder->aacConfig.channelMode) &&
          (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
        value = MODE_212;
      } else {
        value = (UINT)hAacEncoder->aacConfig.channelMode;
      }
      break;
    case AACENC_BANDWIDTH:
      value = (UINT)hAacEncoder->aacConfig.bandWidth;
      break;
    case AACENC_CHANNELORDER:
      value = (UINT)hAacEncoder->aacConfig.channelOrder;
      break;
    case AACENC_AFTERBURNER:
      value = (UINT)hAacEncoder->aacConfig.useRequant;
      break;
    case AACENC_GRANULE_LENGTH:
      value = (UINT)hAacEncoder->aacConfig.framelength;
      break;
    case AACENC_SBR_RATIO:
      value = isSbrActive(&hAacEncoder->aacConfig)
                  ? hAacEncoder->aacConfig.sbrRatio
                  : 0;
      break;
    case AACENC_SBR_MODE:
      value =
          (UINT)(hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0;
      break;
    case AACENC_TRANSMUX:
      value = (UINT)settings->userTpType;
      break;
    case AACENC_SIGNALING_MODE:
      value = (UINT)getSbrSignalingMode(
          hAacEncoder->aacConfig.audioObjectType, settings->userTpType,
          settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio);
      break;
    case AACENC_PROTECTION:
      value = (UINT)settings->userTpProtection;
      break;
    case AACENC_HEADER_PERIOD:
      value = (UINT)hAacEncoder->coderConfig.headerPeriod;
      break;
    case AACENC_AUDIOMUXVER:
      value = (UINT)hAacEncoder->aacConfig.audioMuxVersion;
      break;
    case AACENC_TPSUBFRAMES:
      value = (UINT)settings->userTpNsubFrames;
      break;
    case AACENC_ANCILLARY_BITRATE:
      value = (UINT)hAacEncoder->aacConfig.anc_Rate;
      break;
    case AACENC_CONTROL_STATE:
      value = (UINT)hAacEncoder->InitFlags;
      break;
    case AACENC_METADATA_MODE:
      value = (hAacEncoder->metaDataAllowed == 0)
                  ? 0
                  : (UINT)settings->userMetaDataMode;
      break;
    case AACENC_PEAK_BITRATE:
      value = (UINT)-1; /* peak bitrate parameter is meaningless */
      if (((INT)hAacEncoder->extParam.userPeakBitrate != -1)) {
        value =
            (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate,
                        hAacEncoder->aacConfig
                            .bitRate)); /* peak bitrate parameter is in use */
      }
      break;

    default:
      // err = MPS_INVALID_PARAMETER;
      break;
  } /* switch(param) */

bail:
  return value;
}

AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
                        AACENC_InfoStruct *pInfo) {
  AACENC_ERROR err = AACENC_OK;

  FDKmemclear(pInfo, sizeof(AACENC_InfoStruct));
  pInfo->confSize = 64; /* pre-initialize */

  pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels * 6144) + 7) >> 3;
  pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU;
  pInfo->inBufFillLevel =
      hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
  pInfo->inputChannels = hAacEncoder->extParam.nChannels;
  pInfo->frameLength =
      hAacEncoder->nSamplesToRead / hAacEncoder->extParam.nChannels;
  pInfo->nDelay = hAacEncoder->nDelay;
  pInfo->nDelayCore = hAacEncoder->nDelayCore;

  /* Get encoder configuration */
  if (aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) !=
      AAC_ENC_OK) {
    err = AACENC_INIT_ERROR;
    goto bail;
  }
bail:
  return err;
}
