/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2019 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] = fAddSaturate(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_HEADROOM (1)
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC - SF_HEADROOM)
#define SF_GAIN_P2 (SF_GAIN_P - SF_HEADROOM)

  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_P2 + 1); /* v(0)*g_p */
  *exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM;

  /* 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) << SF_HEADROOM;
  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_P2 + 1);
    *exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
    /* 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)
              << SF_HEADROOM; /* tmp - c_pe * g_sc * c(i+1) */
  } while (--i != 0);

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

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