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