/* -----------------------------------------------------------------------------
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):   Matthias Hildenbrand

   Description: USAC ACELP frame decoder

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

#include "usacdec_acelp.h"

#include "usacdec_ace_d4t64.h"
#include "usacdec_ace_ltp.h"
#include "usacdec_rom.h"
#include "usacdec_lpc.h"
#include "genericStds.h"

#define PIT_FR2_12k8 128 /* Minimum pitch lag with resolution 1/2      */
#define PIT_FR1_12k8 160 /* Minimum pitch lag with resolution 1        */
#define TILT_CODE2 \
  FL2FXCONST_SGL(0.3f * 2.0f) /* ACELP code pre-emphasis factor ( *2 )      */
#define PIT_SHARP \
  FL2FXCONST_SGL(0.85f) /* pitch sharpening factor                    */
#define PREEMPH_FAC \
  FL2FXCONST_SGL(0.68f) /* ACELP synth pre-emphasis factor            */

#define ACELP_HEADROOM 1
#define ACELP_OUTSCALE (MDCT_OUT_HEADROOM - ACELP_HEADROOM)

/**
 * \brief Calculate pre-emphasis (1 - mu z^-1) on input signal.
 * \param[in] in pointer to input signal; in[-1] is also needed.
 * \param[out] out pointer to output signal.
 * \param[in] L length of filtering.
 */
/* static */
void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
  int i;

  for (i = 0; i < L; i++) {
    out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]);
  }

  return;
}

/**
 * \brief Calculate de-emphasis 1/(1 - TILT_CODE z^-1) on innovative codebook
 * vector.
 * \param[in,out] x innovative codebook vector.
 */
static void Preemph_code(
    FIXP_COD x[] /* (i/o)   : input signal overwritten by the output */
) {
  int i;
  FIXP_DBL L_tmp;

  /* ARM926: 12 cycles per sample */
  for (i = L_SUBFR - 1; i > 0; i--) {
    L_tmp = FX_COD2FX_DBL(x[i]);
    L_tmp -= fMultDiv2(x[i - 1], TILT_CODE2);
    x[i] = FX_DBL2FX_COD(L_tmp);
  }
}

/**
 * \brief Apply pitch sharpener to the innovative codebook vector.
 * \param[in,out] x innovative codebook vector.
 * \param[in] pit_lag decoded pitch lag.
 */
static void Pit_shrp(
    FIXP_COD x[], /* in/out: impulse response (or algebraic code) */
    int pit_lag   /* input : pitch lag                            */
) {
  int i;
  FIXP_DBL L_tmp;

  for (i = pit_lag; i < L_SUBFR; i++) {
    L_tmp = FX_COD2FX_DBL(x[i]);
    L_tmp += fMult(x[i - pit_lag], PIT_SHARP);
    x[i] = FX_DBL2FX_COD(L_tmp);
  }

  return;
}

  /**
   * \brief Calculate Quantized codebook gain, Quantized pitch gain and unbiased
   *        Innovative code vector energy.
   * \param[in] index index of quantizer.
   * \param[in] code innovative code vector with exponent = SF_CODE.
   * \param[out] gain_pit Quantized pitch gain g_p with exponent = SF_GAIN_P.
   * \param[out] gain_code Quantized codebook gain g_c.
   * \param[in] mean_ener mean_ener defined in open-loop (2 bits), exponent = 7.
   * \param[out] E_code unbiased innovative code vector energy.
   * \param[out] E_code_e exponent of unbiased innovative code vector energy.
   */

#define SF_MEAN_ENER_LG10 9

/* pow(10.0, {18, 30, 42, 54}/20.0) /(float)(1<<SF_MEAN_ENER_LG10) */
static const FIXP_DBL pow_10_mean_energy[4] = {0x01fc5ebd, 0x07e7db92,
                                               0x1f791f65, 0x7d4bfba3};

static void D_gain2_plus(int index, FIXP_COD code[], FIXP_SGL *gain_pit,
                         FIXP_DBL *gain_code, int mean_ener_bits, int bfi,
                         FIXP_SGL *past_gpit, FIXP_DBL *past_gcode,
                         FIXP_DBL *pEner_code, int *pEner_code_e) {
  FIXP_DBL Ltmp;
  FIXP_DBL gcode0, gcode_inov;
  INT gcode0_e, gcode_inov_e;
  int i;

  FIXP_DBL ener_code;
  INT ener_code_e;

  /* ener_code = sum(code[]^2) */
  ener_code = FIXP_DBL(0);
  for (i = 0; i < L_SUBFR; i++) {
    ener_code += fPow2Div2(code[i]);
  }

  ener_code_e = fMax(fNorm(ener_code) - 1, 0);
  ener_code <<= ener_code_e;
  ener_code_e = 2 * SF_CODE + 1 - ener_code_e;

  /* export energy of code for calc_period_factor() */
  *pEner_code = ener_code;
  *pEner_code_e = ener_code_e;

  ener_code += scaleValue(FL2FXCONST_DBL(0.01f), -ener_code_e);

  /* ener_code *= 1/L_SUBFR, and make exponent even (because of square root
   * below). */
  if (ener_code_e & 1) {
    ener_code_e -= 5;
    ener_code >>= 1;
  } else {
    ener_code_e -= 6;
  }
  gcode_inov = invSqrtNorm2(ener_code, &gcode0_e);
  gcode_inov_e = gcode0_e - (ener_code_e >> 1);

  if (bfi) {
    FIXP_DBL tgcode;
    FIXP_SGL tgpit;

    tgpit = *past_gpit;

    if (tgpit > FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P))) {
      tgpit = FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P));
    } else if (tgpit < FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P))) {
      tgpit = FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P));
    }
    *gain_pit = tgpit;
    tgpit = FX_DBL2FX_SGL(fMult(tgpit, FL2FXCONST_DBL(0.95f)));
    *past_gpit = tgpit;

    tgpit = FL2FXCONST_SGL(1.4f / (1 << SF_GAIN_P)) - tgpit;
    tgcode = fMult(*past_gcode, tgpit) << SF_GAIN_P;
    *gain_code = scaleValue(fMult(tgcode, gcode_inov), gcode_inov_e);
    *past_gcode = tgcode;

    return;
  }

  /*-------------- Decode gains ---------------*/
  /*
   gcode0 = pow(10.0, (float)mean_ener/20.0);
   gcode0 = gcode0 / sqrt(ener_code/L_SUBFR);
   */
  gcode0 = pow_10_mean_energy[mean_ener_bits];
  gcode0 = fMultDiv2(gcode0, gcode_inov);
  gcode0_e = gcode0_e + SF_MEAN_ENER_LG10 - (ener_code_e >> 1) + 1;

  i = index << 1;
  *gain_pit = t_qua_gain7b[i]; /* adaptive codebook gain */
  /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */
  Ltmp = fMult(t_qua_gain7b[i + 1], gcode0);
  *gain_code = scaleValue(Ltmp, gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B);

  /* update bad frame handler */
  *past_gpit = *gain_pit;

  /*--------------------------------------------------------
    past_gcode  = gain_code/gcode_inov
   --------------------------------------------------------*/
  {
    FIXP_DBL gcode_m;
    INT gcode_e;

    gcode_m = fDivNormHighPrec(Ltmp, gcode_inov, &gcode_e);
    gcode_e += (gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B) - (gcode_inov_e);
    *past_gcode = scaleValue(gcode_m, gcode_e);
  }
}

/**
 * \brief Calculate period/voicing factor r_v
 * \param[in] exc pitch excitation.
 * \param[in] gain_pit gain of pitch g_p.
 * \param[in] gain_code gain of code g_c.
 * \param[in] gain_code_e exponent of gain of code.
 * \param[in] ener_code unbiased innovative code vector energy.
 * \param[in] ener_code_e exponent of unbiased innovative code vector energy.
 * \return period/voice factor r_v (-1=unvoiced to 1=voiced), exponent SF_PFAC.
 */
static FIXP_DBL calc_period_factor(FIXP_DBL exc[], FIXP_SGL gain_pit,
                                   FIXP_DBL gain_code, FIXP_DBL ener_code,
                                   int ener_code_e) {
  int ener_exc_e, L_tmp_e, s = 0;
  FIXP_DBL ener_exc, L_tmp;
  FIXP_DBL period_fac;

  /* energy of pitch excitation */
  ener_exc = (FIXP_DBL)0;
  for (int i = 0; i < L_SUBFR; i++) {
    ener_exc += fPow2Div2(exc[i]) >> s;
    if (ener_exc >= FL2FXCONST_DBL(0.5f)) {
      ener_exc >>= 1;
      s++;
    }
  }

  ener_exc_e = fNorm(ener_exc);
  ener_exc = fMult(ener_exc << ener_exc_e, fPow2(gain_pit));
  if (ener_exc != (FIXP_DBL)0) {
    ener_exc_e = 2 * SF_EXC + 1 + 2 * SF_GAIN_P - ener_exc_e + s;
  } else {
    ener_exc_e = 0;
  }

  /* energy of innovative code excitation */
  /* L_tmp = ener_code * gain_code*gain_code; */
  L_tmp_e = fNorm(gain_code);
  L_tmp = fPow2(gain_code << L_tmp_e);
  L_tmp = fMult(ener_code, L_tmp);
  L_tmp_e = 2 * SF_GAIN_C + ener_code_e - 2 * L_tmp_e;

  /* Find common exponent */
  {
    FIXP_DBL num, den;
    int exp_diff;

    exp_diff = ener_exc_e - L_tmp_e;
    if (exp_diff >= 0) {
      ener_exc >>= 1;
      if (exp_diff <= DFRACT_BITS - 2) {
        L_tmp >>= exp_diff + 1;
      } else {
        L_tmp = (FIXP_DBL)0;
      }
      den = ener_exc + L_tmp;
      if (ener_exc_e < DFRACT_BITS - 1) {
        den += scaleValue(FL2FXCONST_DBL(0.01f), -ener_exc_e - 1);
      }
    } else {
      if (exp_diff >= -(DFRACT_BITS - 2)) {
        ener_exc >>= 1 - exp_diff;
      } else {
        ener_exc = (FIXP_DBL)0;
      }
      L_tmp >>= 1;
      den = ener_exc + L_tmp;
      if (L_tmp_e < DFRACT_BITS - 1) {
        den += scaleValue(FL2FXCONST_DBL(0.01f), -L_tmp_e - 1);
      }
    }
    num = (ener_exc - L_tmp);
    num >>= SF_PFAC;

    if (den > (FIXP_DBL)0) {
      if (ener_exc > L_tmp) {
        period_fac = schur_div(num, den, 16);
      } else {
        period_fac = -schur_div(-num, den, 16);
      }
    } else {
      period_fac = (FIXP_DBL)MAXVAL_DBL;
    }
  }

  /* exponent = SF_PFAC */
  return period_fac;
}

/*------------------------------------------------------------*
 * noise enhancer                                             *
 * ~~~~~~~~~~~~~~                                             *
 * - Enhance excitation on noise. (modify gain of code)       *
 *   If signal is noisy and LPC filter is stable, move gain   *
 *   of code 1.5 dB toward gain of code threshold.            *
 *   This decrease by 3 dB noise energy variation.            *
 *------------------------------------------------------------*/
/**
 * \brief Enhance excitation on noise. (modify gain of code)
 * \param[in] gain_code Quantized codebook gain g_c, exponent = SF_GAIN_C.
 * \param[in] period_fac periodicity factor, exponent = SF_PFAC.
 * \param[in] stab_fac stability factor, exponent = SF_STAB.
 * \param[in,out] p_gc_threshold modified gain of previous subframe.
 * \return gain_code smoothed gain of code g_sc, exponent = SF_GAIN_C.
 */
static FIXP_DBL
noise_enhancer(/* (o) : smoothed gain g_sc                     SF_GAIN_C */
               FIXP_DBL gain_code, /* (i) : Quantized codebook gain SF_GAIN_C */
               FIXP_DBL period_fac, /* (i) : periodicity factor (-1=unvoiced to
                                       1=voiced), SF_PFAC */
               FIXP_SGL stab_fac,   /* (i) : stability factor (0 <= ... < 1.0)
                                       SF_STAB   */
               FIXP_DBL
                   *p_gc_threshold) /* (io): gain of code threshold SF_GAIN_C */
{
  FIXP_DBL fac, L_tmp, gc_thres;

  gc_thres = *p_gc_threshold;

  L_tmp = gain_code;
  if (L_tmp < gc_thres) {
    L_tmp += fMultDiv2(gain_code,
                       FL2FXCONST_SGL(2.0 * 0.19f)); /* +1.5dB => *(1.0+0.19) */
    if (L_tmp > gc_thres) {
      L_tmp = gc_thres;
    }
  } else {
    L_tmp = fMult(gain_code,
                  FL2FXCONST_SGL(1.0f / 1.19f)); /* -1.5dB => *10^(-1.5/20) */
    if (L_tmp < gc_thres) {
      L_tmp = gc_thres;
    }
  }
  *p_gc_threshold = L_tmp;

  /* voicing factor     lambda = 0.5*(1-period_fac) */
  /* gain smoothing factor S_m = lambda*stab_fac  (=fac)
                               = 0.5(stab_fac - stab_fac * period_fac) */
  fac = (FX_SGL2FX_DBL(stab_fac) >> (SF_PFAC + 1)) -
        fMultDiv2(stab_fac, period_fac);
  /* fac_e = SF_PFAC + SF_STAB */
  FDK_ASSERT(fac >= (FIXP_DBL)0);

  /* gain_code = (float)((fac*tmp) + ((1.0-fac)*gain_code)); */
  gain_code = fMult(fac, L_tmp) -
              fMult(FL2FXCONST_DBL(-1.0f / (1 << (SF_PFAC + SF_STAB))) + fac,
                    gain_code);
  gain_code <<= (SF_PFAC + SF_STAB);

  return gain_code;
}

/**
 * \brief Update adaptive codebook u'(n) (exc)
 *        Enhance pitch of c(n) and build post-processed excitation u(n) (exc2)
 * \param[in] code innovative codevector c(n), exponent = SF_CODE.
 * \param[in,out] exc filtered adaptive codebook v(n), exponent = SF_EXC.
 * \param[in] gain_pit adaptive codebook gain, exponent = SF_GAIN_P.
 * \param[in] gain_code innovative codebook gain g_c, exponent = SF_GAIN_C.
 * \param[in] gain_code_smoothed smoothed innov. codebook gain g_sc, exponent =
 * SF_GAIN_C.
 * \param[in] period_fac periodicity factor r_v, exponent = SF_PFAC.
 * \param[out] exc2 post-processed excitation u(n), exponent = SF_EXC.
 */
void BuildAdaptiveExcitation(
    FIXP_COD code[],    /* (i) : algebraic codevector c(n)             Q9  */
    FIXP_DBL exc[],     /* (io): filtered adaptive codebook v(n)       Q15 */
    FIXP_SGL gain_pit,  /* (i) : adaptive codebook gain g_p            Q14 */
    FIXP_DBL gain_code, /* (i) : innovative codebook gain g_c          Q16 */
    FIXP_DBL gain_code_smoothed, /* (i) : smoothed innov. codebook gain g_sc
                                    Q16 */
    FIXP_DBL period_fac, /* (i) : periodicity factor r_v                Q15 */
    FIXP_DBL exc2[]      /* (o) : post-processed excitation u(n)        Q15 */
) {
/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
         If exc2[i] is written, code[i] will be destroyed!
*/
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)

  int i;
  FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;

  FIXP_COD code_i;
  FIXP_DBL cpe_code_smooth, cpe_code_smooth_prev;

  /* cpe = (1+r_v)/8 * 2 ; ( SF = -1) */
  cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);

  /* u'(n) */
  tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
  *exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);

  /* u(n) */
  code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
                     << SF; /* c(0) * g_sc */
  code_i = *code++;
  code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
  tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
  cpe_code_smooth = fMultDiv2(cpe, code_smooth);
  *exc2++ = tmp - cpe_code_smooth;
  cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);

  i = L_SUBFR - 2;
  do /* ARM926: 22 cycles per iteration */
  {
    /* u'(n) */
    tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
    *exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
    /* u(n) */
    tmp += code_smooth; /* += g_sc * c(i) */
    tmp -= cpe_code_smooth_prev;
    cpe_code_smooth_prev = cpe_code_smooth;
    code_i = *code++;
    code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
    cpe_code_smooth = fMultDiv2(cpe, code_smooth);
    *exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
  } while (--i != 0);

  /* u'(n) */
  tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
  *exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
  /* u(n) */
  tmp += code_smooth;
  tmp -= cpe_code_smooth_prev;
  *exc2++ = tmp;

  return;
}

/**
 * \brief Interpolate LPC vector in LSP domain for current subframe and convert
 * to LP domain
 * \param[in] lsp_old LPC vector (LSP domain) corresponding to the beginning of
 * current ACELP frame.
 * \param[in] lsp_new LPC vector (LSP domain) corresponding to the end of
 * current ACELP frame.
 * \param[in] subfr_nr number of current ACELP subframe 0..3.
 * \param[in] nb_subfr total number of ACELP subframes in this frame.
 * \param[out] A LP filter coefficients for current ACELP subframe, exponent =
 * SF_A_COEFFS.
 */
/* static */
void int_lpc_acelp(
    const FIXP_LPC lsp_old[], /* input : LSPs from past frame              */
    const FIXP_LPC lsp_new[], /* input : LSPs from present frame           */
    int subfr_nr, int nb_subfr,
    FIXP_LPC
        A[], /* output: interpolated LP coefficients for current subframe */
    INT *A_exp) {
  int i;
  FIXP_LPC lsp_interpol[M_LP_FILTER_ORDER];
  FIXP_SGL fac_old, fac_new;

  FDK_ASSERT((nb_subfr == 3) || (nb_subfr == 4));

  fac_old = lsp_interpol_factor[nb_subfr & 0x1][(nb_subfr - 1) - subfr_nr];
  fac_new = lsp_interpol_factor[nb_subfr & 0x1][subfr_nr];
  for (i = 0; i < M_LP_FILTER_ORDER; i++) {
    lsp_interpol[i] = FX_DBL2FX_LPC(
        (fMultDiv2(lsp_old[i], fac_old) + fMultDiv2(lsp_new[i], fac_new)) << 1);
  }

  E_LPC_f_lsp_a_conversion(lsp_interpol, A, A_exp);

  return;
}

/**
 * \brief Perform LP synthesis by filtering the post-processed excitation u(n)
 *        through the LP synthesis filter 1/A(z)
 * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS.
 * \param[in] length length of input/output signal.
 * \param[in] x post-processed excitation u(n).
 * \param[in,out] y LP synthesis signal and filter memory
 * y[-M_LP_FILTER_ORDER..-1].
 */

/* static */
void Syn_filt(const FIXP_LPC a[], /* (i) : a[m] prediction coefficients Q12 */
              const INT a_exp,
              INT length,   /* (i) : length of input/output signal (64|128)   */
              FIXP_DBL x[], /* (i) : input signal Qx  */
              FIXP_DBL y[]  /* (i/o) : filter states / output signal  Qx-s*/
) {
  int i, j;
  FIXP_DBL L_tmp;

  for (i = 0; i < length; i++) {
    L_tmp = (FIXP_DBL)0;

    for (j = 0; j < M_LP_FILTER_ORDER; j++) {
      L_tmp -= fMultDiv2(a[j], y[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
    }

    L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
    y[i] = fAddSaturate(L_tmp, x[i]);
  }

  return;
}

/**
 * \brief Calculate de-emphasis 1/(1 - mu z^-1) on input signal.
 * \param[in] x input signal.
 * \param[out] y output signal.
 * \param[in] L length of signal.
 * \param[in,out] mem memory (signal[-1]).
 */
/* static */
void Deemph(FIXP_DBL *x, FIXP_DBL *y, int L, FIXP_DBL *mem) {
  int i;
  FIXP_DBL yi = *mem;

  for (i = 0; i < L; i++) {
    FIXP_DBL xi = x[i] >> 1;
    xi = fMultAddDiv2(xi, PREEMPH_FAC, yi);
    yi = SATURATE_LEFT_SHIFT(xi, 1, 32);
    y[i] = yi;
  }
  *mem = yi;
  return;
}

/**
 * \brief Compute the LP residual by filtering the input speech through the
 * analysis filter A(z).
 * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS
 * \param[in] x input signal (note that values x[-m..-1] are needed), exponent =
 * SF_SYNTH
 * \param[out] y output signal (residual), exponent = SF_EXC
 * \param[in] l length of filtering
 */
/* static */
void E_UTIL_residu(const FIXP_LPC *a, const INT a_exp, FIXP_DBL *x, FIXP_DBL *y,
                   INT l) {
  FIXP_DBL s;
  INT i, j;

  /* (note that values x[-m..-1] are needed) */
  for (i = 0; i < l; i++) {
    s = (FIXP_DBL)0;

    for (j = 0; j < M_LP_FILTER_ORDER; j++) {
      s += fMultDiv2(a[j], x[i - j - 1]) >> (LP_FILTER_SCALE - 1);
    }

    s = scaleValue(s, a_exp + LP_FILTER_SCALE);
    y[i] = fAddSaturate(s, x[i]);
  }

  return;
}

/* use to map subfr number to number of bits used for acb_index */
static const UCHAR num_acb_idx_bits_table[2][NB_SUBFR] = {
    {9, 6, 9, 6}, /* coreCoderFrameLength == 1024 */
    {9, 6, 6, 0}  /* coreCoderFrameLength == 768  */
};

static int DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,
                          const UCHAR num_acb_idx_bits,
                          const int PIT_MIN, /* TMIN */
                          const int PIT_FR2, /* TFR2 */
                          const int PIT_FR1, /* TFR1 */
                          const int PIT_MAX, /* TMAX */
                          int *pT0, int *pT0_frac, int *pT0_min, int *pT0_max) {
  int acb_idx;
  int error = 0;
  int T0, T0_frac;

  FDK_ASSERT((num_acb_idx_bits == 9) || (num_acb_idx_bits == 6));

  acb_idx = FDKreadBits(hBs, num_acb_idx_bits);

  if (num_acb_idx_bits == 6) {
    /* When the pitch value is encoded on 6 bits, a pitch resolution of 1/4 is
       always used in the range [T1-8, T1+7.75], where T1 is nearest integer to
       the fractional pitch lag of the previous subframe.
    */
    T0 = *pT0_min + acb_idx / 4;
    T0_frac = acb_idx & 0x3;
  } else { /* num_acb_idx_bits == 9 */
    /* When the pitch value is encoded on 9 bits, a fractional pitch delay is
       used with resolutions 0.25 in the range [TMIN, TFR2-0.25], resolutions
       0.5 in the range [TFR2, TFR1-0.5], and integers only in the range [TFR1,
       TMAX]. NOTE: for small sampling rates TMAX can get smaller than TFR1.
    */
    int T0_min, T0_max;

    if (acb_idx < (PIT_FR2 - PIT_MIN) * 4) {
      /* first interval with 0.25 pitch resolution */
      T0 = PIT_MIN + (acb_idx / 4);
      T0_frac = acb_idx & 0x3;
    } else if (acb_idx < ((PIT_FR2 - PIT_MIN) * 4 + (PIT_FR1 - PIT_FR2) * 2)) {
      /* second interval with 0.5 pitch resolution */
      acb_idx -= (PIT_FR2 - PIT_MIN) * 4;
      T0 = PIT_FR2 + (acb_idx / 2);
      T0_frac = (acb_idx & 0x1) * 2;
    } else {
      /* third interval with 1.0 pitch resolution */
      T0 = acb_idx + PIT_FR1 - ((PIT_FR2 - PIT_MIN) * 4) -
           ((PIT_FR1 - PIT_FR2) * 2);
      T0_frac = 0;
    }
    /* find T0_min and T0_max for subframe 1 or 3 */
    T0_min = T0 - 8;
    if (T0_min < PIT_MIN) {
      T0_min = PIT_MIN;
    }
    T0_max = T0_min + 15;
    if (T0_max > PIT_MAX) {
      T0_max = PIT_MAX;
      T0_min = T0_max - 15;
    }
    *pT0_min = T0_min;
    *pT0_max = T0_max;
  }
  *pT0 = T0;
  *pT0_frac = T0_frac;

  return error;
}
static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,
                            int *pT0, int *pT0_frac) {
  USHORT *pold_T0 = &acelp_mem->old_T0;
  UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;

  if ((int)*pold_T0 >= PIT_MAX) {
    *pold_T0 = (UCHAR)(PIT_MAX - 5);
  }
  *pT0 = (int)*pold_T0;
  *pT0_frac = (int)*pold_T0_frac;
}

static UCHAR tab_coremode2nbits[8] = {20, 28, 36, 44, 52, 64, 12, 16};

static int MapCoreMode2NBits(int core_mode) {
  return (int)tab_coremode2nbits[core_mode];
}

void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
                      const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
                      const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
                      FIXP_SGL stab_fac, CAcelpChannelData *pAcelpData,
                      INT numLostSubframes, int lastLpcLost, int frameCnt,
                      FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
                      INT coreCoderFrameLength) {
  int i_subfr, subfr_nr, l_div, T;
  int T0 = -1, T0_frac = -1; /* mark invalid */

  int pit_gain_index = 0;

  const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset); /* maximum pitch lag */

  FIXP_COD *code;
  FIXP_DBL *exc2;
  FIXP_DBL *syn;
  FIXP_DBL *exc;
  FIXP_LPC A[M_LP_FILTER_ORDER];
  INT A_exp;

  FIXP_DBL period_fac;
  FIXP_SGL gain_pit;
  FIXP_DBL gain_code, gain_code_smooth, Ener_code;
  int Ener_code_e;
  int n;
  int bfi = (numLostSubframes > 0) ? 1 : 0;

  C_ALLOC_SCRATCH_START(
      exc_buf, FIXP_DBL,
      PIT_MAX_MAX + L_INTERPOL + L_DIV + 1); /* 411 + 17 + 256 + 1 = 685 */
  C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
                        M_LP_FILTER_ORDER + L_DIV); /* 16 + 256 = 272 */
  /* use same memory for code[L_SUBFR] and exc2[L_SUBFR] */
  C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_SUBFR); /* 64 */
  /* make sure they don't overlap if they are accessed alternatingly in
   * BuildAdaptiveExcitation() */
#if (COD_BITS == FRACT_BITS)
  code = (FIXP_COD *)(tmp_buf + L_SUBFR / 2);
#elif (COD_BITS == DFRACT_BITS)
  code = (FIXP_COD *)tmp_buf;
#endif
  exc2 = (FIXP_DBL *)tmp_buf;

  syn = syn_buf + M_LP_FILTER_ORDER;
  exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;

  FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
  FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
            (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));

  FDKmemclear(exc_buf + (PIT_MAX_MAX + L_INTERPOL),
              (L_DIV + 1) * sizeof(FIXP_DBL));

  l_div = coreCoderFrameLength / NB_DIV;

  for (i_subfr = 0, subfr_nr = 0; i_subfr < l_div;
       i_subfr += L_SUBFR, subfr_nr++) {
    /*-------------------------------------------------*
     * - Decode pitch lag (T0 and T0_frac)             *
     *-------------------------------------------------*/
    if (bfi) {
      ConcealPitchLag(acelp_mem, PIT_MAX, &T0, &T0_frac);
    } else {
      T0 = (int)pAcelpData->T0[subfr_nr];
      T0_frac = (int)pAcelpData->T0_frac[subfr_nr];
    }

    /*-------------------------------------------------*
     * - Find the pitch gain, the interpolation filter *
     *   and the adaptive codebook vector.             *
     *-------------------------------------------------*/
    Pred_lt4(&exc[i_subfr], T0, T0_frac);

    if ((!bfi && pAcelpData->ltp_filtering_flag[subfr_nr] == 0) ||
        (bfi && numLostSubframes == 1 && stab_fac < FL2FXCONST_SGL(0.25f))) {
      /* find pitch excitation with lp filter: v'(n) => v(n) */
      Pred_lt4_postfilter(&exc[i_subfr]);
    }

    /*-------------------------------------------------------*
     * - Decode innovative codebook.                         *
     * - Add the fixed-gain pitch contribution to code[].    *
     *-------------------------------------------------------*/
    if (bfi) {
      for (n = 0; n < L_SUBFR; n++) {
        code[n] =
            FX_SGL2FX_COD((FIXP_SGL)E_UTIL_random(&acelp_mem->seed_ace)) >> 4;
      }
    } else {
      int nbits = MapCoreMode2NBits((int)pAcelpData->acelp_core_mode);
      D_ACELP_decode_4t64(pAcelpData->icb_index[subfr_nr], nbits, &code[0]);
    }

    T = T0;
    if (T0_frac > 2) {
      T += 1;
    }

    Preemph_code(code);
    Pit_shrp(code, T);

    /* Output pitch lag for bass post-filter */
    if (T > PIT_MAX) {
      pT[subfr_nr] = PIT_MAX;
    } else {
      pT[subfr_nr] = T;
    }
    D_gain2_plus(
        pAcelpData->gains[subfr_nr],
        code,       /* (i)  : Innovative code vector, exponent = SF_CODE */
        &gain_pit,  /* (o)  : Quantized pitch gain, exponent = SF_GAIN_P */
        &gain_code, /* (o)  : Quantized codebook gain                    */
        pAcelpData
            ->mean_energy, /* (i)  : mean_ener defined in open-loop (2 bits) */
        bfi, &acelp_mem->past_gpit, &acelp_mem->past_gcode,
        &Ener_code,    /* (o)  : Innovative code vector energy              */
        &Ener_code_e); /* (o)  : Innovative code vector energy exponent     */

    pit_gain[pit_gain_index++] = FX_SGL2FX_DBL(gain_pit);

    /* calc periodicity factor r_v */
    period_fac =
        calc_period_factor(/* (o) : factor (-1=unvoiced to 1=voiced)    */
                           &exc[i_subfr], /* (i) : pitch excitation, exponent =
                                             SF_EXC */
                           gain_pit,      /* (i) : gain of pitch, exponent =
                                             SF_GAIN_P */
                           gain_code,     /* (i) : gain of code     */
                           Ener_code,     /* (i) : Energy of code[]     */
                           Ener_code_e);  /* (i) : Exponent of energy of code[]
                                           */

    if (lastLpcLost && frameCnt == 0) {
      if (gain_pit > FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P))) {
        gain_pit = FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P));
      }
    }

    gain_code_smooth =
        noise_enhancer(/* (o) : smoothed gain g_sc exponent = SF_GAIN_C */
                       gain_code,  /* (i) : Quantized codebook gain  */
                       period_fac, /* (i) : periodicity factor (-1=unvoiced to
                                      1=voiced)  */
                       stab_fac,   /* (i) : stability factor (0 <= ... < 1),
                                      exponent = 1 */
                       &acelp_mem->gc_threshold);

    /* Compute adaptive codebook update u'(n), pitch enhancement c'(n) and
     * post-processed excitation u(n). */
    BuildAdaptiveExcitation(code, exc + i_subfr, gain_pit, gain_code,
                            gain_code_smooth, period_fac, exc2);

    /* Interpolate filter coeffs for current subframe in lsp domain and convert
     * to LP domain */
    int_lpc_acelp(lsp_old,  /* input : LSPs from past frame              */
                  lsp_new,  /* input : LSPs from present frame           */
                  subfr_nr, /* input : ACELP subframe index              */
                  coreCoderFrameLength / L_DIV,
                  A, /* output: LP coefficients of this subframe  */
                  &A_exp);

    Syn_filt(A, /* (i) : a[m] prediction coefficients               */
             A_exp, L_SUBFR, /* (i) : length */
             exc2, /* (i) : input signal                               */
             &syn[i_subfr] /* (i/o) : filter states / output signal */
    );

  } /* end of subframe loop */

  /* update pitch value for bfi procedure */
  acelp_mem->old_T0_frac = T0_frac;
  acelp_mem->old_T0 = T0;

  /* save old excitation and old synthesis memory for next ACELP frame */
  FDKmemcpy(acelp_mem->old_exc_mem, exc + l_div - (PIT_MAX_MAX + L_INTERPOL),
            sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
  FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + l_div,
            sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);

  Deemph(syn, synth, l_div,
         &acelp_mem->de_emph_mem); /* ref soft: mem = synth[-1] */

  scaleValues(synth, l_div, -ACELP_OUTSCALE);
  acelp_mem->deemph_mem_wsyn = acelp_mem->de_emph_mem;

  C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_SUBFR);
  C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
  C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV + 1);
  return;
}

void CLpd_AcelpReset(CAcelpStaticMem *acelp) {
  acelp->gc_threshold = (FIXP_DBL)0;

  acelp->past_gpit = (FIXP_SGL)0;
  acelp->past_gcode = (FIXP_DBL)0;
  acelp->old_T0 = 64;
  acelp->old_T0_frac = 0;
  acelp->deemph_mem_wsyn = (FIXP_DBL)0;
  acelp->wsyn_rms = (FIXP_DBL)0;
  acelp->seed_ace = 0;
}

/* TCX time domain concealment */
/*   Compare to figure 13a on page 54 in 3GPP TS 26.290 */
void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
                       const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
                       const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
                       const FIXP_SGL stab_fac, INT nLostSf, FIXP_DBL synth[],
                       INT coreCoderFrameLength, UCHAR last_tcx_noise_factor) {
  /* repeat past excitation with pitch from previous decoded TCX frame */
  C_ALLOC_SCRATCH_START(
      exc_buf, FIXP_DBL,
      PIT_MAX_MAX + L_INTERPOL + L_DIV); /* 411 +  17 + 256 + 1 =  */
  C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
                        M_LP_FILTER_ORDER + L_DIV); /* 256 +  16           =  */
                                                    /*                    +=  */
  FIXP_DBL ns_buf[L_DIV + 1];
  FIXP_DBL *syn = syn_buf + M_LP_FILTER_ORDER;
  FIXP_DBL *exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
  FIXP_DBL *ns = ns_buf + 1;
  FIXP_DBL tmp, fact_exc;
  INT T = fMin(*pitch, (SHORT)PIT_MAX_MAX);
  int i, i_subfr, subfr_nr;
  int lDiv = coreCoderFrameLength / NB_DIV;

  FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
  FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
            (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));

  /* if we lost all packets (i.e. 1 packet of TCX-20 ms, 2 packets of
     the TCX-40 ms or 4 packets of the TCX-80ms), we lost the whole
     coded frame extrapolation strategy: repeat lost excitation and
     use extrapolated LSFs */

  /* AMR-WB+ like TCX TD concealment */

  /* number of lost frame cmpt */
  if (nLostSf < 2) {
    fact_exc = FL2FXCONST_DBL(0.8f);
  } else {
    fact_exc = FL2FXCONST_DBL(0.4f);
  }

  /* repeat past excitation */
  for (i = 0; i < lDiv; i++) {
    exc[i] = fMult(fact_exc, exc[i - T]);
  }

  tmp = fMult(fact_exc, acelp_mem->wsyn_rms);
  acelp_mem->wsyn_rms = tmp;

  /* init deemph_mem_wsyn */
  acelp_mem->deemph_mem_wsyn = exc[-1];

  ns[-1] = acelp_mem->deemph_mem_wsyn;

  for (i_subfr = 0, subfr_nr = 0; i_subfr < lDiv;
       i_subfr += L_SUBFR, subfr_nr++) {
    FIXP_DBL tRes[L_SUBFR];
    FIXP_LPC A[M_LP_FILTER_ORDER];
    INT A_exp;

    /* interpolate LPC coefficients */
    int_lpc_acelp(lsp_old, lsp_new, subfr_nr, lDiv / L_SUBFR, A, &A_exp);

    Syn_filt(A,              /* (i) : a[m] prediction coefficients         */
             A_exp, L_SUBFR, /* (i) : length                               */
             &exc[i_subfr],  /* (i) : input signal                         */
             &syn[i_subfr]   /* (i/o) : filter states / output signal      */
    );

    E_LPC_a_weight(
        A, A,
        M_LP_FILTER_ORDER); /* overwrite A as it is not needed any longer */

    E_UTIL_residu(A, A_exp, &syn[i_subfr], tRes, L_SUBFR);

    Deemph(tRes, &ns[i_subfr], L_SUBFR, &acelp_mem->deemph_mem_wsyn);

    /* Amplitude limiter (saturate at wsyn_rms) */
    for (i = i_subfr; i < i_subfr + L_SUBFR; i++) {
      if (ns[i] > tmp) {
        ns[i] = tmp;
      } else {
        if (ns[i] < -tmp) {
          ns[i] = -tmp;
        }
      }
    }

    E_UTIL_preemph(&ns[i_subfr], tRes, L_SUBFR);

    Syn_filt(A,              /* (i) : a[m] prediction coefficients         */
             A_exp, L_SUBFR, /* (i) : length                               */
             tRes,           /* (i) : input signal                         */
             &syn[i_subfr]   /* (i/o) : filter states / output signal      */
    );

    FDKmemmove(&synth[i_subfr], &syn[i_subfr], L_SUBFR * sizeof(FIXP_DBL));
  }

  /* save old excitation and old synthesis memory for next ACELP frame */
  FDKmemcpy(acelp_mem->old_exc_mem, exc + lDiv - (PIT_MAX_MAX + L_INTERPOL),
            sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
  FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + lDiv,
            sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
  acelp_mem->de_emph_mem = acelp_mem->deemph_mem_wsyn;

  C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
  C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV);
}

void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
                         INT *old_T_pf, FIXP_DBL *pit_gain,
                         FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
                         INT coreCoderFrameLength, INT synSfd,
                         INT nbSubfrSuperfr) {
  int n;

  /* init beginning of synth_buf with old synthesis from previous frame */
  FDKmemcpy(synth_buf, old_synth, sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));

  /* calculate pitch lag offset for ACELP decoder */
  *i_offset =
      (samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
      PIT_MIN_12k8;

  /* for bass postfilter */
  for (n = 0; n < synSfd; n++) {
    pitch[n] = old_T_pf[n];
    pit_gain[n] = old_gain_pf[n];
  }
  for (n = 0; n < nbSubfrSuperfr; n++) {
    pitch[n + synSfd] = L_SUBFR;
    pit_gain[n + synSfd] = (FIXP_DBL)0;
  }
}

void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
                          INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
                          INT nbSubfrSuperfr) {
  int n;

  /* store last part of synth_buf (which is not handled by the IMDCT overlap)
   * for next frame */
  FDKmemcpy(old_synth, synth_buf + coreCoderFrameLength,
            sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));

  /* for bass postfilter */
  for (n = 0; n < synSfd; n++) {
    old_T_pf[n] = pitch[nbSubfrSuperfr + n];
  }
}

#define L_FAC_ZIR (LFAC)

void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
                    CAcelpStaticMem *acelp_mem, const INT length,
                    FIXP_DBL zir[], int doDeemph) {
  C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
  FDK_ASSERT(length <= L_FAC_ZIR);

  FDKmemcpy(tmp_buf, acelp_mem->old_syn_mem,
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
  FDKmemset(tmp_buf + M_LP_FILTER_ORDER, 0, L_FAC_ZIR * sizeof(FIXP_DBL));

  Syn_filt(A, A_exp, length, &tmp_buf[M_LP_FILTER_ORDER],
           &tmp_buf[M_LP_FILTER_ORDER]);
  if (!doDeemph) {
    /* if last lpd mode was TD concealment, then bypass deemph */
    FDKmemcpy(zir, tmp_buf, length * sizeof(*zir));
  } else {
    Deemph(&tmp_buf[M_LP_FILTER_ORDER], &zir[0], length,
           &acelp_mem->de_emph_mem);
    scaleValues(zir, length, -ACELP_OUTSCALE);
  }
  C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
}

void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
                                  UCHAR last_last_lpd_mode,
                                  const FIXP_LPC *A_new, const INT A_new_exp,
                                  const FIXP_LPC *A_old, const INT A_old_exp,
                                  CAcelpStaticMem *acelp_mem,
                                  INT coreCoderFrameLength, INT clearOldExc,
                                  UCHAR lpd_mode) {
  int l_div =
      coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */
  int l_div_partial;
  FIXP_DBL *syn, *old_exc_mem;

  C_ALLOC_SCRATCH_START(synth_buf, FIXP_DBL,
                        PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
  syn = &synth_buf[M_LP_FILTER_ORDER];

  l_div_partial = PIT_MAX_MAX + L_INTERPOL - l_div;
  old_exc_mem = acelp_mem->old_exc_mem;

  if (lpd_mode == 4) {
    /* Bypass Domain conversion. TCXTD Concealment does no deemphasis in the
     * end. */
    FDKmemcpy(
        synth_buf, &synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
        (PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER) * sizeof(FIXP_DBL));
    /* Set deemphasis memory state for TD concealment */
    acelp_mem->deemph_mem_wsyn = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
  } else {
    /* convert past [PIT_MAX_MAX+L_INTERPOL+M_LP_FILTER_ORDER] synthesis to
     * preemph domain */
    E_UTIL_preemph(&synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
                   synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
    scaleValuesSaturate(synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER,
                        ACELP_OUTSCALE);
  }

  /* Set deemphasis memory state */
  acelp_mem->de_emph_mem = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);

  /* update acelp synth filter memory */
  FDKmemcpy(acelp_mem->old_syn_mem,
            &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER],
            M_LP_FILTER_ORDER * sizeof(FIXP_DBL));

  if (clearOldExc) {
    FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
    C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
                        PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
    return;
  }

  /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */
  if (last_lpd_mode == 1) {        /* last frame was TCX20 */
    if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */
      /* Delay valid part of excitation buffer (from previous ACELP frame) by
       * l_div samples */
      FDKmemmove(old_exc_mem, old_exc_mem + l_div,
                 sizeof(FIXP_DBL) * l_div_partial);
    } else if (last_last_lpd_mode > 0) { /* TCX -> TCX20 -> ACELP transition */
      E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, l_div_partial);
    }
    E_UTIL_residu(A_new, A_new_exp, syn + l_div_partial,
                  old_exc_mem + l_div_partial, l_div);
  } else { /* prev frame was FD, TCX40 or TCX80 */
    int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL)
                               ? PIT_MAX_MAX + L_INTERPOL
                               : coreCoderFrameLength / 2;
    int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length;
    E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length);
    E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length],
                  &old_exc_mem[exc_A_old_length], exc_A_new_length);
  }
  C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
                      PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);

  return;
}

FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length) {
  FDK_ASSERT(length <= PIT_MAX_MAX + L_INTERPOL);
  return acelp_mem->old_exc_mem;
}

INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelp,
                   INT acelp_core_mode, INT coreCoderFrameLength,
                   INT i_offset) {
  int nb_subfr = coreCoderFrameLength / L_DIV;
  const UCHAR *num_acb_index_bits =
      (nb_subfr == 4) ? num_acb_idx_bits_table[0] : num_acb_idx_bits_table[1];
  int nbits;
  int error = 0;

  const int PIT_MIN = PIT_MIN_12k8 + i_offset;
  const int PIT_FR2 = PIT_FR2_12k8 - i_offset;
  const int PIT_FR1 = PIT_FR1_12k8;
  const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset);
  int T0, T0_frac, T0_min = 0, T0_max;

  if (PIT_MAX > PIT_MAX_MAX) {
    error = AAC_DEC_DECODE_FRAME_ERROR;
    goto bail;
  }

  acelp->acelp_core_mode = acelp_core_mode;

  nbits = MapCoreMode2NBits(acelp_core_mode);

  /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */
  acelp->mean_energy = FDKreadBits(hBs, 2);

  for (int sfr = 0; sfr < nb_subfr; sfr++) {
    /* read ACB index and store T0 and T0_frac for each ACELP subframe. */
    error = DecodePitchLag(hBs, num_acb_index_bits[sfr], PIT_MIN, PIT_FR2,
                           PIT_FR1, PIT_MAX, &T0, &T0_frac, &T0_min, &T0_max);
    if (error) {
      goto bail;
    }
    acelp->T0[sfr] = (USHORT)T0;
    acelp->T0_frac[sfr] = (UCHAR)T0_frac;
    acelp->ltp_filtering_flag[sfr] = FDKreadBits(hBs, 1);
    switch (nbits) {
      case 12: /* 12 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 1);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
        break;
      case 16: /* 16 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
        break;
      case 20: /* 20 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 5);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
        break;
      case 28: /* 28 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
        break;
      case 36: /* 36 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
        break;
      case 44: /* 44 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
        break;
      case 52: /* 52 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 13);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 13);
        break;
      case 64: /* 64 bits AMR-WB codebook is used */
        acelp->icb_index[sfr][0] = FDKreadBits(hBs, 2);
        acelp->icb_index[sfr][1] = FDKreadBits(hBs, 2);
        acelp->icb_index[sfr][2] = FDKreadBits(hBs, 2);
        acelp->icb_index[sfr][3] = FDKreadBits(hBs, 2);
        acelp->icb_index[sfr][4] = FDKreadBits(hBs, 14);
        acelp->icb_index[sfr][5] = FDKreadBits(hBs, 14);
        acelp->icb_index[sfr][6] = FDKreadBits(hBs, 14);
        acelp->icb_index[sfr][7] = FDKreadBits(hBs, 14);
        break;
      default:
        FDK_ASSERT(0);
        break;
    }
    acelp->gains[sfr] = FDKreadBits(hBs, 7);
  }

bail:
  return error;
}
