/* -----------------------------------------------------------------------------
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):   M. Schug / A. Groeschel

   Description: fast aac coder functions

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

#include "aacenc.h"

#include "bitenc.h"
#include "interface.h"
#include "psy_configuration.h"
#include "psy_main.h"
#include "qc_main.h"
#include "bandwidth.h"
#include "channel_map.h"
#include "tns_func.h"
#include "aacEnc_ram.h"

#include "genericStds.h"

#define BITRES_MAX_LD 4000
#define BITRES_MIN_LD 500
#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */

INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength,
                               const INT samplingRate) {
  int shift = 0;
  while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
         (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
    shift++;
  }

  return (bitRate * (frameLength >> shift)) / (samplingRate >> shift);
}

INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength,
                          const INT samplingRate) {
  int shift = 0;
  while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
         (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
    shift++;
  }

  return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift);
}

static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
    INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
    INT sampleRate);

INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
                           INT coreSamplingRate, INT frameLength, INT nChannels,
                           INT nChannelsEff, INT bitRate, INT averageBits,
                           INT *pAverageBitsPerFrame,
                           AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) {
  INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0;
  INT minBitsPerFrame = 40 * nChannels;
  if (isLowDelay(aot)) {
    minBitrate = 8000 * nChannelsEff;
  }

  do {
    prevBitRate = bitRate;
    averageBitsPerFrame =
        FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) /
        nSubFrames;

    if (pAverageBitsPerFrame != NULL) {
      *pAverageBitsPerFrame = averageBitsPerFrame;
    }

    if (hTpEnc != NULL) {
      transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
    } else {
      /* Assume some worst case */
      transportBits = 208;
    }

    bitRate = fMax(bitRate,
                   fMax(minBitrate,
                        FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits),
                                              frameLength, coreSamplingRate)));
    FDK_ASSERT(bitRate >= 0);

    bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate(
                                (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN),
                                frameLength, coreSamplingRate));
    FDK_ASSERT(bitRate >= 0);

  } while (prevBitRate != bitRate && iter++ < 3);

  return bitRate;
}

typedef struct {
  AACENC_BITRATE_MODE bitrateMode;
  int chanBitrate[2]; /* mono/stereo settings */
} CONFIG_TAB_ENTRY_VBR;

static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = {
    {AACENC_BR_MODE_CBR, {0, 0}},
    {AACENC_BR_MODE_VBR_1, {32000, 20000}},
    {AACENC_BR_MODE_VBR_2, {40000, 32000}},
    {AACENC_BR_MODE_VBR_3, {56000, 48000}},
    {AACENC_BR_MODE_VBR_4, {72000, 64000}},
    {AACENC_BR_MODE_VBR_5, {112000, 96000}}};

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

     functionname: FDKaacEnc_GetVBRBitrate
     description:  Get VBR bitrate from vbr quality
     input params: int vbrQuality (VBR0, VBR1, VBR2)
                   channelMode
     returns:      vbr bitrate

 ------------------------------------------------------------------------------*/
INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
                            CHANNEL_MODE channelMode) {
  INT bitrate = 0;
  INT monoStereoMode = 0; /* default mono */

  if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) {
    monoStereoMode = 1;
  }

  switch (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:
      bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode];
      break;
    case AACENC_BR_MODE_INVALID:
    case AACENC_BR_MODE_CBR:
    case AACENC_BR_MODE_SFR:
    case AACENC_BR_MODE_FF:
    default:
      bitrate = 0;
      break;
  }

  /* convert channel bitrate to overall bitrate*/
  bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;

  return bitrate;
}

/**
 * \brief  Convert encoder bitreservoir value for transport library.
 *
 * \param hAacEnc               Encoder handle
 *
 * \return  Corrected bitreservoir level used in transport library.
 */
static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) {
  INT transportBitreservoir = 0;

  switch (hAacEnc->bitrateMode) {
    case AACENC_BR_MODE_CBR:
      transportBitreservoir =
          hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
      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:
      transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */
      break;
    case AACENC_BR_MODE_SFR:
      transportBitreservoir = 0; /* super framing and fixed framing */
      break;                     /* without bitreservoir signaling */
    default:
    case AACENC_BR_MODE_INVALID:
      transportBitreservoir = 0; /* invalid configuration*/
  }

  if (hAacEnc->config->audioMuxVersion == 2) {
    transportBitreservoir =
        MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
  }

  return transportBitreservoir;
}

INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) {
  return FDKaacEnc_EncBitresToTpBitres(hAacEncoder);
}

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

     functionname: FDKaacEnc_AacInitDefaultConfig
     description:  gives reasonable default configuration
     returns:      ---

 ------------------------------------------------------------------------------*/
void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) {
  /* make the preinitialization of the structs flexible */
  FDKmemclear(config, sizeof(AACENC_CONFIG));

  /* default ancillary */
  config->anc_Rate = 0;       /* no ancillary data */
  config->ancDataBitRate = 0; /* no additional consumed bitrate */

  /* default configurations */
  config->bitRate = -1; /* bitrate must be set*/
  config->averageBits =
      -1; /* instead of bitrate/s we can configure bits/superframe */
  config->bitrateMode =
      AACENC_BR_MODE_CBR;           /* set bitrate mode to constant bitrate */
  config->bandWidth = 0;            /* get bandwidth from table */
  config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */
  config->usePns =
      1; /* depending on channelBitrate this might be set to 0 later */
  config->useIS = 1;        /* Intensity Stereo Configuration */
  config->useMS = 1;        /* MS Stereo tool */
  config->framelength = -1; /* Framesize not configured */
  config->syntaxFlags = 0;  /* default syntax with no specialities */
  config->epConfig = -1;    /* no ER syntax -> no additional error protection */
  config->nSubFrames = 1;   /* default, no sub frames */
  config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */
  config->channelMode = MODE_UNKNOWN;
  config->minBitsPerFrame = -1; /* minum number of bits in each AU */
  config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
  config->audioMuxVersion = -1; /* audio mux version not configured */
  config->downscaleFactor =
      1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */
}

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

    functionname: FDKaacEnc_Open
    description:  allocate and initialize a new encoder instance
    returns:      error code

  ---------------------------------------------------------------------------*/
AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements,
                                 const INT nChannels, const INT nSubFrames) {
  AAC_ENCODER_ERROR ErrorStatus;
  AAC_ENC *hAacEnc = NULL;
  UCHAR *dynamicRAM = NULL;

  if (phAacEnc == NULL) {
    return AAC_ENC_INVALID_HANDLE;
  }

  /* allocate encoder structure */
  hAacEnc = GetRam_aacEnc_AacEncoder();
  if (hAacEnc == NULL) {
    ErrorStatus = AAC_ENC_NO_MEMORY;
    goto bail;
  }
  FDKmemclear(hAacEnc, sizeof(AAC_ENC));

  if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) {
    ErrorStatus = AAC_ENC_NO_MEMORY;
    goto bail;
  }
  dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM;

  /* allocate the Psy aud Psy Out structure */
  ErrorStatus =
      FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels,
                                    nSubFrames, dynamicRAM);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  /* allocate the Q&C Out structure */
  ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels,
                                   nSubFrames, dynamicRAM);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  /* allocate the Q&C kernel */
  ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  hAacEnc->maxChannels = nChannels;
  hAacEnc->maxElements = nElements;
  hAacEnc->maxFrames = nSubFrames;

bail:
  *phAacEnc = hAacEnc;
  return ErrorStatus;
}

AAC_ENCODER_ERROR FDKaacEnc_Initialize(
    HANDLE_AAC_ENC hAacEnc,
    AACENC_CONFIG *config, /* pre-initialized config struct */
    HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) {
  AAC_ENCODER_ERROR ErrorStatus;
  INT psyBitrate, tnsMask;  // INT profile = 1;
  CHANNEL_MAPPING *cm = NULL;

  INT mbfac_e, qbw;
  FIXP_DBL mbfac, bw_ratio;
  QC_INIT qcInit;
  INT averageBitsPerFrame = 0;
  int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */
  const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;

  if (config == NULL) return AAC_ENC_INVALID_HANDLE;

  /******************* sanity checks *******************/

  /* check config structure */
  if (config->nChannels < 1 || config->nChannels > (8)) {
    return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
  }

  /* check sample rate */
  switch (config->sampleRate) {
    case 8000:
    case 11025:
    case 12000:
    case 16000:
    case 22050:
    case 24000:
    case 32000:
    case 44100:
    case 48000:
    case 64000:
    case 88200:
    case 96000:
      break;
    default:
      return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
  }

  /* bitrate has to be set */
  if (config->bitRate == -1) {
    return AAC_ENC_UNSUPPORTED_BITRATE;
  }

  /* check bit rate */

  if (FDKaacEnc_LimitBitrate(
          hTpEnc, config->audioObjectType, config->sampleRate,
          config->framelength, config->nChannels,
          FDKaacEnc_GetChannelModeConfiguration(config->channelMode)
              ->nChannelsEff,
          config->bitRate, config->averageBits, &averageBitsPerFrame,
          config->bitrateMode, config->nSubFrames) != config->bitRate &&
      !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) {
    return AAC_ENC_UNSUPPORTED_BITRATE;
  }

  if (config->syntaxFlags & AC_ER_VCB11) {
    return AAC_ENC_UNSUPPORTED_ER_FORMAT;
  }
  if (config->syntaxFlags & AC_ER_HCR) {
    return AAC_ENC_UNSUPPORTED_ER_FORMAT;
  }

  /* check frame length */
  switch (config->framelength) {
    case 1024:
      if (isLowDelay(config->audioObjectType)) {
        return AAC_ENC_INVALID_FRAME_LENGTH;
      }
      break;
    case 128:
    case 256:
    case 512:
    case 120:
    case 240:
    case 480:
      if (!isLowDelay(config->audioObjectType)) {
        return AAC_ENC_INVALID_FRAME_LENGTH;
      }
      break;
    default:
      return AAC_ENC_INVALID_FRAME_LENGTH;
  }

  if (config->anc_Rate != 0) {
    ErrorStatus = FDKaacEnc_InitCheckAncillary(
        config->bitRate, config->framelength, config->anc_Rate,
        &hAacEnc->ancillaryBitsPerFrame, config->sampleRate);
    if (ErrorStatus != AAC_ENC_OK) goto bail;

    /* update estimated consumed bitrate */
    config->ancDataBitRate +=
        FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame,
                              config->framelength, config->sampleRate);
  }

  /* maximal allowed DSE bytes in frame */
  config->maxAncBytesPerAU =
      fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame(
                              (config->bitRate - (config->nChannels * 8000)),
                              config->framelength, config->sampleRate) >>
                              3));

  /* bind config to hAacEnc->config */
  hAacEnc->config = config;

  /* set hAacEnc->bitrateMode */
  hAacEnc->bitrateMode = config->bitrateMode;

  hAacEnc->encoderMode = config->channelMode;

  ErrorStatus = FDKaacEnc_InitChannelMapping(
      hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  cm = &hAacEnc->channelMapping;

  ErrorStatus = FDKaacEnc_DetermineBandWidth(
      config->bandWidth, config->bitRate - config->ancDataBitRate,
      hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm,
      hAacEnc->encoderMode, &hAacEnc->config->bandWidth);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth;

  tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0;
  psyBitrate = config->bitRate - config->ancDataBitRate;

  if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) {
    /* Reinitialize psych states in case of channel configuration change ore if
     * full reset requested. */
    ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut,
                                    hAacEnc->maxFrames, hAacEnc->maxChannels,
                                    config->audioObjectType, cm);
    if (ErrorStatus != AAC_ENC_OK) goto bail;
  }

  ErrorStatus = FDKaacEnc_psyMainInit(
      hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate,
      config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB,
      config->usePns, config->useIS, config->useMS, config->syntaxFlags,
      initFlags);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  qcInit.channelMapping = &hAacEnc->channelMapping;
  qcInit.sceCpe = 0;

  if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) {
    qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
    qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
    qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
    qcInit.maxBits = (config->maxBitsPerFrame != -1)
                         ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
                         : qcInit.maxBits;
    qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7);
    qcInit.minBits =
        (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
    qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
  } else {
    INT bitreservoir = -1; /* default bitrservoir size*/
    if (isLowDelay(config->audioObjectType)) {
      INT brPerChannel = config->bitRate / config->nChannels;
      brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));

      /* bitreservoir  =
       * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes;
       */
      FIXP_DBL slope = fDivNorm(
          (brPerChannel - BITRATE_MIN_LD),
          BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */
      bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
                     BITRES_MIN_LD;     /* interpolate */
      bitreservoir = bitreservoir & ~7; /* align to bytes */
      bitresMin = BITRES_MIN_LD;
    }

    int maxBitres;
    qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
    maxBitres =
        (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits;
    qcInit.bitRes =
        (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres;

    qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
                            ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes);
    qcInit.maxBits = (config->maxBitsPerFrame != -1)
                         ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
                         : qcInit.maxBits;
    qcInit.maxBits =
        fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
               fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7));

    qcInit.minBits = fixMax(
        0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes -
               transportEnc_GetStaticBits(
                   hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes));
    qcInit.minBits = (config->minBitsPerFrame != -1)
                         ? fixMax(qcInit.minBits, config->minBitsPerFrame)
                         : qcInit.minBits;
    qcInit.minBits = fixMin(
        qcInit.minBits, (averageBitsPerFrame -
                         transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) &
                            ~7);
  }

  qcInit.sampleRate = config->sampleRate;
  qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0;
  qcInit.nSubFrames = config->nSubFrames;
  qcInit.padding.paddingRest = config->sampleRate;

  if (qcInit.bitRes >= bitresMin * config->nChannels) {
    qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
  } else if (qcInit.bitRes > 0) {
    qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
  } else {
    qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
  }

  /* Configure bitrate distribution strategy. */
  switch (config->channelMode) {
    case MODE_1_2:
    case MODE_1_2_1:
    case MODE_1_2_2:
    case MODE_1_2_2_1:
    case MODE_6_1:
    case MODE_1_2_2_2_1:
    case MODE_7_1_BACK:
    case MODE_7_1_TOP_FRONT:
    case MODE_7_1_REAR_SURROUND:
    case MODE_7_1_FRONT_CENTER:
      qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */
      break;
    case MODE_1:
    case MODE_2:
    default:                          /* all non mpeg defined channel modes */
      qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */
  }                                   /* config->channelMode */

  /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG *
   * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
  bw_ratio =
      fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB),
               (FIXP_DBL)(config->sampleRate), &qbw);
  qcInit.meanPe =
      fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1);

  /* Calc maxBitFac, scale it to 24 bit accuracy */
  mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames,
                   &mbfac_e);
  qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e));

  switch (config->bitrateMode) {
    case AACENC_BR_MODE_CBR:
      qcInit.bitrateMode = QCDATA_BR_MODE_CBR;
      break;
    case AACENC_BR_MODE_VBR_1:
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1;
      break;
    case AACENC_BR_MODE_VBR_2:
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2;
      break;
    case AACENC_BR_MODE_VBR_3:
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3;
      break;
    case AACENC_BR_MODE_VBR_4:
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4;
      break;
    case AACENC_BR_MODE_VBR_5:
      qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5;
      break;
    case AACENC_BR_MODE_SFR:
      qcInit.bitrateMode = QCDATA_BR_MODE_SFR;
      break;
    case AACENC_BR_MODE_FF:
      qcInit.bitrateMode = QCDATA_BR_MODE_FF;
      break;
    default:
      ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE;
      goto bail;
  }

  qcInit.invQuant = (config->useRequant) ? 2 : 0;

  /* maxIterations should be set to the maximum number of requantization
   * iterations that are allowed before the crash recovery functionality is
   * activated. This setting should be adjusted to the processing power
   * available, i.e. to the processing power headroom in one frame that is still
   * left after normal encoding without requantization. Please note that if
   * activated this functionality is used most likely only in cases where the
   * encoder is operating beyond recommended settings, i.e. the audio quality is
   * suboptimal anyway. Activating the crash recovery does not further reduce
   * audio quality significantly in these cases. */
  if (isLowDelay(config->audioObjectType)) {
    qcInit.maxIterations = 2;
  } else {
    qcInit.maxIterations = 5;
  }

  qcInit.bitrate = config->bitRate - config->ancDataBitRate;

  qcInit.staticBits = transportEnc_GetStaticBits(
      hTpEnc, qcInit.averageBits / qcInit.nSubFrames);

  ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags);
  if (ErrorStatus != AAC_ENC_OK) goto bail;

  /* Map virtual aot's to intern aot used in bitstream writer. */
  switch (hAacEnc->config->audioObjectType) {
    case AOT_MP2_AAC_LC:
      hAacEnc->aot = AOT_AAC_LC;
      break;
    case AOT_MP2_SBR:
      hAacEnc->aot = AOT_SBR;
      break;
    default:
      hAacEnc->aot = hAacEnc->config->audioObjectType;
  }

  /* common things */

  return AAC_ENC_OK;

bail:

  return ErrorStatus;
}

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

    functionname: FDKaacEnc_EncodeFrame
    description:  encodes one frame
    returns:      error code

  ---------------------------------------------------------------------------*/
AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
    HANDLE_AAC_ENC hAacEnc, /* encoder handle */
    HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer,
    const UINT inputBufferBufSize, INT *nOutBytes,
    AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) {
  AAC_ENCODER_ERROR ErrorStatus;
  int el, n, c = 0;
  UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS];

  CHANNEL_MAPPING *cm = &hAacEnc->channelMapping;

  PSY_OUT *psyOut = hAacEnc->psyOut[c];
  QC_OUT *qcOut = hAacEnc->qcOut[c];

  FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR));

  qcOut->elementExtBits = 0; /* sum up all extended bit of each element */
  qcOut->staticBits = 0;     /* sum up side info bits of each element */
  qcOut->totalNoRedPe = 0;   /* sum up PE */

  /* advance psychoacoustics */
  for (el = 0; el < cm->nElements; el++) {
    ELEMENT_INFO elInfo = cm->elInfo[el];

    if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
        (elInfo.elType == ID_LFE)) {
      int ch;

      /* update pointer!*/
      for (ch = 0; ch < elInfo.nChannelsInEl; ch++) {
        PSY_OUT_CHANNEL *psyOutChan =
            psyOut->psyOutElement[el]->psyOutChannel[ch];
        QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch];

        psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum;
        psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy;
        psyOutChan->sfbEnergy = qcOutChan->sfbEnergy;
        psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData;
        psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData;
        psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData;
      }

      ErrorStatus = FDKaacEnc_psyMain(
          elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el],
          hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf,
          psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize,
          cm->elInfo[el].ChannelIndex, cm->nChannels);

      if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;

      /* FormFactor, Pe and staticBitDemand calculation */
      ErrorStatus = FDKaacEnc_QCMainPrepare(
          &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el],
          psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot,
          hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);

      if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;

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

      qcOut->qcElement[el]->extBitsUsed = 0;
      qcOut->qcElement[el]->nExtensions = 0;
      /* reset extension payload */
      FDKmemclear(&qcOut->qcElement[el]->extension,
                  (1) * sizeof(QC_OUT_EXTENSION));

      for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
        if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) &&
            (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) {
          int idx = qcOut->qcElement[el]->nExtensions++;

          qcOut->qcElement[el]->extension[idx].type =
              extPayload[n].dataType; /* Perform a sanity check on the type? */
          qcOut->qcElement[el]->extension[idx].nPayloadBits =
              extPayload[n].dataSize;
          qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData;
          /* Now ask the bitstream encoder how many bits we need to encode the
           * data with the current bitstream syntax: */
          qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData(
              NULL, &qcOut->qcElement[el]->extension[idx], 0, 0,
              hAacEnc->config->syntaxFlags, hAacEnc->aot,
              hAacEnc->config->epConfig);
          extPayloadUsed[n] = 1;
        }
      }

      /* sum up extension and static bits for all channel elements */
      qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed;
      qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed;

      /* sum up pe */
      qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe;
    }
  }

  qcOut->nExtensions = 0;
  qcOut->globalExtBits = 0;

  /* reset extension payload */
  FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION));

  /* Add extension payload not assigned to an channel element
    (Ancillary data is the only supported type up to now) */
  for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
    if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) &&
        (extPayload[n].pData != NULL)) {
      UINT payloadBits = 0;

      if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
        if (hAacEnc->ancillaryBitsPerFrame) {
          /* granted frame dse bitrate */
          payloadBits = hAacEnc->ancillaryBitsPerFrame;
        } else {
          /* write anc data if bitrate constraint fulfilled */
          if ((extPayload[n].dataSize >> 3) <=
              hAacEnc->config->maxAncBytesPerAU) {
            payloadBits = extPayload[n].dataSize;
          }
        }
        payloadBits = fixMin(extPayload[n].dataSize, payloadBits);
      } else {
        payloadBits = extPayload[n].dataSize;
      }

      if (payloadBits > 0) {
        int idx = qcOut->nExtensions++;

        qcOut->extension[idx].type =
            extPayload[n].dataType; /* Perform a sanity check on the type? */
        qcOut->extension[idx].nPayloadBits = payloadBits;
        qcOut->extension[idx].pPayload = extPayload[n].pData;
        /* Now ask the bitstream encoder how many bits we need to encode the
         * data with the current bitstream syntax: */
        qcOut->globalExtBits += FDKaacEnc_writeExtensionData(
            NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags,
            hAacEnc->aot, hAacEnc->config->epConfig);
        if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
          /* substract the processed bits */
          extPayload[n].dataSize -= payloadBits;
        }
        extPayloadUsed[n] = 1;
      }
    }
  }

  if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) {
    qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */
  }

  /* build bitstream all nSubFrames */
  {
    INT totalBits = 0; /* Total AU bits */
    ;
    INT avgTotalBits = 0;

    /*-------------------------------------------- */
    /* Get average total bits */
    /*-------------------------------------------- */
    {
      /* frame wise bitrate adaption */
      FDKaacEnc_AdjustBitrate(
          hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate,
          hAacEnc->config->sampleRate, hAacEnc->config->framelength);

      /* adjust super frame bitrate */
      avgTotalBits *= hAacEnc->config->nSubFrames;
    }

    /* Make first estimate of transport header overhead.
       Take maximum possible frame size into account to prevent bitreservoir
       underrun. */
    hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(
        hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot);

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

    ErrorStatus = FDKaacEnc_QCMain(
        hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm,
        hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);

    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
    /*-------------------------------------------- */

    /*-------------------------------------------- */
    ErrorStatus = FDKaacEnc_updateFillBits(
        cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut);
    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;

    /*-------------------------------------------- */
    ErrorStatus = FDKaacEnc_FinalizeBitConsumption(
        cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot,
        hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
    /*-------------------------------------------- */
    totalBits += qcOut->totalBits;

    /*-------------------------------------------- */
    FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut);

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

    /* for ( all sub frames ) ... */
    /* write bitstream header */
    if (TRANSPORTENC_OK !=
        transportEnc_WriteAccessUnit(hTpEnc, totalBits,
                                     FDKaacEnc_EncBitresToTpBitres(hAacEnc),
                                     cm->nChannelsEff)) {
      return AAC_ENC_UNKNOWN;
    }

    /* write bitstream */
    ErrorStatus = FDKaacEnc_WriteBitstream(
        hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot,
        hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);

    if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;

    /* transportEnc_EndAccessUnit() is being called inside
     * FDKaacEnc_WriteBitstream() */
    if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) {
      return AAC_ENC_UNKNOWN;
    }

  } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */

  /*-------------------------------------------- */
  return AAC_ENC_OK;
}

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

    functionname:FDKaacEnc_Close
    description: delete encoder instance
    returns:

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

void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */
{
  if (*phAacEnc == NULL) {
    return;
  }
  AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc;

  if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM);

  FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut);

  FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut);

  FreeRam_aacEnc_AacEncoder(phAacEnc);
}

/* The following functions are in this source file only for convenience and */
/* need not be visible outside of a possible encoder library. */

/* basic defines for ancillary data */
#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */

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

    functionname:  FDKaacEnc_InitCheckAncillary
    description:   initialize and check ancillary data struct
    return:        if success or NULL if error

  ---------------------------------------------------------------------------*/
static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
    INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
    INT sampleRate) {
  /* don't use negative ancillary rates */
  if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE;

  /* check if ancillary rate is ok */
  if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) {
    /* ancRate <= 15% of bitrate && ancRate < 19200 */
    if ((ancillaryRate >= MAX_ANCRATE) ||
        ((ancillaryRate * 20) > (bitRate * 3))) {
      return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
    }
  } else if (ancillaryRate == -1) {
    /* if no special ancRate is requested but a ancillary file is
       stated, then generate a ancillary rate matching to the bitrate */
    if (bitRate >= (MAX_ANCRATE * 10)) {
      /* ancillary rate is 19199 */
      ancillaryRate = (MAX_ANCRATE - 1);
    } else { /* 10% of bitrate */
      ancillaryRate = bitRate / 10;
    }
  }

  /* make ancillaryBitsPerFrame byte align */
  *ancillaryBitsPerFrame =
      FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7;

  return AAC_ENC_OK;
}
