/* -----------------------------------------------------------------------------
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
----------------------------------------------------------------------------- */

/**************************** SBR decoder library ******************************

   Author(s):

   Description:

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

/*!
  \file
  \brief  envelope decoding
  This module provides envelope decoding and error concealment algorithms. The
  main entry point is decodeSbrData().

  \sa decodeSbrData(),\ref documentationOverview
*/

#include "env_dec.h"

#include "env_extr.h"
#include "transcendent.h"

#include "genericStds.h"

static void decodeEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
                           HANDLE_SBR_FRAME_DATA h_sbr_data,
                           HANDLE_SBR_PREV_FRAME_DATA h_prev_data,
                           HANDLE_SBR_PREV_FRAME_DATA h_prev_data_otherChannel);
static void sbr_envelope_unmapping(HANDLE_SBR_HEADER_DATA hHeaderData,
                                   HANDLE_SBR_FRAME_DATA h_data_left,
                                   HANDLE_SBR_FRAME_DATA h_data_right);
static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data,
                                   int ampResolution);
static void deltaToLinearPcmEnvelopeDecoding(
    HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_FRAME_DATA h_sbr_data,
    HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
static void decodeNoiseFloorlevels(HANDLE_SBR_HEADER_DATA hHeaderData,
                                   HANDLE_SBR_FRAME_DATA h_sbr_data,
                                   HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
static void timeCompensateFirstEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
                                        HANDLE_SBR_FRAME_DATA h_sbr_data,
                                        HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
static int checkEnvelopeData(HANDLE_SBR_HEADER_DATA hHeaderData,
                             HANDLE_SBR_FRAME_DATA h_sbr_data,
                             HANDLE_SBR_PREV_FRAME_DATA h_prev_data);

#define SBR_ENERGY_PAN_OFFSET (12 << ENV_EXP_FRACT)
#define SBR_MAX_ENERGY (35 << ENV_EXP_FRACT)

#define DECAY (1 << ENV_EXP_FRACT)

#if ENV_EXP_FRACT
#define DECAY_COUPLING \
  (1 << (ENV_EXP_FRACT - 1)) /*!< corresponds to a value of 0.5 */
#else
#define DECAY_COUPLING \
  1 /*!< If the energy data is not shifted, use 1 instead of 0.5 */
#endif

/*!
  \brief  Convert table index
*/
static int indexLow2High(int offset, /*!< mapping factor */
                         int index,  /*!< index to scalefactor band */
                         int res)    /*!< frequency resolution */
{
  if (res == 0) {
    if (offset >= 0) {
      if (index < offset)
        return (index);
      else
        return (2 * index - offset);
    } else {
      offset = -offset;
      if (index < offset)
        return (2 * index + index);
      else
        return (2 * index + offset);
    }
  } else
    return (index);
}

/*!
  \brief  Update previous envelope value for delta-coding

  The current envelope values needs to be stored for delta-coding
  in the next frame.  The stored envelope is always represented with
  the high frequency resolution.  If the current envelope uses the
  low frequency resolution, the energy value will be mapped to the
  corresponding high-res bands.
*/
static void mapLowResEnergyVal(
    FIXP_SGL currVal,   /*!< current energy value */
    FIXP_SGL *prevData, /*!< pointer to previous data vector */
    int offset,         /*!< mapping factor */
    int index,          /*!< index to scalefactor band */
    int res)            /*!< frequeny resolution */
{
  if (res == 0) {
    if (offset >= 0) {
      if (index < offset)
        prevData[index] = currVal;
      else {
        prevData[2 * index - offset] = currVal;
        prevData[2 * index + 1 - offset] = currVal;
      }
    } else {
      offset = -offset;
      if (index < offset) {
        prevData[3 * index] = currVal;
        prevData[3 * index + 1] = currVal;
        prevData[3 * index + 2] = currVal;
      } else {
        prevData[2 * index + offset] = currVal;
        prevData[2 * index + 1 + offset] = currVal;
      }
    }
  } else
    prevData[index] = currVal;
}

/*!
  \brief    Convert raw envelope and noisefloor data to energy levels

  This function is being called by sbrDecoder_ParseElement() and provides two
  important algorithms:

  First the function decodes envelopes and noise floor levels as described in
  requantizeEnvelopeData() and sbr_envelope_unmapping(). The function also
  implements concealment algorithms in case there are errors within the sbr
  data. For both operations fractional arithmetic is used. Therefore you might
  encounter different output values on your target system compared to the
  reference implementation.
*/
void decodeSbrData(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA
        h_data_left, /*!< pointer to left channel frame data */
    HANDLE_SBR_PREV_FRAME_DATA
        h_prev_data_left, /*!< pointer to left channel previous frame data */
    HANDLE_SBR_FRAME_DATA
        h_data_right, /*!< pointer to right channel frame data */
    HANDLE_SBR_PREV_FRAME_DATA
        h_prev_data_right) /*!< pointer to right channel previous frame data */
{
  FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
  int errLeft;

  /* Save previous energy values to be able to reuse them later for concealment.
   */
  FDKmemcpy(tempSfbNrgPrev, h_prev_data_left->sfb_nrg_prev,
            MAX_FREQ_COEFFS * sizeof(FIXP_SGL));

  if (hHeaderData->frameErrorFlag || hHeaderData->bs_info.pvc_mode == 0) {
    decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left,
                   h_prev_data_right);
  } else {
    FDK_ASSERT(h_data_right == NULL);
  }
  decodeNoiseFloorlevels(hHeaderData, h_data_left, h_prev_data_left);

  if (h_data_right != NULL) {
    errLeft = hHeaderData->frameErrorFlag;
    decodeEnvelope(hHeaderData, h_data_right, h_prev_data_right,
                   h_prev_data_left);
    decodeNoiseFloorlevels(hHeaderData, h_data_right, h_prev_data_right);

    if (!errLeft && hHeaderData->frameErrorFlag) {
      /* If an error occurs in the right channel where the left channel seemed
         ok, we apply concealment also on the left channel. This ensures that
         the coupling modes of both channels match and that we have the same
         number of envelopes in coupling mode. However, as the left channel has
         already been processed before, the resulting energy levels are not the
         same as if the left channel had been concealed during the first call of
         decodeEnvelope().
      */
      /* Restore previous energy values for concealment, because the values have
         been overwritten by the first call of decodeEnvelope(). */
      FDKmemcpy(h_prev_data_left->sfb_nrg_prev, tempSfbNrgPrev,
                MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
      /* Do concealment */
      decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left,
                     h_prev_data_right);
    }

    if (h_data_left->coupling) {
      sbr_envelope_unmapping(hHeaderData, h_data_left, h_data_right);
    }
  }

  /* Display the data for debugging: */
}

/*!
  \brief   Convert from coupled channels to independent L/R data
*/
static void sbr_envelope_unmapping(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_data_left,  /*!< pointer to left channel */
    HANDLE_SBR_FRAME_DATA h_data_right) /*!< pointer to right channel */
{
  int i;
  FIXP_SGL tempL_m, tempR_m, tempRplus1_m, newL_m, newR_m;
  SCHAR tempL_e, tempR_e, tempRplus1_e, newL_e, newR_e;

  /* 1. Unmap (already dequantized) coupled envelope energies */

  for (i = 0; i < h_data_left->nScaleFactors; i++) {
    tempR_m = (FIXP_SGL)((LONG)h_data_right->iEnvelope[i] & MASK_M);
    tempR_e = (SCHAR)((LONG)h_data_right->iEnvelope[i] & MASK_E);

    tempR_e -= (18 + NRG_EXP_OFFSET); /* -18 = ld(UNMAPPING_SCALE /
                                         h_data_right->nChannels) */
    tempL_m = (FIXP_SGL)((LONG)h_data_left->iEnvelope[i] & MASK_M);
    tempL_e = (SCHAR)((LONG)h_data_left->iEnvelope[i] & MASK_E);

    tempL_e -= NRG_EXP_OFFSET;

    /* Calculate tempRight+1 */
    FDK_add_MantExp(tempR_m, tempR_e, FL2FXCONST_SGL(0.5f), 1, /* 1.0 */
                    &tempRplus1_m, &tempRplus1_e);

    FDK_divide_MantExp(tempL_m, tempL_e + 1, /*  2 * tempLeft */
                       tempRplus1_m, tempRplus1_e, &newR_m, &newR_e);

    if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
      newR_m >>= 1;
      newR_e += 1;
    }

    newL_m = FX_DBL2FX_SGL(fMult(tempR_m, newR_m));
    newL_e = tempR_e + newR_e;

    h_data_right->iEnvelope[i] =
        ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) +
        (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NRG_EXP_OFFSET) & MASK_E);
    h_data_left->iEnvelope[i] =
        ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) +
        (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NRG_EXP_OFFSET) & MASK_E);
  }

  /* 2. Dequantize and unmap coupled noise floor levels */

  for (i = 0; i < hHeaderData->freqBandData.nNfb *
                      h_data_left->frameInfo.nNoiseEnvelopes;
       i++) {
    tempL_e = (SCHAR)(6 - (LONG)h_data_left->sbrNoiseFloorLevel[i]);
    tempR_e = (SCHAR)((LONG)h_data_right->sbrNoiseFloorLevel[i] -
                      12) /*SBR_ENERGY_PAN_OFFSET*/;

    /* Calculate tempR+1 */
    FDK_add_MantExp(FL2FXCONST_SGL(0.5f), 1 + tempR_e, /* tempR */
                    FL2FXCONST_SGL(0.5f), 1,           /*  1.0  */
                    &tempRplus1_m, &tempRplus1_e);

    /* Calculate 2*tempLeft/(tempR+1) */
    FDK_divide_MantExp(FL2FXCONST_SGL(0.5f), tempL_e + 2, /*  2 * tempLeft */
                       tempRplus1_m, tempRplus1_e, &newR_m, &newR_e);

    /* if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
      newR_m >>= 1;
      newR_e += 1;
    } */

    /* L = tempR * R */
    newL_m = newR_m;
    newL_e = newR_e + tempR_e;
    h_data_right->sbrNoiseFloorLevel[i] =
        ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) +
        (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NOISE_EXP_OFFSET) & MASK_E);
    h_data_left->sbrNoiseFloorLevel[i] =
        ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) +
        (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NOISE_EXP_OFFSET) & MASK_E);
  }
}

/*!
  \brief    Simple alternative to the real SBR concealment

  If the real frameInfo is not available due to a frame loss, a replacement will
  be constructed with 1 envelope spanning the whole frame (FIX-FIX).
  The delta-coded energies are set to negative values, resulting in a fade-down.
  In case of coupling, the balance-channel will move towards the center.
*/
static void leanSbrConcealment(
    HANDLE_SBR_HEADER_DATA hHeaderData,    /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_sbr_data,      /*!< pointer to current data */
    HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */
) {
  FIXP_SGL target; /* targeted level for sfb_nrg_prev during fade-down */
  FIXP_SGL step;   /* speed of fade */
  int i;

  int currentStartPos =
      fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots);
  int currentStopPos = hHeaderData->numberTimeSlots;

  /* Use some settings of the previous frame */
  h_sbr_data->ampResolutionCurrentFrame = h_prev_data->ampRes;
  h_sbr_data->coupling = h_prev_data->coupling;
  for (i = 0; i < MAX_INVF_BANDS; i++)
    h_sbr_data->sbr_invf_mode[i] = h_prev_data->sbr_invf_mode[i];

  /* Generate concealing control data */

  h_sbr_data->frameInfo.nEnvelopes = 1;
  h_sbr_data->frameInfo.borders[0] = currentStartPos;
  h_sbr_data->frameInfo.borders[1] = currentStopPos;
  h_sbr_data->frameInfo.freqRes[0] = 1;
  h_sbr_data->frameInfo.tranEnv = -1; /* no transient */
  h_sbr_data->frameInfo.nNoiseEnvelopes = 1;
  h_sbr_data->frameInfo.bordersNoise[0] = currentStartPos;
  h_sbr_data->frameInfo.bordersNoise[1] = currentStopPos;

  h_sbr_data->nScaleFactors = hHeaderData->freqBandData.nSfb[1];

  /* Generate fake envelope data */

  h_sbr_data->domain_vec[0] = 1;

  if (h_sbr_data->coupling == COUPLING_BAL) {
    target = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
    step = (FIXP_SGL)DECAY_COUPLING;
  } else {
    target = FL2FXCONST_SGL(0.0f);
    step = (FIXP_SGL)DECAY;
  }
  if (hHeaderData->bs_info.ampResolution == 0) {
    target <<= 1;
    step <<= 1;
  }

  for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
    if (h_prev_data->sfb_nrg_prev[i] > target)
      h_sbr_data->iEnvelope[i] = -step;
    else
      h_sbr_data->iEnvelope[i] = step;
  }

  /* Noisefloor levels are always cleared ... */

  h_sbr_data->domain_vec_noise[0] = 1;
  for (i = 0; i < hHeaderData->freqBandData.nNfb; i++)
    h_sbr_data->sbrNoiseFloorLevel[i] = FL2FXCONST_SGL(0.0f);

  /* ... and so are the sines */
  FDKmemclear(h_sbr_data->addHarmonics,
              sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE);
}

/*!
  \brief   Build reference energies and noise levels from bitstream elements
*/
static void decodeEnvelope(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_sbr_data,   /*!< pointer to current data */
    HANDLE_SBR_PREV_FRAME_DATA
        h_prev_data, /*!< pointer to data of last frame */
    HANDLE_SBR_PREV_FRAME_DATA
        otherChannel /*!< other channel's last frame data */
) {
  int i;
  int fFrameError = hHeaderData->frameErrorFlag;
  FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];

  if (!fFrameError) {
    /*
      To avoid distortions after bad frames, set the error flag if delta coding
      in time occurs. However, SBR can take a little longer to come up again.
    */
    if (h_prev_data->frameErrorFlag) {
      if (h_sbr_data->domain_vec[0] != 0) {
        fFrameError = 1;
      }
    } else {
      /* Check that the previous stop position and the current start position
         match. (Could be done in checkFrameInfo(), but the previous frame data
         is not available there) */
      if (h_sbr_data->frameInfo.borders[0] !=
          h_prev_data->stopPos - hHeaderData->numberTimeSlots) {
        /* Both the previous as well as the current frame are flagged to be ok,
         * but they do not match! */
        if (h_sbr_data->domain_vec[0] == 1) {
          /* Prefer concealment over delta-time coding between the mismatching
           * frames */
          fFrameError = 1;
        } else {
          /* Close the gap in time by triggering timeCompensateFirstEnvelope()
           */
          fFrameError = 1;
        }
      }
    }
  }

  if (fFrameError) /* Error is detected */
  {
    leanSbrConcealment(hHeaderData, h_sbr_data, h_prev_data);

    /* decode the envelope data to linear PCM */
    deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data);
  } else /*Do a temporary dummy decoding and check that the envelope values are
            within limits */
  {
    if (h_prev_data->frameErrorFlag) {
      timeCompensateFirstEnvelope(hHeaderData, h_sbr_data, h_prev_data);
      if (h_sbr_data->coupling != h_prev_data->coupling) {
        /*
          Coupling mode has changed during concealment.
           The stored energy levels need to be converted.
         */
        for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) {
          /* Former Level-Channel will be used for both channels */
          if (h_prev_data->coupling == COUPLING_BAL)
            h_prev_data->sfb_nrg_prev[i] = otherChannel->sfb_nrg_prev[i];
          /* Former L/R will be combined as the new Level-Channel */
          else if (h_sbr_data->coupling == COUPLING_LEVEL)
            h_prev_data->sfb_nrg_prev[i] = (h_prev_data->sfb_nrg_prev[i] +
                                            otherChannel->sfb_nrg_prev[i]) >>
                                           1;
          else if (h_sbr_data->coupling == COUPLING_BAL)
            h_prev_data->sfb_nrg_prev[i] = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
        }
      }
    }
    FDKmemcpy(tempSfbNrgPrev, h_prev_data->sfb_nrg_prev,
              MAX_FREQ_COEFFS * sizeof(FIXP_SGL));

    deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data);

    fFrameError = checkEnvelopeData(hHeaderData, h_sbr_data, h_prev_data);

    if (fFrameError) {
      hHeaderData->frameErrorFlag = 1;
      FDKmemcpy(h_prev_data->sfb_nrg_prev, tempSfbNrgPrev,
                MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
      decodeEnvelope(hHeaderData, h_sbr_data, h_prev_data, otherChannel);
      return;
    }
  }

  requantizeEnvelopeData(h_sbr_data, h_sbr_data->ampResolutionCurrentFrame);

  hHeaderData->frameErrorFlag = fFrameError;
}

/*!
  \brief   Verify that envelope energies are within the allowed range
  \return  0 if all is fine, 1 if an envelope value was too high
*/
static int checkEnvelopeData(
    HANDLE_SBR_HEADER_DATA hHeaderData,    /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_sbr_data,      /*!< pointer to current data */
    HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */
) {
  FIXP_SGL *iEnvelope = h_sbr_data->iEnvelope;
  FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev;
  int i = 0, errorFlag = 0;
  FIXP_SGL sbr_max_energy = (h_sbr_data->ampResolutionCurrentFrame == 1)
                                ? SBR_MAX_ENERGY
                                : (SBR_MAX_ENERGY << 1);

  /*
    Range check for current energies
  */
  for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
    if (iEnvelope[i] > sbr_max_energy) {
      errorFlag = 1;
    }
    if (iEnvelope[i] < FL2FXCONST_SGL(0.0f)) {
      errorFlag = 1;
      /* iEnvelope[i] = FL2FXCONST_SGL(0.0f); */
    }
  }

  /*
    Range check for previous energies
  */
  for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) {
    sfb_nrg_prev[i] = fixMax(sfb_nrg_prev[i], FL2FXCONST_SGL(0.0f));
    sfb_nrg_prev[i] = fixMin(sfb_nrg_prev[i], sbr_max_energy);
  }

  return (errorFlag);
}

/*!
  \brief   Verify that the noise levels are within the allowed range

  The function is equivalent to checkEnvelopeData().
  When the noise-levels are being decoded, it is already too late for
  concealment. Therefore the noise levels are simply limited here.
*/
static void limitNoiseLevels(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_sbr_data)   /*!< pointer to current data */
{
  int i;
  int nNfb = hHeaderData->freqBandData.nNfb;

/*
  Set range limits. The exact values depend on the coupling mode.
  However this limitation is primarily intended to avoid unlimited
  accumulation of the delta-coded noise levels.
*/
#define lowerLimit \
  ((FIXP_SGL)0) /* lowerLimit actually refers to the _highest_ noise energy */
#define upperLimit \
  ((FIXP_SGL)35) /* upperLimit actually refers to the _lowest_ noise energy */

  /*
    Range check for current noise levels
  */
  for (i = 0; i < h_sbr_data->frameInfo.nNoiseEnvelopes * nNfb; i++) {
    h_sbr_data->sbrNoiseFloorLevel[i] =
        fixMin(h_sbr_data->sbrNoiseFloorLevel[i], upperLimit);
    h_sbr_data->sbrNoiseFloorLevel[i] =
        fixMax(h_sbr_data->sbrNoiseFloorLevel[i], lowerLimit);
  }
}

/*!
  \brief   Compensate for the wrong timing that might occur after a frame error.
*/
static void timeCompensateFirstEnvelope(
    HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_sbr_data,   /*!< pointer to actual data */
    HANDLE_SBR_PREV_FRAME_DATA
        h_prev_data) /*!< pointer to data of last frame */
{
  int i, nScalefactors;
  FRAME_INFO *pFrameInfo = &h_sbr_data->frameInfo;
  UCHAR *nSfb = hHeaderData->freqBandData.nSfb;
  int estimatedStartPos =
      fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots);
  int refLen, newLen, shift;
  FIXP_SGL deltaExp;

  /* Original length of first envelope according to bitstream */
  refLen = pFrameInfo->borders[1] - pFrameInfo->borders[0];
  /* Corrected length of first envelope (concealing can make the first envelope
   * longer) */
  newLen = pFrameInfo->borders[1] - estimatedStartPos;

  if (newLen <= 0) {
    /* An envelope length of <= 0 would not work, so we don't use it.
       May occur if the previous frame was flagged bad due to a mismatch
       of the old and new frame infos. */
    newLen = refLen;
    estimatedStartPos = pFrameInfo->borders[0];
  }

  deltaExp = FDK_getNumOctavesDiv8(newLen, refLen);

  /* Shift by -3 to rescale ld-table, ampRes-1 to enable coarser steps */
  shift = (FRACT_BITS - 1 - ENV_EXP_FRACT - 1 +
           h_sbr_data->ampResolutionCurrentFrame - 3);
  deltaExp = deltaExp >> shift;
  pFrameInfo->borders[0] = estimatedStartPos;
  pFrameInfo->bordersNoise[0] = estimatedStartPos;

  if (h_sbr_data->coupling != COUPLING_BAL) {
    nScalefactors = (pFrameInfo->freqRes[0]) ? nSfb[1] : nSfb[0];

    for (i = 0; i < nScalefactors; i++)
      h_sbr_data->iEnvelope[i] = h_sbr_data->iEnvelope[i] + deltaExp;
  }
}

/*!
  \brief   Convert each envelope value from logarithmic to linear domain

  Energy levels are transmitted in powers of 2, i.e. only the exponent
  is extracted from the bitstream.
  Therefore, normally only integer exponents can occur. However during
  fading (in case of a corrupt bitstream), a fractional part can also
  occur. The data in the array iEnvelope is shifted left by ENV_EXP_FRACT
  compared to an integer representation so that numbers smaller than 1
  can be represented.

  This function calculates a mantissa corresponding to the fractional
  part of the exponent for each reference energy. The array iEnvelope
  is converted in place to save memory. Input and output data must
  be interpreted differently, as shown in the below figure:

  \image html  EnvelopeData.png

  The data is then used in calculateSbrEnvelope().
*/
static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data,
                                   int ampResolution) {
  int i;
  FIXP_SGL mantissa;
  int ampShift = 1 - ampResolution;
  int exponent;

  /* In case that ENV_EXP_FRACT is changed to something else but 0 or 8,
     the initialization of this array has to be adapted!
  */
#if ENV_EXP_FRACT
  static const FIXP_SGL pow2[ENV_EXP_FRACT] = {
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 1))), /* 0.7071 */
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 2))), /* 0.5946 */
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 3))),
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 4))),
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 5))),
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 6))),
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 7))),
      FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 8))) /* 0.5013 */
  };

  int bit, mask;
#endif

  for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
    exponent = (LONG)h_sbr_data->iEnvelope[i];

#if ENV_EXP_FRACT

    exponent = exponent >> ampShift;
    mantissa = 0.5f;

    /* Amplify mantissa according to the fractional part of the
       exponent (result will be between 0.500000 and 0.999999)
    */
    mask = 1; /* begin with lowest bit of exponent */

    for (bit = ENV_EXP_FRACT - 1; bit >= 0; bit--) {
      if (exponent & mask) {
        /* The current bit of the exponent is set,
           multiply mantissa with the corresponding factor: */
        mantissa = (FIXP_SGL)((mantissa * pow2[bit]) << 1);
      }
      /* Advance to next bit */
      mask = mask << 1;
    }

    /* Make integer part of exponent right aligned */
    exponent = exponent >> ENV_EXP_FRACT;

#else
    /* In case of the high amplitude resolution, 1 bit of the exponent gets lost
       by the shift. This will be compensated by a mantissa of 0.5*sqrt(2)
       instead of 0.5 if that bit is 1. */
    mantissa = (exponent & ampShift) ? FL2FXCONST_SGL(0.707106781186548f)
                                     : FL2FXCONST_SGL(0.5f);
    exponent = exponent >> ampShift;
#endif

    /*
      Mantissa was set to 0.5 (instead of 1.0, therefore increase exponent by
      1). Multiply by L=nChannels=64 by increasing exponent by another 6.
      => Increase exponent by 7
    */
    exponent += 7 + NRG_EXP_OFFSET;

    /* Combine mantissa and exponent and write back the result */
    h_sbr_data->iEnvelope[i] =
        ((FIXP_SGL)((SHORT)(FIXP_SGL)mantissa & MASK_M)) +
        (FIXP_SGL)((SHORT)(FIXP_SGL)exponent & MASK_E);
  }
}

/*!
  \brief   Build new reference energies from old ones and delta coded data
*/
static void deltaToLinearPcmEnvelopeDecoding(
    HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_sbr_data,       /*!< pointer to current data */
    HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */
{
  int i, domain, no_of_bands, band, freqRes;

  FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev;
  FIXP_SGL *ptr_nrg = h_sbr_data->iEnvelope;

  int offset =
      2 * hHeaderData->freqBandData.nSfb[0] - hHeaderData->freqBandData.nSfb[1];

  for (i = 0; i < h_sbr_data->frameInfo.nEnvelopes; i++) {
    domain = h_sbr_data->domain_vec[i];
    freqRes = h_sbr_data->frameInfo.freqRes[i];

    FDK_ASSERT(freqRes >= 0 && freqRes <= 1);

    no_of_bands = hHeaderData->freqBandData.nSfb[freqRes];

    FDK_ASSERT(no_of_bands < (64));

    if (domain == 0) {
      mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, 0, freqRes);
      ptr_nrg++;
      for (band = 1; band < no_of_bands; band++) {
        *ptr_nrg = *ptr_nrg + *(ptr_nrg - 1);
        mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
        ptr_nrg++;
      }
    } else {
      for (band = 0; band < no_of_bands; band++) {
        *ptr_nrg =
            *ptr_nrg + sfb_nrg_prev[indexLow2High(offset, band, freqRes)];
        mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
        ptr_nrg++;
      }
    }
  }
}

/*!
  \brief   Build new noise levels from old ones and delta coded data
*/
static void decodeNoiseFloorlevels(
    HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
    HANDLE_SBR_FRAME_DATA h_sbr_data,       /*!< pointer to current data */
    HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */
{
  int i;
  int nNfb = hHeaderData->freqBandData.nNfb;
  int nNoiseFloorEnvelopes = h_sbr_data->frameInfo.nNoiseEnvelopes;

  /* Decode first noise envelope */

  if (h_sbr_data->domain_vec_noise[0] == 0) {
    FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[0];
    for (i = 1; i < nNfb; i++) {
      noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i];
      h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel;
    }
  } else {
    for (i = 0; i < nNfb; i++) {
      h_sbr_data->sbrNoiseFloorLevel[i] += h_prev_data->prevNoiseLevel[i];
    }
  }

  /* If present, decode the second noise envelope
     Note:  nNoiseFloorEnvelopes can only be 1 or 2 */

  if (nNoiseFloorEnvelopes > 1) {
    if (h_sbr_data->domain_vec_noise[1] == 0) {
      FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[nNfb];
      for (i = nNfb + 1; i < 2 * nNfb; i++) {
        noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i];
        h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel;
      }
    } else {
      for (i = 0; i < nNfb; i++) {
        h_sbr_data->sbrNoiseFloorLevel[i + nNfb] +=
            h_sbr_data->sbrNoiseFloorLevel[i];
      }
    }
  }

  limitNoiseLevels(hHeaderData, h_sbr_data);

  /* Update prevNoiseLevel with the last noise envelope */
  for (i = 0; i < nNfb; i++)
    h_prev_data->prevNoiseLevel[i] =
        h_sbr_data->sbrNoiseFloorLevel[i + nNfb * (nNoiseFloorEnvelopes - 1)];

  /* Requantize the noise floor levels in COUPLING_OFF-mode */
  if (!h_sbr_data->coupling) {
    int nf_e;

    for (i = 0; i < nNoiseFloorEnvelopes * nNfb; i++) {
      nf_e = 6 - (LONG)h_sbr_data->sbrNoiseFloorLevel[i] + 1 + NOISE_EXP_OFFSET;
      /* +1 to compensate for a mantissa of 0.5 instead of 1.0 */

      h_sbr_data->sbrNoiseFloorLevel[i] =
          (FIXP_SGL)(((LONG)FL2FXCONST_SGL(0.5f)) + /* mantissa */
                     (nf_e & MASK_E));              /* exponent */
    }
  }
}
