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

   Author(s):   Manuel Jander

   Description: USAC Linear Prediction Domain coding

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

#include "usacdec_lpd.h"

#include "usacdec_rom.h"
#include "usacdec_fac.h"
#include "usacdec_lpc.h"
#include "FDK_tools_rom.h"
#include "fft.h"
#include "mdct.h"
#include "usacdec_acelp.h"
#include "overlapadd.h"

#include "conceal.h"

#include "block.h"

#define SF_PITCH_TRACK 6
#define SF_GAIN 3
#define MIN_VAL FL2FXCONST_DBL(0.0f)
#define MAX_VAL (FIXP_DBL) MAXVAL_DBL

#include "ac_arith_coder.h"

void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
            const FIXP_SGL *filt, INT stop, int len) {
  INT i, j;
  FIXP_DBL tmp;

  for (i = 0; i < stop; i++) {
    tmp = fMultDiv2(noise[i], filt[0]);  // Filt in Q-1.16
    for (j = 1; j <= len; j++) {
      tmp += fMultDiv2((noise[i - j] + noise[i + j]), filt[j]);
    }
    syn_out[i] = (FIXP_PCM)(IMDCT_SCALE(syn[i] - tmp));
  }
}

void bass_pf_1sf_delay(
    FIXP_DBL *syn,   /* (i) : 12.8kHz synthesis to postfilter              */
    const INT *T_sf, /* (i) : Pitch period for all subframes (T_sf[16])    */
    FIXP_DBL *pit_gain,
    const int frame_length, /* (i) : frame length (should be 768|1024) */
    const INT l_frame,
    const INT l_next, /* (i) : look ahead for symmetric filtering           */
    FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
    FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR]                */
{
  INT i, sf, i_subfr, T, T2, lg;

  FIXP_DBL tmp, ener, corr, gain;
  FIXP_DBL *noise, *noise_in;
  FIXP_DBL
  noise_buf[L_FILT + (2 * L_SUBFR)];  // L_FILT = 12, L_SUBFR = 64 => 140
  const FIXP_DBL *x, *y;

  {
    noise = noise_buf + L_FILT;  // L_FILT = 12 delay of upsampling filter
    noise_in = noise_buf + L_FILT + L_SUBFR;
    /* Input scaling of the BPF memory */
    scaleValues(mem_bpf, (L_FILT + L_SUBFR), 1);
  }

  int gain_exp = 17;

  sf = 0;
  for (i_subfr = 0; i_subfr < l_frame; i_subfr += L_SUBFR, sf++) {
    T = T_sf[sf];
    gain = pit_gain[sf];

    /* Gain is in Q17.14 */
    /* If gain > 1 set to 1 */
    if (gain > (FIXP_DBL)(1 << 14)) gain = (FIXP_DBL)(1 << 14);

    /* If gain < 0 set to 0 */
    if (gain < (FIXP_DBL)0) gain = (FIXP_DBL)0;

    if (gain > (FIXP_DBL)0) {
      /* pitch tracker: test pitch/2 to avoid continuous pitch doubling */
      /* Note: pitch is limited to PIT_MIN (34 = 376Hz) at the encoder  */
      T2 = T >> 1;
      x = &syn[i_subfr - L_EXTRA];
      y = &syn[i_subfr - T2 - L_EXTRA];

      ener = (FIXP_DBL)0;
      corr = (FIXP_DBL)0;
      tmp = (FIXP_DBL)0;

      int headroom_x = getScalefactor(x, L_SUBFR + L_EXTRA);
      int headroom_y = getScalefactor(y, L_SUBFR + L_EXTRA);

      int width_shift = 7;

      for (i = 0; i < (L_SUBFR + L_EXTRA); i++) {
        ener += fPow2Div2((x[i] << headroom_x)) >> width_shift;
        corr += fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >>
                width_shift;
        tmp += fPow2Div2((y[i] << headroom_y)) >> width_shift;
      }

      int exp_ener = ((17 - headroom_x) << 1) + width_shift + 1;
      int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
      int exp_tmp = ((17 - headroom_y) << 1) + width_shift + 1;

      /* Add 0.01 to "ener". Adjust exponents */
      FIXP_DBL point_zero_one = (FIXP_DBL)0x51eb851f; /* In Q-6.37 */
      int diff;
      ener = fAddNorm(ener, exp_ener, point_zero_one, -6, &exp_ener);
      corr = fAddNorm(corr, exp_corr, point_zero_one, -6, &exp_corr);
      tmp = fAddNorm(tmp, exp_tmp, point_zero_one, -6, &exp_tmp);

      /* use T2 if normalized correlation > 0.95 */
      INT s1, s2;
      s1 = CntLeadingZeros(ener) - 1;
      s2 = CntLeadingZeros(tmp) - 1;

      FIXP_DBL ener_by_tmp = fMultDiv2(ener << s1, tmp << s2);
      int ener_by_tmp_exp = (exp_ener - s1) + (exp_tmp - s2) + 1;

      if (ener_by_tmp_exp & 1) {
        ener_by_tmp <<= 1;
        ener_by_tmp_exp -= 1;
      }

      int temp_exp = 0;

      FIXP_DBL temp1 = invSqrtNorm2(ener_by_tmp, &temp_exp);

      int temp1_exp = temp_exp - (ener_by_tmp_exp >> 1);

      FIXP_DBL tmp_result = fMult(corr, temp1);

      int tmp_result_exp = exp_corr + temp1_exp;

      diff = tmp_result_exp - 0;
      FIXP_DBL point95 = FL2FXCONST_DBL(0.95f);
      if (diff >= 0) {
        diff = fMin(diff, 31);
        point95 = FL2FXCONST_DBL(0.95f) >> diff;
      } else {
        diff = fMax(diff, -31);
        tmp_result >>= (-diff);
      }

      if (tmp_result > point95) T = T2;

      /* prevent that noise calculation below reaches into not defined signal
         parts at the end of the synth_buf or in other words restrict the below
         used index (i+i_subfr+T) < l_frame + l_next
      */
      lg = l_frame + l_next - T - i_subfr;

      if (lg > L_SUBFR)
        lg = L_SUBFR;
      else if (lg < 0)
        lg = 0;

      /* limit gain to avoid problem on burst */
      if (lg > 0) {
        FIXP_DBL tmp1;

        /* max(lg) = 64 => scale with 6 bits minus 1 (fPow2Div2) */

        s1 = getScalefactor(&syn[i_subfr], lg);
        s2 = getScalefactor(&syn[i_subfr + T], lg);
        INT s = fixMin(s1, s2);

        tmp = (FIXP_DBL)0;
        ener = (FIXP_DBL)0;
        for (i = 0; i < lg; i++) {
          tmp += fPow2Div2(syn[i + i_subfr] << s1) >> (SF_PITCH_TRACK);
          ener += fPow2Div2(syn[i + i_subfr + T] << s2) >> (SF_PITCH_TRACK);
        }
        tmp = tmp >> fMin(DFRACT_BITS - 1, (2 * (s1 - s)));
        ener = ener >> fMin(DFRACT_BITS - 1, (2 * (s2 - s)));

        /* error robustness: for the specific case syn[...] == -1.0f for all 64
           samples ener or tmp might overflow and become negative. For all sane
           cases we have enough headroom.
        */
        if (ener <= (FIXP_DBL)0) {
          ener = (FIXP_DBL)1;
        }
        if (tmp <= (FIXP_DBL)0) {
          tmp = (FIXP_DBL)1;
        }
        FDK_ASSERT(ener > (FIXP_DBL)0);

        /* tmp = sqrt(tmp/ener) */
        int result_e = 0;
        tmp1 = fDivNorm(tmp, ener, &result_e);
        if (result_e & 1) {
          tmp1 >>= 1;
          result_e += 1;
        }
        tmp = sqrtFixp(tmp1);
        result_e >>= 1;

        gain_exp = 17;

        diff = result_e - gain_exp;

        FIXP_DBL gain1 = gain;

        if (diff >= 0) {
          diff = fMin(diff, 31);
          gain1 >>= diff;
        } else {
          result_e += (-diff);
          diff = fMax(diff, -31);
          tmp >>= (-diff);
        }

        if (tmp < gain1) {
          gain = tmp;
          gain_exp = result_e;
        }
      }

      /* calculate noise based on voiced pitch */
      /* fMultDiv2() replaces weighting of gain with 0.5 */
      diff = gain_exp - 17;
      if (diff >= 0) {
        gain <<= diff;
      } else {
        gain >>= (-diff);
      }

      s1 = CntLeadingZeros(gain) - 1;
      s1 -= 16; /* Leading bits for SGL */

      FIXP_SGL gainSGL = FX_DBL2FX_SGL(gain << 16);

      gainSGL = gainSGL << s1;

      {
        for (i = 0; i < lg; i++) {
          /* scaled with SF_SYNTH + gain_sf + 1 */
          noise_in[i] =
              (fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) -
                                  (syn[i + i_subfr + T] >> 1))) >>
              s1;
        }

        for (i = lg; i < L_SUBFR; i++) {
          /* scaled with SF_SYNTH + gain_sf + 1 */
          noise_in[i] =
              (fMult(gainSGL, syn[i + i_subfr] - syn[i + i_subfr - T])) >> s1;
        }
      }
    } else {
      FDKmemset(noise_in, (FIXP_DBL)0, L_SUBFR * sizeof(FIXP_DBL));
    }

    {
      FDKmemcpy(noise_buf, mem_bpf, (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));

      FDKmemcpy(mem_bpf, noise_buf + L_SUBFR,
                (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));
    }

    /* substract from voiced speech low-pass filtered noise */
    /* filter coefficients are scaled with factor SF_FILT_LP (1) */

    {
      filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise,
             fdk_dec_filt_lp, L_SUBFR, L_FILT);
    }
  }

  {

  }

  // To be determined (info from Ben)
  {
    /* Output scaling of the BPF memory */
    scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
    /* Copy the rest of the signal (after the fac) */
    scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame],
                        (FIXP_DBL *)&syn[l_frame - L_SUBFR],
                        (frame_length - l_frame), MDCT_OUT_HEADROOM);
  }

  return;
}

/*
 * Frequency Domain Noise Shaping
 */

/**
 * \brief Adaptive Low Frequencies Deemphasis of spectral coefficients.
 *
 * Ensure quantization of low frequencies in case where the
 * signal dynamic is higher than the LPC noise shaping.
 * This is the inverse operation of adap_low_freq_emph().
 * Output gain of all blocks.
 *
 * \param x pointer to the spectral coefficients, requires 1 bit headroom.
 * \param lg length of x.
 * \param bUseNewAlfe if set, apply ALFD for fullband lpd.
 * \param gainLpc1 pointer to gain based on old input LPC coefficients.
 * \param gainLpc2 pointer to gain based on new input LPC coefficients.
 * \param alfd_gains pointer to output gains.
 * \param s current scale shift factor of x.
 */
#define ALFDPOW2_SCALE 3
/*static*/
void CLpd_AdaptLowFreqDeemph(FIXP_DBL x[], int lg, FIXP_DBL alfd_gains[],
                             INT s) {
  {
    int i, j, k, i_max;
    FIXP_DBL max, fac;
    /* Note: This stack array saves temporary accumulation results to be used in
     * a second run */
    /*       The size should be limited to (1024/4)/8=32 */
    FIXP_DBL tmp_pow2[32];

    s = s * 2 + ALFDPOW2_SCALE;
    s = fMin(31, s);

    k = 8;
    i_max = lg / 4; /* ALFD range = 1600Hz (lg = 6400Hz) */

    /* find spectral peak */
    max = FL2FX_DBL(0.01f) >> s;
    for (i = 0; i < i_max; i += k) {
      FIXP_DBL tmp;

      tmp = FIXP_DBL(0);
      FIXP_DBL *pX = &x[i];

      j = 8;
      do {
        FIXP_DBL x0 = *pX++;
        FIXP_DBL x1 = *pX++;
        x0 = fPow2Div2(x0);
        x1 = fPow2Div2(x1);
        tmp = tmp + (x0 >> (ALFDPOW2_SCALE - 1));
        tmp = tmp + (x1 >> (ALFDPOW2_SCALE - 1));
      } while ((j = j - 2) != 0);
      tmp = fMax(tmp, (FL2FX_DBL(0.01f) >> s));
      tmp_pow2[i >> 3] = tmp;
      if (tmp > max) {
        max = tmp;
      }
    }

    /* deemphasis of all blocks below the peak */
    fac = FL2FX_DBL(0.1f) >> 1;
    for (i = 0; i < i_max; i += k) {
      FIXP_DBL tmp;
      INT shifti;

      tmp = tmp_pow2[i >> 3];

      /* tmp = (float)sqrt(tmp/max); */

      /* value of tmp is between 8/2*max^2 and max^2 / 2. */
      /* required shift factor of division can grow up to 27
         (grows exponentially for values toward zero)
         thus using normalized division to assure valid result. */
      {
        INT sd;

        if (tmp != (FIXP_DBL)0) {
          tmp = fDivNorm(max, tmp, &sd);
          if (sd & 1) {
            sd++;
            tmp >>= 1;
          }
        } else {
          tmp = (FIXP_DBL)MAXVAL_DBL;
          sd = 0;
        }
        tmp = invSqrtNorm2(tmp, &shifti);
        tmp = scaleValue(tmp, shifti - 1 - (sd / 2));
      }
      if (tmp > fac) {
        fac = tmp;
      }
      FIXP_DBL *pX = &x[i];

      j = 8;
      do {
        FIXP_DBL x0 = pX[0];
        FIXP_DBL x1 = pX[1];
        x0 = fMultDiv2(x0, fac);
        x1 = fMultDiv2(x1, fac);
        x0 = x0 << 2;
        x1 = x1 << 2;
        *pX++ = x0;
        *pX++ = x1;

      } while ((j = j - 2) != 0);
      /* Store gains for FAC */
      *alfd_gains++ = fac;
    }
  }
}

/**
 * \brief Interpolated Noise Shaping for mdct coefficients.
 * This algorithm shapes temporally the spectral noise between
 * the two spectral noise represention (FDNS_NPTS of resolution).
 * The noise is shaped monotonically between the two points
 * using a curved shape to favor the lower gain in mid-frame.
 * ODFT and amplitud calculation are applied to the 2 LPC coefficients first.
 *
 * \param r pointer to spectrum data.
 * \param rms RMS of output spectrum.
 * \param lg length of r.
 * \param A1 pointer to old input LPC coefficients of length M_LP_FILTER_ORDER
 * scaled by SF_A_COEFFS.
 * \param A2 pointer to new input LPC coefficients of length M_LP_FILTER_ORDER
 * scaled by SF_A_COEFFS.
 * \param bLpc2Mdct flags control lpc2mdct conversion and noise shaping.
 * \param gainLpc1 pointer to gain based on old input LPC coefficients.
 * \param gainLpc2 pointer to gain based on new input LPC coefficients.
 * \param gLpc_e pointer to exponent of gainLpc1 and gainLpc2.
 */
/* static */
#define NSHAPE_SCALE (4)

#define LPC2MDCT_CALC (1)
#define LPC2MDCT_GAIN_LOAD (2)
#define LPC2MDCT_GAIN_SAVE (4)
#define LPC2MDCT_APPLY_NSHAPE (8)

void lpc2mdctAndNoiseShaping(FIXP_DBL *r, SHORT *pScale, const INT lg,
                             const INT fdns_npts, const FIXP_LPC *A1,
                             const INT A1_exp, const FIXP_LPC *A2,
                             const INT A2_exp) {
  FIXP_DBL *tmp2 = NULL;
  FIXP_DBL rr_minus_one;
  int i, k, s, step;

  C_AALLOC_SCRATCH_START(tmp1, FIXP_DBL, FDNS_NPTS * 8)

  {
    tmp2 = tmp1 + fdns_npts * 4;

    /* lpc2mdct() */

    /* ODFT. E_LPC_a_weight() for A1 and A2 vectors is included into the loop
     * below. */
    FIXP_DBL f = FL2FXCONST_DBL(0.92f);

    const FIXP_STP *SinTab;
    int k_step;
    /* needed values: sin(phi), cos(phi); phi = i*PI/(2*fdns_npts), i = 0 ...
     * M_LP_FILTER_ORDER */
    switch (fdns_npts) {
      case 64:
        SinTab = SineTable512;
        k_step = (512 / 64);
        FDK_ASSERT(512 >= 64);
        break;
      case 48:
        SinTab = SineTable384;
        k_step = 384 / 48;
        FDK_ASSERT(384 >= 48);
        break;
      default:
        FDK_ASSERT(0);
        return;
    }

    for (i = 0, k = k_step; i < M_LP_FILTER_ORDER; i++, k += k_step) {
      FIXP_STP cs = SinTab[k];
      FIXP_DBL wA1, wA2;

      wA1 = fMult(A1[i], f);
      wA2 = fMult(A2[i], f);

      /* r[i] = A[i]*cos() */
      tmp1[2 + i * 2] = fMult(wA1, cs.v.re);
      tmp2[2 + i * 2] = fMult(wA2, cs.v.re);
      /* i[i] = A[i]*sin() */
      tmp1[3 + i * 2] = -fMult(wA1, cs.v.im);
      tmp2[3 + i * 2] = -fMult(wA2, cs.v.im);

      f = fMult(f, FL2FXCONST_DBL(0.92f));
    }

    /* Guarantee at least 2 bits of headroom for the FFT */
    /* "3" stands for 1.0 with 2 bits of headroom; (A1_exp + 2) guarantess 2
     * bits of headroom if A1_exp > 1 */
    int A1_exp_fix = fMax(3, A1_exp + 2);
    int A2_exp_fix = fMax(3, A2_exp + 2);

    /* Set 1.0 in the proper format */
    tmp1[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A1_exp_fix);
    tmp2[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A2_exp_fix);

    tmp1[1] = tmp2[1] = (FIXP_DBL)0;

    /* Clear the resto of the array */
    FDKmemclear(
        tmp1 + 2 * (M_LP_FILTER_ORDER + 1),
        2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
    FDKmemclear(
        tmp2 + 2 * (M_LP_FILTER_ORDER + 1),
        2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));

    /* Guarantee 2 bits of headroom for FFT */
    scaleValues(&tmp1[2], (2 * M_LP_FILTER_ORDER), (A1_exp - A1_exp_fix));
    scaleValues(&tmp2[2], (2 * M_LP_FILTER_ORDER), (A2_exp - A2_exp_fix));

    INT s2;
    s = A1_exp_fix;
    s2 = A2_exp_fix;

    fft(2 * fdns_npts, tmp1, &s);
    fft(2 * fdns_npts, tmp2, &s2);

    /* Adjust the exponents of both fft outputs if necessary*/
    if (s > s2) {
      scaleValues(tmp2, 2 * fdns_npts, s2 - s);
      s2 = s;
    } else if (s < s2) {
      scaleValues(tmp1, 2 * fdns_npts, s - s2);
      s = s2;
    }

    FDK_ASSERT(s == s2);
  }

  /* Get amplitude and apply gains */
  step = lg / fdns_npts;
  rr_minus_one = (FIXP_DBL)0;

  for (k = 0; k < fdns_npts; k++) {
    FIXP_DBL g1, g2, inv_g1_g2, a, b;
    INT inv_g1_g2_e;
    int g_e, shift;

    {
      FIXP_DBL real, imag;
      int si1, si2, sInput;

      real = tmp1[k * 2];
      imag = tmp1[k * 2 + 1];
      sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
      real <<= sInput;
      imag <<= sInput;
      /* g1_e = si1 - 2*s/2 */
      g1 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si1);
      si1 += sInput;

      real = tmp2[k * 2];
      imag = tmp2[k * 2 + 1];
      sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
      real <<= sInput;
      imag <<= sInput;
      /* g2_e = si2 - 2*s/2 */
      g2 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si2);
      si2 += sInput;

      /* Pick a common scale factor for g1 and g2 */
      if (si1 > si2) {
        g2 >>= si1 - si2;
        g_e = si1 - s;
      } else {
        g1 >>= si2 - si1;
        g_e = si2 - s;
      }
    }

    /* end of lpc2mdct() */

    FDK_ASSERT(g1 >= (FIXP_DBL)0);
    FDK_ASSERT(g2 >= (FIXP_DBL)0);

    /* mdct_IntNoiseShaping() */
    {
      /* inv_g1_g2 * 2^inv_g1_g2_e = 1/(g1+g2) */
      inv_g1_g2 = (g1 >> 1) + (g2 >> 1);
      if (inv_g1_g2 != (FIXP_DBL)0) {
        inv_g1_g2 = fDivNorm(FL2FXCONST_DBL(0.5f), inv_g1_g2, &inv_g1_g2_e);
        inv_g1_g2_e = inv_g1_g2_e - g_e;
      } else {
        inv_g1_g2 = (FIXP_DBL)MAXVAL_DBL;
        inv_g1_g2_e = 0;
      }

      if (g_e < 0) {
        /* a_e = g_e + inv_g1_g2_e + 1 */
        a = scaleValue(fMult(fMult(g1, g2), inv_g1_g2), g_e);
        /* b_e = g_e + inv_g1_g2_e */
        b = fMult(g2 - g1, inv_g1_g2);
        shift = g_e + inv_g1_g2_e + 1 - NSHAPE_SCALE;
      } else {
        /* a_e = (g_e+g_e) + inv_g1_g2_e + 1 */
        a = fMult(fMult(g1, g2), inv_g1_g2);
        /* b_e = (g_e+g_e) + inv_g1_g2_e */
        b = scaleValue(fMult(g2 - g1, inv_g1_g2), -g_e);
        shift = (g_e + g_e) + inv_g1_g2_e + 1 - NSHAPE_SCALE;
      }

      for (i = k * step; i < (k + 1) * step; i++) {
        FIXP_DBL tmp;

        /* rr[i] = 2*a*r[i] + b*rr[i-1] */
        tmp = fMult(a, r[i]);
        tmp += scaleValue(fMultDiv2(b, rr_minus_one), NSHAPE_SCALE);
        tmp = scaleValueSaturate(tmp, shift);
        rr_minus_one = tmp;
        r[i] = tmp;
      }
    }
  }

  /* end of mdct_IntNoiseShaping() */
  { *pScale += NSHAPE_SCALE; }

  C_AALLOC_SCRATCH_END(tmp1, FIXP_DBL, FDNS_NPTS * 8)
}

/**
 * \brief Calculates the energy.
 * \param r pointer to spectrum.
 * \param rs scale factor of spectrum r.
 * \param lg frame length in audio samples.
 * \param rms_e pointer to exponent of energy value.
 * \return mantissa of energy value.
 */
static FIXP_DBL calcEnergy(const FIXP_DBL *r, const SHORT rs, const INT lg,
                           INT *rms_e) {
  int headroom = getScalefactor(r, lg);

  FIXP_DBL rms_m = 0;

  /* Calculate number of growth bits due to addition */
  INT shift = (INT)(fNormz((FIXP_DBL)lg));
  shift = 31 - shift;

  /* Generate 1e-2 in Q-6.37 */
  const FIXP_DBL value0_01 = 0x51eb851e;
  const INT value0_01_exp = -6;

  /* Find the exponent of the resulting energy value */
  *rms_e = ((rs - headroom) << 1) + shift + 1;

  INT delta = *rms_e - value0_01_exp;
  if (delta > 0) {
    /* Limit shift_to 31*/
    delta = fMin(31, delta);
    rms_m = value0_01 >> delta;
  } else {
    rms_m = value0_01;
    *rms_e = value0_01_exp;
    shift = shift - delta;
    /* Limit shift_to 31*/
    shift = fMin(31, shift);
  }

  for (int i = 0; i < lg; i++) {
    rms_m += fPow2Div2(r[i] << headroom) >> shift;
  }

  return rms_m;
}

/**
 * \brief TCX gain calculation.
 * \param pAacDecoderChannelInfo channel context data.
 * \param r output spectrum.
 * \param rms_e pointer to mantissa of energy value.
 * \param rms_e pointer to exponent of energy value.
 * \param frame the frame index of the LPD super frame.
 * \param lg the frame length in audio samples.
 * \param gain_m pointer to mantissa of TCX gain.
 * \param gain_e pointer to exponent of TCX gain.
 * \param elFlags element specific parser guidance flags.
 * \param lg_fb the fullband frame length in audio samples.
 * \param IGF_bgn the IGF start index.
 */
static void calcTCXGain(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
                        FIXP_DBL *r, FIXP_DBL rms_m, INT rms_e, const INT frame,
                        const INT lg) {
  if ((rms_m != (FIXP_DBL)0)) {
    FIXP_DBL tcx_gain_m;
    INT tcx_gain_e;

    CLpd_DecodeGain(&tcx_gain_m, &tcx_gain_e,
                    pAacDecoderChannelInfo->pDynData->specificTo.usac
                        .tcx_global_gain[frame]);

    /* rms * 2^rms_e = lg/sqrt(sum(spec^2)) */
    if (rms_e & 1) {
      rms_m >>= 1;
      rms_e++;
    }

    {
      FIXP_DBL fx_lg;
      INT fx_lg_e, s;
      INT inv_e;

      /* lg = fx_lg * 2^fx_lg_e */
      s = fNorm((FIXP_DBL)lg);
      fx_lg = (FIXP_DBL)lg << s;
      fx_lg_e = DFRACT_BITS - 1 - s;
      /* 1/sqrt(rms) */
      rms_m = invSqrtNorm2(rms_m, &inv_e);
      rms_m = fMult(rms_m, fx_lg);
      rms_e = inv_e - (rms_e >> 1) + fx_lg_e;
    }

    {
      int s = fNorm(tcx_gain_m);
      tcx_gain_m = tcx_gain_m << s;
      tcx_gain_e -= s;
    }

    tcx_gain_m = fMultDiv2(tcx_gain_m, rms_m);
    tcx_gain_e = tcx_gain_e + rms_e;

    /* global_gain * 2^(global_gain_e+rms_e) = (10^(global_gain/28)) * rms *
     * 2^rms_e */
    {
      { tcx_gain_e += 1; }
    }

    pAacDecoderChannelInfo->data.usac.tcx_gain[frame] = tcx_gain_m;
    pAacDecoderChannelInfo->data.usac.tcx_gain_e[frame] = tcx_gain_e;

    pAacDecoderChannelInfo->specScale[frame] += tcx_gain_e;
  }
}

/**
 * \brief FDNS decoding.
 * \param pAacDecoderChannelInfo channel context data.
 * \param pAacDecoderStaticChannelInfo channel context static data.
 * \param r output spectrum.
 * \param lg the frame length in audio samples.
 * \param frame the frame index of the LPD super frame.
 * \param pScale pointer to current scale shift factor of r[].
 * \param A1 old input LPC coefficients of length M_LP_FILTER_ORDER.
 * \param A2 new input LPC coefficients of length M_LP_FILTER_ORDER.
 * \param pAlfdGains pointer for ALFD gains output scaled by 1.
 * \param fdns_npts number of lines (FDNS_NPTS).
 * \param inf_mask pointer to noise mask.
 * \param IGF_win_mode IGF window mode (LONG, SHORT, TCX10, TCX20).
 * \param frameType (IGF_FRAME_DIVISION_AAC_OR_TCX_LONG or
 * IGF_FRAME_DIVISION_TCX_SHORT_1).
 * \param elFlags element specific parser guidance flags.
 * \param lg_fb the fullband frame length in audio samples.
 * \param IGF_bgn the IGF start index.
 * \param rms_m mantisse of energy.
 * \param rms_e exponent of energy.
 */
/* static */
void CLpd_FdnsDecode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
                     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
                     FIXP_DBL r[], const INT lg, const INT frame, SHORT *pScale,
                     const FIXP_LPC A1[M_LP_FILTER_ORDER], const INT A1_exp,
                     const FIXP_LPC A2[M_LP_FILTER_ORDER], const INT A2_exp,
                     FIXP_DBL pAlfdGains[LFAC / 4], const INT fdns_npts) {
  /* Weight LPC coefficients using Rm values */
  CLpd_AdaptLowFreqDeemph(r, lg, pAlfdGains, *pScale);

  FIXP_DBL rms_m = (FIXP_DBL)0;
  INT rms_e = 0;
  {
    /* Calculate Energy */
    rms_m = calcEnergy(r, *pScale, lg, &rms_e);
  }

  calcTCXGain(pAacDecoderChannelInfo, r, rms_m, rms_e, frame, lg);

  /* Apply ODFT and Noise Shaping. LP coefficient (A1, A2) weighting is done
   * inside on the fly. */

  lpc2mdctAndNoiseShaping(r, pScale, lg, fdns_npts, A1, A1_exp, A2, A2_exp);
}

/**
 * find pitch for TCX20 (time domain) concealment.
 */
static int find_mpitch(FIXP_DBL xri[], int lg) {
  FIXP_DBL max, pitch;
  INT pitch_e;
  int i, n;

  max = (FIXP_DBL)0;
  n = 2;

  /* find maximum below 400Hz */
  for (i = 2; i < (lg >> 4); i += 2) {
    FIXP_DBL tmp = fPow2Div2(xri[i]) + fPow2Div2(xri[i + 1]);
    if (tmp > max) {
      max = tmp;
      n = i;
    }
  }

  // pitch = ((float)lg<<1)/(float)n;
  pitch = fDivNorm((FIXP_DBL)lg << 1, (FIXP_DBL)n, &pitch_e);
  pitch >>= fixMax(0, DFRACT_BITS - 1 - pitch_e - 16);

  /* find pitch multiple under 20ms */
  if (pitch >= (FIXP_DBL)((256 << 16) - 1)) { /*231.0f*/
    n = 256;
  } else {
    FIXP_DBL mpitch = pitch;
    while (mpitch < (FIXP_DBL)(255 << 16)) {
      mpitch += pitch;
    }
    n = (int)(mpitch - pitch) >> 16;
  }

  return (n);
}

/**
 * number of spectral coefficients / time domain samples using frame mode as
 * index.
 */
static const int lg_table_ccfl[2][4] = {
    {256, 256, 512, 1024}, /* coreCoderFrameLength = 1024 */
    {192, 192, 384, 768}   /* coreCoderFrameLength = 768  */
};

/**
 * \brief Decode and render one MDCT-TCX frame.
 * \param pAacDecoderChannelInfo channel context data.
 * \param lg the frame length in audio samples.
 * \param frame the frame index of the LPD super frame.
 */
static void CLpd_TcxDecode(
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags,
    int mod, int last_mod, int frame, int frameOk) {
  FIXP_DBL *pAlfd_gains = pAacDecoderStaticChannelInfo->last_alfd_gains;
  ULONG *pSeed = &pAacDecoderStaticChannelInfo->nfRandomSeed;
  int lg = (pAacDecoderChannelInfo->granuleLength == 128)
               ? lg_table_ccfl[0][mod + 0]
               : lg_table_ccfl[1][mod + 0];
  int next_frame = frame + (1 << (mod - 1));
  int isFullBandLpd = 0;

  /* Obtain r[] vector by combining the quant[] and noise[] vectors */
  {
    FIXP_DBL noise_level;
    FIXP_DBL *coeffs =
        SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
                 pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
    int scale = pAacDecoderChannelInfo->specScale[frame];
    int i, nfBgn, nfEnd;
    UCHAR tcx_noise_factor = pAacDecoderChannelInfo->pDynData->specificTo.usac
                                 .tcx_noise_factor[frame];

    /* find pitch for bfi case */
    pAacDecoderStaticChannelInfo->last_tcx_pitch = find_mpitch(coeffs, lg);

    if (frameOk) {
      /* store for concealment */
      pAacDecoderStaticChannelInfo->last_tcx_noise_factor = tcx_noise_factor;
    } else {
      /* restore last frames value */
      tcx_noise_factor = pAacDecoderStaticChannelInfo->last_tcx_noise_factor;
    }

    noise_level =
        (FIXP_DBL)((LONG)FL2FXCONST_DBL(0.0625f) * (8 - tcx_noise_factor));
    noise_level = scaleValue(noise_level, -scale);

    const FIXP_DBL neg_noise_level = -noise_level;

    {
      nfBgn = lg / 6;
      nfEnd = lg;
    }

    for (i = nfBgn; i < nfEnd - 7; i += 8) {
      LONG tmp;

      /* Fill all 8 consecutive zero coeffs with noise */
      tmp = coeffs[i + 0] | coeffs[i + 1] | coeffs[i + 2] | coeffs[i + 3] |
            coeffs[i + 4] | coeffs[i + 5] | coeffs[i + 6] | coeffs[i + 7];

      if (tmp == 0) {
        for (int k = i; k < i + 8; k++) {
          UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
                                : (coeffs[k] = noise_level);
        }
      }
    }
    if ((nfEnd - i) >
        0) { /* noise filling for last "band" with less than 8 bins */
      LONG tmp = (LONG)coeffs[i];
      int k;

      FDK_ASSERT((nfEnd - i) < 8);
      for (k = 1; k < (nfEnd - i); k++) {
        tmp |= (LONG)coeffs[i + k];
      }
      if (tmp == 0) {
        for (k = i; k < nfEnd; k++) {
          UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
                                : (coeffs[k] = noise_level);
        }
      }
    }
  }

  {
    /* Convert LPC to LP domain */
    if (last_mod == 0) {
      /* Note: The case where last_mod == 255 is handled by other means
       * in CLpdChannelStream_Read() */
      E_LPC_f_lsp_a_conversion(
          pAacDecoderChannelInfo->data.usac.lsp_coeff[frame],
          pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
          &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame]);
    }

    E_LPC_f_lsp_a_conversion(
        pAacDecoderChannelInfo->data.usac.lsp_coeff[next_frame],
        pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
        &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame]);

    /* FDNS decoding */
    CLpd_FdnsDecode(
        pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
        SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
                 pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
        lg, frame, pAacDecoderChannelInfo->specScale + frame,
        pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
        pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame],
        pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
        pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame], pAlfd_gains,
        pAacDecoderChannelInfo->granuleLength / 2 /* == FDNS_NPTS(ccfl) */
    );
  }
}

/**
 * \brief Read the tcx_coding bitstream part
 * \param hBs bitstream handle to read from.
 * \param pAacDecoderChannelInfo channel context info to store data into.
 * \param lg the frame length in audio samples.
 * \param first_tcx_flag flag indicating that this is the first TCX frame.
 * \param frame the frame index of the LPD super frame.
 */
static AAC_DECODER_ERROR CLpd_TCX_Read(
    HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, int lg,
    int first_tcx_flag, int frame, UINT flags) {
  AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
  ARITH_CODING_ERROR error = ARITH_CODER_OK;
  FIXP_DBL *pSpec;
  int arith_reset_flag = 0;
  int isFullBandLpd = 0;

  pSpec = SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
                   pAacDecoderChannelInfo->granuleLength, isFullBandLpd);

  /* TCX noise level */
  {
    pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_noise_factor[frame] =
        FDKreadBits(hBs, 3);
  }
  /* TCX global gain */
  pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_global_gain[frame] =
      FDKreadBits(hBs, 7);

  /* Arithmetic coded residual/spectrum */
  if (first_tcx_flag) {
    if (flags & AC_INDEP) {
      arith_reset_flag = 1;
    } else {
      arith_reset_flag = FDKreadBits(hBs, 1);
    }
  }

  /* CArco_DecodeArithData() output scale of "pSpec" is DFRACT_BITS-1 */
  error = CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs, pSpec,
                                lg, lg, arith_reset_flag);

  /* Rescale residual/spectrum */
  {
    int scale = getScalefactor(pSpec, lg) - 2; /* Leave 2 bits headroom */

    /* Exponent of CArco_DecodeArithData() output is DFRACT_BITS; integer
     * values. */
    scaleValues(pSpec, lg, scale);
    scale = DFRACT_BITS - 1 - scale;

    pAacDecoderChannelInfo->specScale[frame] = scale;
  }

  if (error == ARITH_CODER_ERROR) errorAAC = AAC_DEC_UNKNOWN;

  return errorAAC;
}

/**
 * \brief translate lpd_mode into the mod[] array which describes the mode of
 * each each LPD frame
 * \param mod[] the array that will be filled with the mode indexes of the
 * inidividual frames.
 * \param lpd_mode the lpd_mode field read from the lpd_channel_stream
 */
static AAC_DECODER_ERROR CLpd_ReadAndMapLpdModeToModArray(
    UCHAR mod[4], HANDLE_FDK_BITSTREAM hBs, UINT elFlags) {
  int lpd_mode;

  {
    lpd_mode = FDKreadBits(hBs, 5);

    if (lpd_mode > 25 || lpd_mode < 0) {
      return AAC_DEC_PARSE_ERROR;
    }

    switch (lpd_mode) {
      case 25:
        /* 1 80MS frame */
        mod[0] = mod[1] = mod[2] = mod[3] = 3;
        break;
      case 24:
        /* 2 40MS frames */
        mod[0] = mod[1] = mod[2] = mod[3] = 2;
        break;
      default:
        switch (lpd_mode >> 2) {
          case 4:
            /* lpd_mode 19 - 16  => 1 40MS and 2 20MS frames */
            mod[0] = mod[1] = 2;
            mod[2] = (lpd_mode & 1) ? 1 : 0;
            mod[3] = (lpd_mode & 2) ? 1 : 0;
            break;
          case 5:
            /* lpd_mode 23 - 20 => 2 20MS and 1 40MS frames */
            mod[2] = mod[3] = 2;
            mod[0] = (lpd_mode & 1) ? 1 : 0;
            mod[1] = (lpd_mode & 2) ? 1 : 0;
            break;
          default:
            /* lpd_mode < 16 => 4 20MS frames */
            mod[0] = (lpd_mode & 1) ? 1 : 0;
            mod[1] = (lpd_mode & 2) ? 1 : 0;
            mod[2] = (lpd_mode & 4) ? 1 : 0;
            mod[3] = (lpd_mode & 8) ? 1 : 0;
            break;
        }
        break;
    }
  }
  return AAC_DEC_OK;
}

static void CLpd_Reset(
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    int keep_past_signal) {
  int i;

  /* Reset TCX / ACELP common memory */
  if (!keep_past_signal) {
    FDKmemclear(pAacDecoderStaticChannelInfo->old_synth,
                sizeof(pAacDecoderStaticChannelInfo->old_synth));
  }

  /* Initialize the LSFs */
  for (i = 0; i < M_LP_FILTER_ORDER; i++) {
    pAacDecoderStaticChannelInfo->lpc4_lsf[i] = fdk_dec_lsf_init[i];
  }

  /* Reset memory needed by bass post-filter */
  FDKmemclear(pAacDecoderStaticChannelInfo->mem_bpf,
              sizeof(pAacDecoderStaticChannelInfo->mem_bpf));

  pAacDecoderStaticChannelInfo->old_bpf_control_info = 0;
  for (i = 0; i < SYN_SFD; i++) {
    pAacDecoderStaticChannelInfo->old_T_pf[i] = 64;
    pAacDecoderStaticChannelInfo->old_gain_pf[i] = (FIXP_DBL)0;
  }

  /* Reset ACELP memory */
  CLpd_AcelpReset(&pAacDecoderStaticChannelInfo->acelp);

  pAacDecoderStaticChannelInfo->last_lpc_lost = 0;      /* prev_lpc_lost */
  pAacDecoderStaticChannelInfo->last_tcx_pitch = L_DIV; /* pitch_tcx     */
  pAacDecoderStaticChannelInfo->numLostLpdFrames = 0;   /* nbLostCmpt    */
}

/*
 * Externally visible functions
 */

AAC_DECODER_ERROR CLpdChannelStream_Read(
    HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    const SamplingRateInfo *pSamplingRateInfo, UINT flags) {
  AAC_DECODER_ERROR error = AAC_DEC_OK;
  int first_tcx_flag;
  int k, nbDiv, fFacDataPresent, first_lpd_flag, acelp_core_mode,
      facGetMemState = 0;
  UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
  int lpd_mode_last, prev_frame_was_lpd;
  USAC_COREMODE core_mode_last;
  const int lg_table_offset = 0;
  const int *lg_table = (pAacDecoderChannelInfo->granuleLength == 128)
                            ? &lg_table_ccfl[0][lg_table_offset]
                            : &lg_table_ccfl[1][lg_table_offset];
  int last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;

  int last_frame_ok = CConcealment_GetLastFrameOk(
      &pAacDecoderStaticChannelInfo->concealmentInfo, 1);

  INT i_offset;
  UINT samplingRate;

  samplingRate = pSamplingRateInfo->samplingRate;

  i_offset =
      (INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
      (INT)PIT_MIN_12k8;

  if ((samplingRate < FAC_FSCALE_MIN) || (samplingRate > FAC_FSCALE_MAX)) {
    error = AAC_DEC_PARSE_ERROR;
    goto bail;
  }

  acelp_core_mode = FDKreadBits(hBs, 3);

  /* lpd_mode */
  error = CLpd_ReadAndMapLpdModeToModArray(mod, hBs, 0);
  if (error != AAC_DEC_OK) {
    goto bail;
  }

  /* bpf_control_info */
  pAacDecoderChannelInfo->data.usac.bpf_control_info = FDKreadBit(hBs);

  /* last_core_mode */
  prev_frame_was_lpd = FDKreadBit(hBs);
  /* fac_data_present */
  fFacDataPresent = FDKreadBit(hBs);

  /* Set valid values from
   * pAacDecoderStaticChannelInfo->{last_core_mode,last_lpd_mode} */
  pAacDecoderChannelInfo->data.usac.core_mode_last =
      pAacDecoderStaticChannelInfo->last_core_mode;
  lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last =
      pAacDecoderStaticChannelInfo->last_lpd_mode;

  if (prev_frame_was_lpd == 0) {
    /* Last frame was FD */
    pAacDecoderChannelInfo->data.usac.core_mode_last = FD_LONG;
    pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
  } else {
    /* Last frame was LPD */
    pAacDecoderChannelInfo->data.usac.core_mode_last = LPD;
    if (((mod[0] == 0) && fFacDataPresent) ||
        ((mod[0] != 0) && !fFacDataPresent)) {
      /* Currend mod is ACELP, fac data present -> TCX, current mod TCX, no fac
       * data -> TCX */
      if (lpd_mode_last == 0) {
        /* Bit stream interruption detected. Assume last TCX mode as TCX20. */
        pAacDecoderChannelInfo->data.usac.lpd_mode_last = 1;
      }
      /* Else assume that remembered TCX mode is correct. */
    } else {
      pAacDecoderChannelInfo->data.usac.lpd_mode_last = 0;
    }
  }

  first_lpd_flag = (pAacDecoderChannelInfo->data.usac.core_mode_last !=
                    LPD); /* Depends on bitstream configuration */
  first_tcx_flag = 1;

  if (pAacDecoderStaticChannelInfo->last_core_mode !=
      LPD) { /* ATTENTION: Reset depends on what we rendered before! */
    CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo, 0);

    if (!last_frame_ok) {
      /* If last rendered frame was not LPD and first lpd flag is not set, this
       * must be an error - set last_lpc_lost flag */
      last_lpc_lost |= (first_lpd_flag) ? 0 : 1;
    }
  }

  core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last;
  lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last;

  nbDiv = NB_DIV;

  /* k is the frame index. If a frame is of size 40MS or 80MS,
     this frame index is incremented 2 or 4 instead of 1 respectively. */

  k = 0;
  while (k < nbDiv) {
    /* Reset FAC data pointers in order to avoid applying old random FAC data.
     */
    pAacDecoderChannelInfo->data.usac.fac_data[k] = NULL;

    if ((k == 0 && core_mode_last == LPD && fFacDataPresent) ||
        (lpd_mode_last == 0 && mod[k] > 0) ||
        ((lpd_mode_last != 255) && lpd_mode_last > 0 && mod[k] == 0)) {
      int err;

      /* Assign FAC memory */
      pAacDecoderChannelInfo->data.usac.fac_data[k] =
          CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);

      /* FAC for (ACELP -> TCX) or (TCX -> ACELP) */
      err = CLpd_FAC_Read(
          hBs, pAacDecoderChannelInfo->data.usac.fac_data[k],
          pAacDecoderChannelInfo->data.usac.fac_data_e,
          pAacDecoderChannelInfo->granuleLength, /* == fac_length */
          0, k);
      if (err != 0) {
        error = AAC_DEC_PARSE_ERROR;
        goto bail;
      }
    }

    if (mod[k] == 0) /* acelp-mode */
    {
      int err;
      err = CLpd_AcelpRead(
          hBs, &pAacDecoderChannelInfo->data.usac.acelp[k], acelp_core_mode,
          pAacDecoderChannelInfo->granuleLength * 8 /* coreCoderFrameLength */,
          i_offset);
      if (err != 0) {
        error = AAC_DEC_PARSE_ERROR;
        goto bail;
      }

      lpd_mode_last = 0;
      k++;
    } else /* mode != 0  =>  TCX */
    {
      error = CLpd_TCX_Read(hBs, pAacDecoderChannelInfo,
                            pAacDecoderStaticChannelInfo, lg_table[mod[k]],
                            first_tcx_flag, k, flags);

      lpd_mode_last = mod[k];
      first_tcx_flag = 0;
      k += 1 << (mod[k] - 1);
    }
    if (error != AAC_DEC_OK) {
      error = AAC_DEC_PARSE_ERROR;
      goto bail;
    }
  }

  {
    int err;

    /* Read LPC coefficients */
    err = CLpc_Read(
        hBs, pAacDecoderChannelInfo->data.usac.lsp_coeff,
        pAacDecoderStaticChannelInfo->lpc4_lsf,
        pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
        pAacDecoderChannelInfo->data.usac.aStability, mod, first_lpd_flag,
        /* if last lpc4 is available from concealment do not extrapolate lpc0
           from lpc2 */
        (mod[0] & 0x3) ? 0
                       : (last_lpc_lost &&
                          pAacDecoderStaticChannelInfo->last_core_mode != LPD),
        last_frame_ok);
    if (err != 0) {
      error = AAC_DEC_PARSE_ERROR;
      goto bail;
    }
  }

  /* adjust old lsp[] following to a bad frame (to avoid overshoot) (ref:
   * dec_LPD.c) */
  if (last_lpc_lost && !last_frame_ok) {
    int k_next;
    k = 0;
    while (k < nbDiv) {
      int i;
      k_next = k + (((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1)));
      FIXP_LPC *lsp_old = pAacDecoderChannelInfo->data.usac.lsp_coeff[k];
      FIXP_LPC *lsp_new = pAacDecoderChannelInfo->data.usac.lsp_coeff[k_next];

      for (i = 0; i < M_LP_FILTER_ORDER; i++) {
        if (lsp_new[i] < lsp_old[i]) {
          lsp_old[i] = lsp_new[i];
        }
      }
      k = k_next;
    }
  }

  if (!CConcealment_GetLastFrameOk(
          &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
    E_LPC_f_lsp_a_conversion(
        pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
        pAacDecoderChannelInfo->data.usac.lp_coeff[0],
        &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
  } else if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) {
    if (pAacDecoderStaticChannelInfo->last_lpd_mode == 255) {
      /* We need it for TCX decoding or ACELP excitation update */
      E_LPC_f_lsp_a_conversion(
          pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
          pAacDecoderChannelInfo->data.usac.lp_coeff[0],
          &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
    } else { /* last_lpd_mode was TCX */
      /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
       * converting LSP coefficients again). */
      FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
                pAacDecoderStaticChannelInfo->lp_coeff_old[0],
                M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
      pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
          pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
    }
  } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */

  if (fFacDataPresent && (core_mode_last != LPD)) {
    int prev_frame_was_short;

    prev_frame_was_short = FDKreadBit(hBs);

    if (prev_frame_was_short) {
      core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last =
          FD_SHORT;
      pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;

      if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) &&
          CConcealment_GetLastFrameOk(
              &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
        /* USAC Conformance document:
           short_fac_flag   shall be encoded with a value of 1 if the
           window_sequence of the previous frame was 2 (EIGHT_SHORT_SEQUENCE).
                            Otherwise short_fac_flag shall be encoded with a
           value of 0. */
        error = AAC_DEC_PARSE_ERROR;
        goto bail;
      }
    }

    /* Assign memory */
    pAacDecoderChannelInfo->data.usac.fac_data[0] =
        CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);

    {
      int err;

      /* FAC for FD -> ACELP */
      err = CLpd_FAC_Read(
          hBs, pAacDecoderChannelInfo->data.usac.fac_data[0],
          pAacDecoderChannelInfo->data.usac.fac_data_e,
          CLpd_FAC_getLength(core_mode_last != FD_SHORT,
                             pAacDecoderChannelInfo->granuleLength),
          1, 0);
      if (err != 0) {
        error = AAC_DEC_PARSE_ERROR;
        goto bail;
      }
    }
  }

bail:
  if (error == AAC_DEC_OK) {
    /* check consitency of last core/lpd mode values */
    if ((pAacDecoderChannelInfo->data.usac.core_mode_last !=
         pAacDecoderStaticChannelInfo->last_core_mode) &&
        (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
      /* Something got wrong! */
      /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
    } else if ((pAacDecoderChannelInfo->data.usac.core_mode_last == LPD) &&
               (pAacDecoderChannelInfo->data.usac.lpd_mode_last !=
                pAacDecoderStaticChannelInfo->last_lpd_mode) &&
               (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
      /* Something got wrong! */
      /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
    }
  }

  return error;
}

void CLpdChannelStream_Decode(
    CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags) {
  UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
  int k;
  UCHAR last_lpd_mode;
  int nbDiv = NB_DIV;

  /* k is the frame index. If a frame is of size 40MS or 80MS,
     this frame index is incremented 2 or 4 instead of 1 respectively. */
  k = 0;
  last_lpd_mode =
      pAacDecoderChannelInfo->data.usac
          .lpd_mode_last; /* could be different to what has been rendered */
  while (k < nbDiv) {
    if (mod[k] == 0) {
      /* ACELP */

      /* If FAC (fac_data[k] != NULL), and previous frame was TCX, apply (TCX)
       * gains to FAC data */
      if (last_lpd_mode > 0 && last_lpd_mode != 255 &&
          pAacDecoderChannelInfo->data.usac.fac_data[k]) {
        CFac_ApplyGains(pAacDecoderChannelInfo->data.usac.fac_data[k],
                        pAacDecoderChannelInfo->granuleLength,
                        pAacDecoderStaticChannelInfo->last_tcx_gain,
                        pAacDecoderStaticChannelInfo->last_alfd_gains,
                        (last_lpd_mode < 4) ? last_lpd_mode : 3);

        pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
            pAacDecoderStaticChannelInfo->last_tcx_gain_e;
      }
    } else {
      /* TCX */
      CLpd_TcxDecode(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
                     flags, mod[k], last_lpd_mode, k, 1 /* frameOk == 1 */
      );

      /* Store TCX gain scale for next possible FAC transition. */
      pAacDecoderStaticChannelInfo->last_tcx_gain =
          pAacDecoderChannelInfo->data.usac.tcx_gain[k];
      pAacDecoderStaticChannelInfo->last_tcx_gain_e =
          pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];

      /* If FAC (fac_data[k] != NULL), apply gains */
      if (last_lpd_mode == 0 && pAacDecoderChannelInfo->data.usac.fac_data[k]) {
        CFac_ApplyGains(
            pAacDecoderChannelInfo->data.usac.fac_data[k],
            pAacDecoderChannelInfo->granuleLength /* == fac_length */,
            pAacDecoderChannelInfo->data.usac.tcx_gain[k],
            pAacDecoderStaticChannelInfo->last_alfd_gains, mod[k]);

        pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
            pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];
      }
    }

    /* remember previous mode */
    last_lpd_mode = mod[k];

    /* Increase k to next frame */
    k += (mod[k] == 0) ? 1 : (1 << (mod[k] - 1));
  }
}

AAC_DECODER_ERROR CLpd_RenderTimeSignal(
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
    INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags,
    UINT strmFlags) {
  UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
  AAC_DECODER_ERROR error = AAC_DEC_OK;
  int k, i_offset;
  int last_k;
  int nrSamples = 0;
  int facFB = 1;
  int nbDiv = NB_DIV;
  int lDiv = lFrame / nbDiv; /* length of division (acelp or tcx20 frame)*/
  int lFac = lDiv / 2;
  int nbSubfr =
      lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
  int nbSubfrSuperfr = nbDiv * nbSubfr;
  int synSfd = (nbSubfrSuperfr / 2) - BPF_SFD;
  int SynDelay = synSfd * L_SUBFR;
  int aacDelay = lFrame / 2;

  /*
   In respect to the reference software, the synth pointer here is lagging by
   aacDelay ( == SYN_DELAY + BPF_DELAY ) samples. The corresponding old
   synthesis samples are handled by the IMDCT overlap.
   */

  FIXP_DBL *synth_buf =
      pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->synth_buf;
  FIXP_DBL *synth = synth_buf + PIT_MAX_MAX - BPF_DELAY;
  UCHAR last_lpd_mode, last_last_lpd_mode, last_lpc_lost, last_frame_lost;

  INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
  FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];

  const int *lg_table;
  int lg_table_offset = 0;

  UINT samplingRate = pSamplingRateInfo->samplingRate;

  FDKmemclear(pitch, (NB_SUBFR_SUPERFR + SYN_SFD) * sizeof(INT));

  if (flags & AACDEC_FLUSH) {
    CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
               flags & AACDEC_FLUSH);
    frameOk = 0;
  }

  switch (lFrame) {
    case 1024:
      lg_table = &lg_table_ccfl[0][lg_table_offset];
      break;
    case 768:
      lg_table = &lg_table_ccfl[1][lg_table_offset];
      break;
    default:
      FDK_ASSERT(0);
      return AAC_DEC_UNKNOWN;
  }

  last_frame_lost = !CConcealment_GetLastFrameOk(
      &pAacDecoderStaticChannelInfo->concealmentInfo, 0);

  /* Maintain LPD mode from previous frame */
  if ((pAacDecoderStaticChannelInfo->last_core_mode == FD_LONG) ||
      (pAacDecoderStaticChannelInfo->last_core_mode == FD_SHORT)) {
    pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
  }

  if (!frameOk) {
    FIXP_DBL old_tcx_gain;
    FIXP_SGL old_stab;
    SCHAR old_tcx_gain_e;
    int nLostSf;

    last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
    old_tcx_gain = pAacDecoderStaticChannelInfo->last_tcx_gain;
    old_tcx_gain_e = pAacDecoderStaticChannelInfo->last_tcx_gain_e;
    old_stab = pAacDecoderStaticChannelInfo->oldStability;
    nLostSf = pAacDecoderStaticChannelInfo->numLostLpdFrames;

    /* patch the last LPD mode */
    pAacDecoderChannelInfo->data.usac.lpd_mode_last = last_lpd_mode;

    /* Do mode extrapolation and repeat the previous mode:
       if previous mode = ACELP        -> ACELP
       if previous mode = TCX-20/40    -> TCX-20
       if previous mode = TCX-80       -> TCX-80
       notes:
       - ACELP is not allowed after TCX (no pitch information to reuse)
       - TCX-40 is not allowed in the mode repetition to keep the logic simple
     */
    switch (last_lpd_mode) {
      case 0:
        mod[0] = mod[1] = mod[2] = mod[3] = 0; /* -> ACELP concealment */
        break;
      case 3:
        mod[0] = mod[1] = mod[2] = mod[3] = 3; /* -> TCX FD concealment */
        break;
      case 2:
        mod[0] = mod[1] = mod[2] = mod[3] = 2; /* -> TCX FD concealment */
        break;
      case 1:
      default:
        mod[0] = mod[1] = mod[2] = mod[3] = 4; /* -> TCX TD concealment */
        break;
    }

    /* LPC extrapolation */
    CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
                 pAacDecoderStaticChannelInfo->lpc4_lsf,
                 pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
                 /*(pAacDecoderStaticChannelInfo->numLostLpdFrames == 0) ||*/
                 (last_lpd_mode == 255));

    if ((last_lpd_mode > 0) && (last_lpd_mode < 255)) {
      /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
       * converting LSP coefficients again). */
      FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
                pAacDecoderStaticChannelInfo->lp_coeff_old[0],
                M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
      pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
          pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
    } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */
    /* case last_lpd_mode was Time domain TCX concealment is handled after this
     * "if (!frameOk)"-block */

    /* k is the frame index. If a frame is of size 40MS or 80MS,
       this frame index is incremented 2 or 4 instead of 1 respectively. */
    k = 0;
    while (k < nbDiv) {
      pAacDecoderChannelInfo->data.usac.tcx_gain[k] = old_tcx_gain;
      pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] = old_tcx_gain_e;

      /* restore stability value from last frame */
      pAacDecoderChannelInfo->data.usac.aStability[k] = old_stab;

      /* Increase k to next frame */
      k += ((mod[k] & 0x3) == 0) ? 1 : (1 << ((mod[k] & 0x3) - 1));

      nLostSf++;
    }
  } else {
    if ((pAacDecoderStaticChannelInfo->last_lpd_mode == 4) && (mod[0] > 0)) {
      /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
       * converting LSP coefficients again). */
      FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
                pAacDecoderStaticChannelInfo->lp_coeff_old[0],
                M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
      pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
          pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
    }
  }

  Acelp_PreProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth, pitch,
                      pAacDecoderStaticChannelInfo->old_T_pf, pit_gain,
                      pAacDecoderStaticChannelInfo->old_gain_pf, samplingRate,
                      &i_offset, lFrame, synSfd, nbSubfrSuperfr);

  /* k is the frame index. If a frame is of size 40MS or 80MS,
     this frame index is incremented 2 or 4 instead of 1 respectively. */
  k = 0;
  last_k = -1; /* mark invalid */
  last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
  last_last_lpd_mode = pAacDecoderStaticChannelInfo->last_last_lpd_mode;
  last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost | last_frame_lost;

  /* This buffer must be avalable for the case of FD->ACELP transition. The
  beginning of the buffer is used after the BPF to overwrite the output signal.
  Only the FAC area must be affected by the BPF */

  while (k < nbDiv) {
    if (frameOk == 0) {
      pAacDecoderStaticChannelInfo->numLostLpdFrames++;
    } else {
      last_frame_lost |=
          (pAacDecoderStaticChannelInfo->numLostLpdFrames > 0) ? 1 : 0;
      pAacDecoderStaticChannelInfo->numLostLpdFrames = 0;
    }
    if (mod[k] == 0 || mod[k] == 4) {
      /* ACELP or TCX time domain concealment */
      FIXP_DBL *acelp_out;

      /* FAC management */
      if ((last_lpd_mode != 0) && (last_lpd_mode != 4)) /* TCX TD concealment */
      {
        FIXP_DBL *pFacData = NULL;

        if (frameOk && !last_frame_lost) {
          pFacData = pAacDecoderChannelInfo->data.usac.fac_data[k];
        }

        nrSamples += CLpd_FAC_Mdct2Acelp(
            &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples, pFacData,
            pAacDecoderChannelInfo->data.usac.fac_data_e[k],
            pAacDecoderChannelInfo->data.usac.lp_coeff[k],
            pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
            lFrame - nrSamples,
            CLpd_FAC_getLength(
                (pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) ||
                    (k > 0),
                lFac),
            (pAacDecoderStaticChannelInfo->last_core_mode != LPD) && (k == 0),
            0);

        FDKmemcpy(
            synth + nrSamples, pAacDecoderStaticChannelInfo->IMdct.overlap.time,
            pAacDecoderStaticChannelInfo->IMdct.ov_offset * sizeof(FIXP_DBL));
        {
          FIXP_LPC *lp_prev =
              pAacDecoderChannelInfo->data.usac
                  .lp_coeff[0]; /* init value does not real matter */
          INT lp_prev_exp = pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0];

          if (last_lpd_mode != 255) { /* last mode was tcx */
            last_k = k - (1 << (last_lpd_mode - 1));
            if (last_k < 0) {
              lp_prev = pAacDecoderStaticChannelInfo->lp_coeff_old[1];
              lp_prev_exp = pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1];
            } else {
              lp_prev = pAacDecoderChannelInfo->data.usac.lp_coeff[last_k];
              lp_prev_exp =
                  pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
            }
          }

          CLpd_AcelpPrepareInternalMem(
              synth + aacDelay + k * lDiv, last_lpd_mode,
              (last_last_lpd_mode == 4) ? 0 : last_last_lpd_mode,
              pAacDecoderChannelInfo->data.usac.lp_coeff[k],
              pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k], lp_prev,
              lp_prev_exp, &pAacDecoderStaticChannelInfo->acelp, lFrame,
              (last_frame_lost && k < 2), mod[k]);
        }
      } else {
        if (k == 0 && pAacDecoderStaticChannelInfo->IMdct.ov_offset !=
                          lFrame / facFB / 2) {
          pAacDecoderStaticChannelInfo->IMdct.ov_offset = lFrame / facFB / 2;
        }
        nrSamples += imdct_drain(&pAacDecoderStaticChannelInfo->IMdct,
                                 synth + nrSamples, lFrame / facFB - nrSamples);
      }

      if (nrSamples >= lFrame / facFB) {
        /* Write ACELP time domain samples into IMDCT overlap buffer at
         * pAacDecoderStaticChannelInfo->IMdct.overlap.time +
         * pAacDecoderStaticChannelInfo->IMdct.ov_offset
         */
        acelp_out = pAacDecoderStaticChannelInfo->IMdct.overlap.time +
                    pAacDecoderStaticChannelInfo->IMdct.ov_offset;

        /* Account ACELP time domain output samples to overlap buffer */
        pAacDecoderStaticChannelInfo->IMdct.ov_offset += lDiv;
      } else {
        /* Write ACELP time domain samples into output buffer at pTimeData +
         * nrSamples */
        acelp_out = synth + nrSamples;

        /* Account ACELP time domain output samples to output buffer */
        nrSamples += lDiv;
      }

      if (mod[k] == 4) {
        pAacDecoderStaticChannelInfo->acelp.wsyn_rms = scaleValue(
            pAacDecoderChannelInfo->data.usac.tcx_gain[k],
            fixMin(0,
                   pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] - SF_EXC));
        CLpd_TcxTDConceal(&pAacDecoderStaticChannelInfo->acelp,
                          &pAacDecoderStaticChannelInfo->last_tcx_pitch,
                          pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
                          pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
                          pAacDecoderChannelInfo->data.usac.aStability[k],
                          pAacDecoderStaticChannelInfo->numLostLpdFrames,
                          acelp_out, lFrame,
                          pAacDecoderStaticChannelInfo->last_tcx_noise_factor);

      } else {
        FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[k] >=
                   (FIXP_SGL)0);
        CLpd_AcelpDecode(&pAacDecoderStaticChannelInfo->acelp, i_offset,
                         pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
                         pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
                         pAacDecoderChannelInfo->data.usac.aStability[k],
                         &pAacDecoderChannelInfo->data.usac.acelp[k],
                         pAacDecoderStaticChannelInfo->numLostLpdFrames,
                         last_lpc_lost, k, acelp_out,
                         &pitch[(k * nbSubfr) + synSfd],
                         &pit_gain[(k * nbSubfr) + synSfd], lFrame);
      }

      if (mod[k] != 4) {
        if (last_lpd_mode != 0 &&
            pAacDecoderChannelInfo->data.usac
                .bpf_control_info) { /* FD/TCX -> ACELP transition */
          /* bass post-filter past FAC area (past two (one for FD short)
           * subframes) */
          int currentSf = synSfd + k * nbSubfr;

          if ((k > 0) || (pAacDecoderStaticChannelInfo->last_core_mode !=
                          FD_SHORT)) { /* TCX or FD long -> ACELP */
            pitch[currentSf - 2] = pitch[currentSf - 1] = pitch[currentSf];
            pit_gain[currentSf - 2] = pit_gain[currentSf - 1] =
                pit_gain[currentSf];
          } else { /* FD short -> ACELP */
            pitch[currentSf - 1] = pitch[currentSf];
            pit_gain[currentSf - 1] = pit_gain[currentSf];
          }
        }
      }
    } else { /* TCX */
      int lg = lg_table[mod[k]];
      int isFullBandLpd = 0;

      /* FAC management */
      if ((last_lpd_mode == 0) || (last_lpd_mode == 4)) /* TCX TD concealment */
      {
        C_AALLOC_SCRATCH_START(fac_buf, FIXP_DBL, 1024 / 8);

        /* pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL means no FAC
         * data available. */
        if (last_frame_lost == 1 ||
            pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL) {
          FDKmemclear(fac_buf, 1024 / 8 * sizeof(FIXP_DBL));
          pAacDecoderChannelInfo->data.usac.fac_data[k] = fac_buf;
          pAacDecoderChannelInfo->data.usac.fac_data_e[k] = 0;
        }

        nrSamples += CLpd_FAC_Acelp2Mdct(
            &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
            SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
                     pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
            pAacDecoderChannelInfo->specScale + k, 1,
            pAacDecoderChannelInfo->data.usac.fac_data[k],
            pAacDecoderChannelInfo->data.usac.fac_data_e[k],
            pAacDecoderChannelInfo->granuleLength /* == fac_length */,
            lFrame - nrSamples, lg,
            FDKgetWindowSlope(lDiv,
                              GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
            lDiv, pAacDecoderChannelInfo->data.usac.lp_coeff[k],
            pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
            &pAacDecoderStaticChannelInfo->acelp,
            pAacDecoderChannelInfo->data.usac.tcx_gain[k],
            (last_frame_lost || !frameOk), 0 /* is not FD FAC */
            ,
            last_lpd_mode, k,
            pAacDecoderChannelInfo
                ->currAliasingSymmetry /* Note: The current aliasing
                                          symmetry for a TCX (i.e. LPD)
                                          frame must always be 0 */
        );

        pitch[(k * nbSubfr) + synSfd + 1] = pitch[(k * nbSubfr) + synSfd] =
            pitch[(k * nbSubfr) + synSfd - 1];
        pit_gain[(k * nbSubfr) + synSfd + 1] =
            pit_gain[(k * nbSubfr) + synSfd] =
                pit_gain[(k * nbSubfr) + synSfd - 1];

        C_AALLOC_SCRATCH_END(fac_buf, FIXP_DBL, 1024 / 8);
      } else {
        int tl = lg;
        int fl = lDiv;
        int fr = lDiv;

        nrSamples += imlt_block(
            &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
            SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
                     pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
            pAacDecoderChannelInfo->specScale + k, 1, lFrame - nrSamples, tl,
            FDKgetWindowSlope(fl,
                              GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
            fl,
            FDKgetWindowSlope(fr,
                              GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
            fr, pAacDecoderChannelInfo->data.usac.tcx_gain[k],
            pAacDecoderChannelInfo->currAliasingSymmetry
                ? MLT_FLAG_CURR_ALIAS_SYMMETRY
                : 0);
      }
    }
    /* remember previous mode */
    last_last_lpd_mode = last_lpd_mode;
    last_lpd_mode = mod[k];
    last_lpc_lost = (frameOk == 0) ? 1 : 0;

    /* Increase k to next frame */
    last_k = k;
    k += ((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1));
  }

  if (frameOk) {
    /* assume data was ok => store for concealment */
    FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[last_k] >=
               (FIXP_SGL)0);
    pAacDecoderStaticChannelInfo->oldStability =
        pAacDecoderChannelInfo->data.usac.aStability[last_k];
    FDKmemcpy(pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
              pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
              M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
  }

  /* store past lp coeffs for next superframe (they are only valid and needed if
   * last_lpd_mode was tcx) */
  if (last_lpd_mode > 0) {
    FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[0],
              pAacDecoderChannelInfo->data.usac.lp_coeff[nbDiv],
              M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
    pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0] =
        pAacDecoderChannelInfo->data.usac.lp_coeff_exp[nbDiv];
    FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[1],
              pAacDecoderChannelInfo->data.usac.lp_coeff[last_k],
              M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
    pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1] =
        pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
  }

  FDK_ASSERT(nrSamples == lFrame);

  /* check whether usage of bass postfilter was de-activated in the bitstream;
   if yes, set pitch gain to 0 */
  if (!(pAacDecoderChannelInfo->data.usac.bpf_control_info)) {
    if (mod[0] != 0 && (pAacDecoderStaticChannelInfo->old_bpf_control_info)) {
      for (int i = 2; i < nbSubfrSuperfr; i++)
        pit_gain[synSfd + i] = (FIXP_DBL)0;
    } else {
      for (int i = 0; i < nbSubfrSuperfr; i++)
        pit_gain[synSfd + i] = (FIXP_DBL)0;
    }
  }

  /* for bass postfilter */
  for (int n = 0; n < synSfd; n++) {
    pAacDecoderStaticChannelInfo->old_T_pf[n] = pitch[nbSubfrSuperfr + n];
    pAacDecoderStaticChannelInfo->old_gain_pf[n] = pit_gain[nbSubfrSuperfr + n];
  }

  pAacDecoderStaticChannelInfo->old_bpf_control_info =
      pAacDecoderChannelInfo->data.usac.bpf_control_info;

  {
    INT lookahead = -BPF_DELAY;
    int copySamp = (mod[nbDiv - 1] == 0) ? (aacDelay) : (aacDelay - lFac);

    /* Copy enough time domain samples from MDCT to synthesis buffer as needed
     * by the bass postfilter */

    lookahead += imdct_copy_ov_and_nr(&pAacDecoderStaticChannelInfo->IMdct,
                                      synth + nrSamples, copySamp);

    FDK_ASSERT(lookahead == copySamp - BPF_DELAY);

    FIXP_DBL *p2_synth = synth + BPF_DELAY;

    /* recalculate pitch gain to allow postfilering on FAC area */
    for (int i = 0; i < nbSubfrSuperfr; i++) {
      int T = pitch[i];
      FIXP_DBL gain = pit_gain[i];

      if (gain > (FIXP_DBL)0) {
        gain = get_gain(&p2_synth[i * L_SUBFR], &p2_synth[(i * L_SUBFR) - T],
                        L_SUBFR);
        pit_gain[i] = gain;
      }
    }

    {
      bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB,
                        mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay,
                        pTimeData, pAacDecoderStaticChannelInfo->mem_bpf);
    }
  }

  Acelp_PostProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth,
                       pitch, pAacDecoderStaticChannelInfo->old_T_pf, lFrame,
                       synSfd, nbSubfrSuperfr);

  /* Store last mode for next super frame */
  { pAacDecoderStaticChannelInfo->last_core_mode = LPD; }
  pAacDecoderStaticChannelInfo->last_lpd_mode = last_lpd_mode;
  pAacDecoderStaticChannelInfo->last_last_lpd_mode = last_last_lpd_mode;
  pAacDecoderStaticChannelInfo->last_lpc_lost = last_lpc_lost;

  return error;
}
