Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten
      5 Forschung e.V. All rights reserved.
      6 
      7  1.    INTRODUCTION
      8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
      9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
     10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
     11 a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
     14 general perceptual audio codecs. AAC-ELD is considered the best-performing
     15 full-bandwidth communications codec by independent studies and is widely
     16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
     17 specifications.
     18 
     19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
     20 those of Fraunhofer) may be obtained through Via Licensing
     21 (www.vialicensing.com) or through the respective patent owners individually for
     22 the purpose of encoding or decoding bit streams in products that are compliant
     23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
     24 Android devices already license these patent claims through Via Licensing or
     25 directly from the patent owners, and therefore FDK AAC Codec software may
     26 already be covered under those patent licenses when it is used for those
     27 licensed purposes only.
     28 
     29 Commercially-licensed AAC software libraries, including floating-point versions
     30 with enhanced sound quality, are also available from Fraunhofer. Users are
     31 encouraged to check the Fraunhofer website for additional applications
     32 information and documentation.
     33 
     34 2.    COPYRIGHT LICENSE
     35 
     36 Redistribution and use in source and binary forms, with or without modification,
     37 are permitted without payment of copyright license fees provided that you
     38 satisfy the following conditions:
     39 
     40 You must retain the complete text of this software license in redistributions of
     41 the FDK AAC Codec or your modifications thereto in source code form.
     42 
     43 You must retain the complete text of this software license in the documentation
     44 and/or other materials provided with redistributions of the FDK AAC Codec or
     45 your modifications thereto in binary form. You must make available free of
     46 charge copies of the complete source code of the FDK AAC Codec and your
     47 modifications thereto to recipients of copies in binary form.
     48 
     49 The name of Fraunhofer may not be used to endorse or promote products derived
     50 from this library without prior written permission.
     51 
     52 You may not charge copyright license fees for anyone to use, copy or distribute
     53 the FDK AAC Codec software or your modifications thereto.
     54 
     55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
     56 that you changed the software and the date of any change. For modified versions
     57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
     58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
     59 AAC Codec Library for Android."
     60 
     61 3.    NO PATENT LICENSE
     62 
     63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
     64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
     65 Fraunhofer provides no warranty of patent non-infringement with respect to this
     66 software.
     67 
     68 You may use this FDK AAC Codec software or modifications thereto only for
     69 purposes that are authorized by appropriate patent licenses.
     70 
     71 4.    DISCLAIMER
     72 
     73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
     74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
     75 including but not limited to the implied warranties of merchantability and
     76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
     78 or consequential damages, including but not limited to procurement of substitute
     79 goods or services; loss of use, data, or profits, or business interruption,
     80 however caused and on any theory of liability, whether in contract, strict
     81 liability, or tort (including negligence), arising in any way out of the use of
     82 this software, even if advised of the possibility of such damage.
     83 
     84 5.    CONTACT INFORMATION
     85 
     86 Fraunhofer Institute for Integrated Circuits IIS
     87 Attention: Audio and Multimedia Departments - FDK AAC LL
     88 Am Wolfsmantel 33
     89 91058 Erlangen, Germany
     90 
     91 www.iis.fraunhofer.de/amm
     92 amm-info (at) iis.fraunhofer.de
     93 ----------------------------------------------------------------------------- */
     94 
     95 /**************************** AAC decoder library ******************************
     96 
     97    Author(s):   Matthias Hildenbrand
     98 
     99    Description: USAC ACELP frame decoder
    100 
    101 *******************************************************************************/
    102 
    103 #include "usacdec_acelp.h"
    104 
    105 #include "usacdec_ace_d4t64.h"
    106 #include "usacdec_ace_ltp.h"
    107 #include "usacdec_rom.h"
    108 #include "usacdec_lpc.h"
    109 #include "genericStds.h"
    110 
    111 #define PIT_FR2_12k8 128 /* Minimum pitch lag with resolution 1/2      */
    112 #define PIT_FR1_12k8 160 /* Minimum pitch lag with resolution 1        */
    113 #define TILT_CODE2 \
    114   FL2FXCONST_SGL(0.3f * 2.0f) /* ACELP code pre-emphasis factor ( *2 )      */
    115 #define PIT_SHARP \
    116   FL2FXCONST_SGL(0.85f) /* pitch sharpening factor                    */
    117 #define PREEMPH_FAC \
    118   FL2FXCONST_SGL(0.68f) /* ACELP synth pre-emphasis factor            */
    119 
    120 #define ACELP_HEADROOM 1
    121 #define ACELP_OUTSCALE (MDCT_OUT_HEADROOM - ACELP_HEADROOM)
    122 
    123 /**
    124  * \brief Calculate pre-emphasis (1 - mu z^-1) on input signal.
    125  * \param[in] in pointer to input signal; in[-1] is also needed.
    126  * \param[out] out pointer to output signal.
    127  * \param[in] L length of filtering.
    128  */
    129 /* static */
    130 void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
    131   int i;
    132 
    133   for (i = 0; i < L; i++) {
    134     out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]);
    135   }
    136 
    137   return;
    138 }
    139 
    140 /**
    141  * \brief Calculate de-emphasis 1/(1 - TILT_CODE z^-1) on innovative codebook
    142  * vector.
    143  * \param[in,out] x innovative codebook vector.
    144  */
    145 static void Preemph_code(
    146     FIXP_COD x[] /* (i/o)   : input signal overwritten by the output */
    147 ) {
    148   int i;
    149   FIXP_DBL L_tmp;
    150 
    151   /* ARM926: 12 cycles per sample */
    152   for (i = L_SUBFR - 1; i > 0; i--) {
    153     L_tmp = FX_COD2FX_DBL(x[i]);
    154     L_tmp -= fMultDiv2(x[i - 1], TILT_CODE2);
    155     x[i] = FX_DBL2FX_COD(L_tmp);
    156   }
    157 }
    158 
    159 /**
    160  * \brief Apply pitch sharpener to the innovative codebook vector.
    161  * \param[in,out] x innovative codebook vector.
    162  * \param[in] pit_lag decoded pitch lag.
    163  */
    164 static void Pit_shrp(
    165     FIXP_COD x[], /* in/out: impulse response (or algebraic code) */
    166     int pit_lag   /* input : pitch lag                            */
    167 ) {
    168   int i;
    169   FIXP_DBL L_tmp;
    170 
    171   for (i = pit_lag; i < L_SUBFR; i++) {
    172     L_tmp = FX_COD2FX_DBL(x[i]);
    173     L_tmp += fMult(x[i - pit_lag], PIT_SHARP);
    174     x[i] = FX_DBL2FX_COD(L_tmp);
    175   }
    176 
    177   return;
    178 }
    179 
    180   /**
    181    * \brief Calculate Quantized codebook gain, Quantized pitch gain and unbiased
    182    *        Innovative code vector energy.
    183    * \param[in] index index of quantizer.
    184    * \param[in] code innovative code vector with exponent = SF_CODE.
    185    * \param[out] gain_pit Quantized pitch gain g_p with exponent = SF_GAIN_P.
    186    * \param[out] gain_code Quantized codebook gain g_c.
    187    * \param[in] mean_ener mean_ener defined in open-loop (2 bits), exponent = 7.
    188    * \param[out] E_code unbiased innovative code vector energy.
    189    * \param[out] E_code_e exponent of unbiased innovative code vector energy.
    190    */
    191 
    192 #define SF_MEAN_ENER_LG10 9
    193 
    194 /* pow(10.0, {18, 30, 42, 54}/20.0) /(float)(1<<SF_MEAN_ENER_LG10) */
    195 static const FIXP_DBL pow_10_mean_energy[4] = {0x01fc5ebd, 0x07e7db92,
    196                                                0x1f791f65, 0x7d4bfba3};
    197 
    198 static void D_gain2_plus(int index, FIXP_COD code[], FIXP_SGL *gain_pit,
    199                          FIXP_DBL *gain_code, int mean_ener_bits, int bfi,
    200                          FIXP_SGL *past_gpit, FIXP_DBL *past_gcode,
    201                          FIXP_DBL *pEner_code, int *pEner_code_e) {
    202   FIXP_DBL Ltmp;
    203   FIXP_DBL gcode0, gcode_inov;
    204   INT gcode0_e, gcode_inov_e;
    205   int i;
    206 
    207   FIXP_DBL ener_code;
    208   INT ener_code_e;
    209 
    210   /* ener_code = sum(code[]^2) */
    211   ener_code = FIXP_DBL(0);
    212   for (i = 0; i < L_SUBFR; i++) {
    213     ener_code += fPow2Div2(code[i]);
    214   }
    215 
    216   ener_code_e = fMax(fNorm(ener_code) - 1, 0);
    217   ener_code <<= ener_code_e;
    218   ener_code_e = 2 * SF_CODE + 1 - ener_code_e;
    219 
    220   /* export energy of code for calc_period_factor() */
    221   *pEner_code = ener_code;
    222   *pEner_code_e = ener_code_e;
    223 
    224   ener_code += scaleValue(FL2FXCONST_DBL(0.01f), -ener_code_e);
    225 
    226   /* ener_code *= 1/L_SUBFR, and make exponent even (because of square root
    227    * below). */
    228   if (ener_code_e & 1) {
    229     ener_code_e -= 5;
    230     ener_code >>= 1;
    231   } else {
    232     ener_code_e -= 6;
    233   }
    234   gcode_inov = invSqrtNorm2(ener_code, &gcode0_e);
    235   gcode_inov_e = gcode0_e - (ener_code_e >> 1);
    236 
    237   if (bfi) {
    238     FIXP_DBL tgcode;
    239     FIXP_SGL tgpit;
    240 
    241     tgpit = *past_gpit;
    242 
    243     if (tgpit > FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P))) {
    244       tgpit = FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P));
    245     } else if (tgpit < FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P))) {
    246       tgpit = FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P));
    247     }
    248     *gain_pit = tgpit;
    249     tgpit = FX_DBL2FX_SGL(fMult(tgpit, FL2FXCONST_DBL(0.95f)));
    250     *past_gpit = tgpit;
    251 
    252     tgpit = FL2FXCONST_SGL(1.4f / (1 << SF_GAIN_P)) - tgpit;
    253     tgcode = fMult(*past_gcode, tgpit) << SF_GAIN_P;
    254     *gain_code = scaleValue(fMult(tgcode, gcode_inov), gcode_inov_e);
    255     *past_gcode = tgcode;
    256 
    257     return;
    258   }
    259 
    260   /*-------------- Decode gains ---------------*/
    261   /*
    262    gcode0 = pow(10.0, (float)mean_ener/20.0);
    263    gcode0 = gcode0 / sqrt(ener_code/L_SUBFR);
    264    */
    265   gcode0 = pow_10_mean_energy[mean_ener_bits];
    266   gcode0 = fMultDiv2(gcode0, gcode_inov);
    267   gcode0_e = gcode0_e + SF_MEAN_ENER_LG10 - (ener_code_e >> 1) + 1;
    268 
    269   i = index << 1;
    270   *gain_pit = t_qua_gain7b[i]; /* adaptive codebook gain */
    271   /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */
    272   Ltmp = fMult(t_qua_gain7b[i + 1], gcode0);
    273   *gain_code = scaleValue(Ltmp, gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B);
    274 
    275   /* update bad frame handler */
    276   *past_gpit = *gain_pit;
    277 
    278   /*--------------------------------------------------------
    279     past_gcode  = gain_code/gcode_inov
    280    --------------------------------------------------------*/
    281   {
    282     FIXP_DBL gcode_m;
    283     INT gcode_e;
    284 
    285     gcode_m = fDivNormHighPrec(Ltmp, gcode_inov, &gcode_e);
    286     gcode_e += (gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B) - (gcode_inov_e);
    287     *past_gcode = scaleValue(gcode_m, gcode_e);
    288   }
    289 }
    290 
    291 /**
    292  * \brief Calculate period/voicing factor r_v
    293  * \param[in] exc pitch excitation.
    294  * \param[in] gain_pit gain of pitch g_p.
    295  * \param[in] gain_code gain of code g_c.
    296  * \param[in] gain_code_e exponent of gain of code.
    297  * \param[in] ener_code unbiased innovative code vector energy.
    298  * \param[in] ener_code_e exponent of unbiased innovative code vector energy.
    299  * \return period/voice factor r_v (-1=unvoiced to 1=voiced), exponent SF_PFAC.
    300  */
    301 static FIXP_DBL calc_period_factor(FIXP_DBL exc[], FIXP_SGL gain_pit,
    302                                    FIXP_DBL gain_code, FIXP_DBL ener_code,
    303                                    int ener_code_e) {
    304   int ener_exc_e, L_tmp_e, s = 0;
    305   FIXP_DBL ener_exc, L_tmp;
    306   FIXP_DBL period_fac;
    307 
    308   /* energy of pitch excitation */
    309   ener_exc = (FIXP_DBL)0;
    310   for (int i = 0; i < L_SUBFR; i++) {
    311     ener_exc += fPow2Div2(exc[i]) >> s;
    312     if (ener_exc > FL2FXCONST_DBL(0.5f)) {
    313       ener_exc >>= 1;
    314       s++;
    315     }
    316   }
    317 
    318   ener_exc_e = fNorm(ener_exc);
    319   ener_exc = fMult(ener_exc << ener_exc_e, fPow2(gain_pit));
    320   if (ener_exc != (FIXP_DBL)0) {
    321     ener_exc_e = 2 * SF_EXC + 1 + 2 * SF_GAIN_P - ener_exc_e + s;
    322   } else {
    323     ener_exc_e = 0;
    324   }
    325 
    326   /* energy of innovative code excitation */
    327   /* L_tmp = ener_code * gain_code*gain_code; */
    328   L_tmp_e = fNorm(gain_code);
    329   L_tmp = fPow2(gain_code << L_tmp_e);
    330   L_tmp = fMult(ener_code, L_tmp);
    331   L_tmp_e = 2 * SF_GAIN_C + ener_code_e - 2 * L_tmp_e;
    332 
    333   /* Find common exponent */
    334   {
    335     FIXP_DBL num, den;
    336     int exp_diff;
    337 
    338     exp_diff = ener_exc_e - L_tmp_e;
    339     if (exp_diff >= 0) {
    340       ener_exc >>= 1;
    341       if (exp_diff <= DFRACT_BITS - 2) {
    342         L_tmp >>= exp_diff + 1;
    343       } else {
    344         L_tmp = (FIXP_DBL)0;
    345       }
    346       den = ener_exc + L_tmp;
    347       if (ener_exc_e < DFRACT_BITS - 1) {
    348         den += scaleValue(FL2FXCONST_DBL(0.01f), -ener_exc_e - 1);
    349       }
    350     } else {
    351       if (exp_diff >= -(DFRACT_BITS - 2)) {
    352         ener_exc >>= 1 - exp_diff;
    353       } else {
    354         ener_exc = (FIXP_DBL)0;
    355       }
    356       L_tmp >>= 1;
    357       den = ener_exc + L_tmp;
    358       if (L_tmp_e < DFRACT_BITS - 1) {
    359         den += scaleValue(FL2FXCONST_DBL(0.01f), -L_tmp_e - 1);
    360       }
    361     }
    362     num = (ener_exc - L_tmp);
    363     num >>= SF_PFAC;
    364 
    365     if (den > (FIXP_DBL)0) {
    366       if (ener_exc > L_tmp) {
    367         period_fac = schur_div(num, den, 16);
    368       } else {
    369         period_fac = -schur_div(-num, den, 16);
    370       }
    371     } else {
    372       period_fac = (FIXP_DBL)MAXVAL_DBL;
    373     }
    374   }
    375 
    376   /* exponent = SF_PFAC */
    377   return period_fac;
    378 }
    379 
    380 /*------------------------------------------------------------*
    381  * noise enhancer                                             *
    382  * ~~~~~~~~~~~~~~                                             *
    383  * - Enhance excitation on noise. (modify gain of code)       *
    384  *   If signal is noisy and LPC filter is stable, move gain   *
    385  *   of code 1.5 dB toward gain of code threshold.            *
    386  *   This decrease by 3 dB noise energy variation.            *
    387  *------------------------------------------------------------*/
    388 /**
    389  * \brief Enhance excitation on noise. (modify gain of code)
    390  * \param[in] gain_code Quantized codebook gain g_c, exponent = SF_GAIN_C.
    391  * \param[in] period_fac periodicity factor, exponent = SF_PFAC.
    392  * \param[in] stab_fac stability factor, exponent = SF_STAB.
    393  * \param[in,out] p_gc_threshold modified gain of previous subframe.
    394  * \return gain_code smoothed gain of code g_sc, exponent = SF_GAIN_C.
    395  */
    396 static FIXP_DBL
    397 noise_enhancer(/* (o) : smoothed gain g_sc                     SF_GAIN_C */
    398                FIXP_DBL gain_code, /* (i) : Quantized codebook gain SF_GAIN_C */
    399                FIXP_DBL period_fac, /* (i) : periodicity factor (-1=unvoiced to
    400                                        1=voiced), SF_PFAC */
    401                FIXP_SGL stab_fac,   /* (i) : stability factor (0 <= ... < 1.0)
    402                                        SF_STAB   */
    403                FIXP_DBL
    404                    *p_gc_threshold) /* (io): gain of code threshold SF_GAIN_C */
    405 {
    406   FIXP_DBL fac, L_tmp, gc_thres;
    407 
    408   gc_thres = *p_gc_threshold;
    409 
    410   L_tmp = gain_code;
    411   if (L_tmp < gc_thres) {
    412     L_tmp += fMultDiv2(gain_code,
    413                        FL2FXCONST_SGL(2.0 * 0.19f)); /* +1.5dB => *(1.0+0.19) */
    414     if (L_tmp > gc_thres) {
    415       L_tmp = gc_thres;
    416     }
    417   } else {
    418     L_tmp = fMult(gain_code,
    419                   FL2FXCONST_SGL(1.0f / 1.19f)); /* -1.5dB => *10^(-1.5/20) */
    420     if (L_tmp < gc_thres) {
    421       L_tmp = gc_thres;
    422     }
    423   }
    424   *p_gc_threshold = L_tmp;
    425 
    426   /* voicing factor     lambda = 0.5*(1-period_fac) */
    427   /* gain smoothing factor S_m = lambda*stab_fac  (=fac)
    428                                = 0.5(stab_fac - stab_fac * period_fac) */
    429   fac = (FX_SGL2FX_DBL(stab_fac) >> (SF_PFAC + 1)) -
    430         fMultDiv2(stab_fac, period_fac);
    431   /* fac_e = SF_PFAC + SF_STAB */
    432   FDK_ASSERT(fac >= (FIXP_DBL)0);
    433 
    434   /* gain_code = (float)((fac*tmp) + ((1.0-fac)*gain_code)); */
    435   gain_code = fMult(fac, L_tmp) -
    436               fMult(FL2FXCONST_DBL(-1.0f / (1 << (SF_PFAC + SF_STAB))) + fac,
    437                     gain_code);
    438   gain_code <<= (SF_PFAC + SF_STAB);
    439 
    440   return gain_code;
    441 }
    442 
    443 /**
    444  * \brief Update adaptive codebook u'(n) (exc)
    445  *        Enhance pitch of c(n) and build post-processed excitation u(n) (exc2)
    446  * \param[in] code innovative codevector c(n), exponent = SF_CODE.
    447  * \param[in,out] exc filtered adaptive codebook v(n), exponent = SF_EXC.
    448  * \param[in] gain_pit adaptive codebook gain, exponent = SF_GAIN_P.
    449  * \param[in] gain_code innovative codebook gain g_c, exponent = SF_GAIN_C.
    450  * \param[in] gain_code_smoothed smoothed innov. codebook gain g_sc, exponent =
    451  * SF_GAIN_C.
    452  * \param[in] period_fac periodicity factor r_v, exponent = SF_PFAC.
    453  * \param[out] exc2 post-processed excitation u(n), exponent = SF_EXC.
    454  */
    455 void BuildAdaptiveExcitation(
    456     FIXP_COD code[],    /* (i) : algebraic codevector c(n)             Q9  */
    457     FIXP_DBL exc[],     /* (io): filtered adaptive codebook v(n)       Q15 */
    458     FIXP_SGL gain_pit,  /* (i) : adaptive codebook gain g_p            Q14 */
    459     FIXP_DBL gain_code, /* (i) : innovative codebook gain g_c          Q16 */
    460     FIXP_DBL gain_code_smoothed, /* (i) : smoothed innov. codebook gain g_sc
    461                                     Q16 */
    462     FIXP_DBL period_fac, /* (i) : periodicity factor r_v                Q15 */
    463     FIXP_DBL exc2[]      /* (o) : post-processed excitation u(n)        Q15 */
    464 ) {
    465 /* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
    466          If exc2[i] is written, code[i] will be destroyed!
    467 */
    468 #define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)
    469 
    470   int i;
    471   FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
    472 
    473   FIXP_COD code_i;
    474   FIXP_DBL cpe_code_smooth, cpe_code_smooth_prev;
    475 
    476   /* cpe = (1+r_v)/8 * 2 ; ( SF = -1) */
    477   cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
    478 
    479   /* u'(n) */
    480   tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
    481   *exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
    482 
    483   /* u(n) */
    484   code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
    485                      << SF; /* c(0) * g_sc */
    486   code_i = *code++;
    487   code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
    488   tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
    489   cpe_code_smooth = fMultDiv2(cpe, code_smooth);
    490   *exc2++ = tmp - cpe_code_smooth;
    491   cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
    492 
    493   i = L_SUBFR - 2;
    494   do /* ARM926: 22 cycles per iteration */
    495   {
    496     /* u'(n) */
    497     tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
    498     *exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
    499     /* u(n) */
    500     tmp += code_smooth; /* += g_sc * c(i) */
    501     tmp -= cpe_code_smooth_prev;
    502     cpe_code_smooth_prev = cpe_code_smooth;
    503     code_i = *code++;
    504     code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
    505     cpe_code_smooth = fMultDiv2(cpe, code_smooth);
    506     *exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
    507   } while (--i != 0);
    508 
    509   /* u'(n) */
    510   tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
    511   *exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
    512   /* u(n) */
    513   tmp += code_smooth;
    514   tmp -= cpe_code_smooth_prev;
    515   *exc2++ = tmp;
    516 
    517   return;
    518 }
    519 
    520 /**
    521  * \brief Interpolate LPC vector in LSP domain for current subframe and convert
    522  * to LP domain
    523  * \param[in] lsp_old LPC vector (LSP domain) corresponding to the beginning of
    524  * current ACELP frame.
    525  * \param[in] lsp_new LPC vector (LSP domain) corresponding to the end of
    526  * current ACELP frame.
    527  * \param[in] subfr_nr number of current ACELP subframe 0..3.
    528  * \param[in] nb_subfr total number of ACELP subframes in this frame.
    529  * \param[out] A LP filter coefficients for current ACELP subframe, exponent =
    530  * SF_A_COEFFS.
    531  */
    532 /* static */
    533 void int_lpc_acelp(
    534     const FIXP_LPC lsp_old[], /* input : LSPs from past frame              */
    535     const FIXP_LPC lsp_new[], /* input : LSPs from present frame           */
    536     int subfr_nr, int nb_subfr,
    537     FIXP_LPC
    538         A[], /* output: interpolated LP coefficients for current subframe */
    539     INT *A_exp) {
    540   int i;
    541   FIXP_LPC lsp_interpol[M_LP_FILTER_ORDER];
    542   FIXP_SGL fac_old, fac_new;
    543 
    544   FDK_ASSERT((nb_subfr == 3) || (nb_subfr == 4));
    545 
    546   fac_old = lsp_interpol_factor[nb_subfr & 0x1][(nb_subfr - 1) - subfr_nr];
    547   fac_new = lsp_interpol_factor[nb_subfr & 0x1][subfr_nr];
    548   for (i = 0; i < M_LP_FILTER_ORDER; i++) {
    549     lsp_interpol[i] = FX_DBL2FX_LPC(
    550         (fMultDiv2(lsp_old[i], fac_old) + fMultDiv2(lsp_new[i], fac_new)) << 1);
    551   }
    552 
    553   E_LPC_f_lsp_a_conversion(lsp_interpol, A, A_exp);
    554 
    555   return;
    556 }
    557 
    558 /**
    559  * \brief Perform LP synthesis by filtering the post-processed excitation u(n)
    560  *        through the LP synthesis filter 1/A(z)
    561  * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS.
    562  * \param[in] length length of input/output signal.
    563  * \param[in] x post-processed excitation u(n).
    564  * \param[in,out] y LP synthesis signal and filter memory
    565  * y[-M_LP_FILTER_ORDER..-1].
    566  */
    567 
    568 /* static */
    569 void Syn_filt(const FIXP_LPC a[], /* (i) : a[m] prediction coefficients Q12 */
    570               const INT a_exp,
    571               INT length,   /* (i) : length of input/output signal (64|128)   */
    572               FIXP_DBL x[], /* (i) : input signal Qx  */
    573               FIXP_DBL y[]  /* (i/o) : filter states / output signal  Qx-s*/
    574 ) {
    575   int i, j;
    576   FIXP_DBL L_tmp;
    577 
    578   for (i = 0; i < length; i++) {
    579     L_tmp = (FIXP_DBL)0;
    580 
    581     for (j = 0; j < M_LP_FILTER_ORDER; j++) {
    582       L_tmp -= fMultDiv2(a[j], y[i - (j + 1)]);
    583     }
    584 
    585     L_tmp = scaleValue(L_tmp, a_exp + 1);
    586     y[i] = L_tmp + x[i];
    587   }
    588 
    589   return;
    590 }
    591 
    592 /**
    593  * \brief Calculate de-emphasis 1/(1 - mu z^-1) on input signal.
    594  * \param[in] x input signal.
    595  * \param[out] y output signal.
    596  * \param[in] L length of signal.
    597  * \param[in,out] mem memory (signal[-1]).
    598  */
    599 /* static */
    600 void Deemph(FIXP_DBL *x, FIXP_DBL *y, int L, FIXP_DBL *mem) {
    601   int i;
    602   FIXP_DBL yi = *mem;
    603 
    604   for (i = 0; i < L; i++) {
    605     FIXP_DBL xi = x[i] >> 1;
    606     xi = fMultAddDiv2(xi, PREEMPH_FAC, yi);
    607     yi = SATURATE_LEFT_SHIFT(xi, 1, 32);
    608     y[i] = yi;
    609   }
    610   *mem = yi;
    611   return;
    612 }
    613 
    614 /**
    615  * \brief Compute the LP residual by filtering the input speech through the
    616  * analysis filter A(z).
    617  * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS
    618  * \param[in] x input signal (note that values x[-m..-1] are needed), exponent =
    619  * SF_SYNTH
    620  * \param[out] y output signal (residual), exponent = SF_EXC
    621  * \param[in] l length of filtering
    622  */
    623 /* static */
    624 void E_UTIL_residu(const FIXP_LPC *a, const INT a_exp, FIXP_DBL *x, FIXP_DBL *y,
    625                    INT l) {
    626   FIXP_DBL s;
    627   INT i, j;
    628 
    629   /* (note that values x[-m..-1] are needed) */
    630   for (i = 0; i < l; i++) {
    631     s = (FIXP_DBL)0;
    632 
    633     for (j = 0; j < M_LP_FILTER_ORDER; j++) {
    634       s += fMultDiv2(a[j], x[i - j - 1]);
    635     }
    636 
    637     s = scaleValue(s, a_exp + 1);
    638     y[i] = fAddSaturate(s, x[i]);
    639   }
    640 
    641   return;
    642 }
    643 
    644 /* use to map subfr number to number of bits used for acb_index */
    645 static const UCHAR num_acb_idx_bits_table[2][NB_SUBFR] = {
    646     {9, 6, 9, 6}, /* coreCoderFrameLength == 1024 */
    647     {9, 6, 6, 0}  /* coreCoderFrameLength == 768  */
    648 };
    649 
    650 static int DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,
    651                           const UCHAR num_acb_idx_bits,
    652                           const int PIT_MIN, /* TMIN */
    653                           const int PIT_FR2, /* TFR2 */
    654                           const int PIT_FR1, /* TFR1 */
    655                           const int PIT_MAX, /* TMAX */
    656                           int *pT0, int *pT0_frac, int *pT0_min, int *pT0_max) {
    657   int acb_idx;
    658   int error = 0;
    659   int T0, T0_frac;
    660 
    661   FDK_ASSERT((num_acb_idx_bits == 9) || (num_acb_idx_bits == 6));
    662 
    663   acb_idx = FDKreadBits(hBs, num_acb_idx_bits);
    664 
    665   if (num_acb_idx_bits == 6) {
    666     /* When the pitch value is encoded on 6 bits, a pitch resolution of 1/4 is
    667        always used in the range [T1-8, T1+7.75], where T1 is nearest integer to
    668        the fractional pitch lag of the previous subframe.
    669     */
    670     T0 = *pT0_min + acb_idx / 4;
    671     T0_frac = acb_idx & 0x3;
    672   } else { /* num_acb_idx_bits == 9 */
    673     /* When the pitch value is encoded on 9 bits, a fractional pitch delay is
    674        used with resolutions 0.25 in the range [TMIN, TFR2-0.25], resolutions
    675        0.5 in the range [TFR2, TFR1-0.5], and integers only in the range [TFR1,
    676        TMAX]. NOTE: for small sampling rates TMAX can get smaller than TFR1.
    677     */
    678     int T0_min, T0_max;
    679 
    680     if (acb_idx < (PIT_FR2 - PIT_MIN) * 4) {
    681       /* first interval with 0.25 pitch resolution */
    682       T0 = PIT_MIN + (acb_idx / 4);
    683       T0_frac = acb_idx & 0x3;
    684     } else if (acb_idx < ((PIT_FR2 - PIT_MIN) * 4 + (PIT_FR1 - PIT_FR2) * 2)) {
    685       /* second interval with 0.5 pitch resolution */
    686       acb_idx -= (PIT_FR2 - PIT_MIN) * 4;
    687       T0 = PIT_FR2 + (acb_idx / 2);
    688       T0_frac = (acb_idx & 0x1) * 2;
    689     } else {
    690       /* third interval with 1.0 pitch resolution */
    691       T0 = acb_idx + PIT_FR1 - ((PIT_FR2 - PIT_MIN) * 4) -
    692            ((PIT_FR1 - PIT_FR2) * 2);
    693       T0_frac = 0;
    694     }
    695     /* find T0_min and T0_max for subframe 1 or 3 */
    696     T0_min = T0 - 8;
    697     if (T0_min < PIT_MIN) {
    698       T0_min = PIT_MIN;
    699     }
    700     T0_max = T0_min + 15;
    701     if (T0_max > PIT_MAX) {
    702       T0_max = PIT_MAX;
    703       T0_min = T0_max - 15;
    704     }
    705     *pT0_min = T0_min;
    706     *pT0_max = T0_max;
    707   }
    708   *pT0 = T0;
    709   *pT0_frac = T0_frac;
    710 
    711   return error;
    712 }
    713 static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,
    714                             int *pT0, int *pT0_frac) {
    715   USHORT *pold_T0 = &acelp_mem->old_T0;
    716   UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;
    717 
    718   if ((int)*pold_T0 >= PIT_MAX) {
    719     *pold_T0 = (UCHAR)(PIT_MAX - 5);
    720   }
    721   *pT0 = (int)*pold_T0;
    722   *pT0_frac = (int)*pold_T0_frac;
    723 }
    724 
    725 static UCHAR tab_coremode2nbits[8] = {20, 28, 36, 44, 52, 64, 12, 16};
    726 
    727 static int MapCoreMode2NBits(int core_mode) {
    728   return (int)tab_coremode2nbits[core_mode];
    729 }
    730 
    731 void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
    732                       const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
    733                       const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
    734                       FIXP_SGL stab_fac, CAcelpChannelData *pAcelpData,
    735                       INT numLostSubframes, int lastLpcLost, int frameCnt,
    736                       FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
    737                       INT coreCoderFrameLength) {
    738   int i_subfr, subfr_nr, l_div, T;
    739   int T0 = -1, T0_frac = -1; /* mark invalid */
    740 
    741   int pit_gain_index = 0;
    742 
    743   const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset); /* maximum pitch lag */
    744 
    745   FIXP_COD *code;
    746   FIXP_DBL *exc2;
    747   FIXP_DBL *syn;
    748   FIXP_DBL *exc;
    749   FIXP_LPC A[M_LP_FILTER_ORDER];
    750   INT A_exp;
    751 
    752   FIXP_DBL period_fac;
    753   FIXP_SGL gain_pit;
    754   FIXP_DBL gain_code, gain_code_smooth, Ener_code;
    755   int Ener_code_e;
    756   int n;
    757   int bfi = (numLostSubframes > 0) ? 1 : 0;
    758 
    759   C_ALLOC_SCRATCH_START(
    760       exc_buf, FIXP_DBL,
    761       PIT_MAX_MAX + L_INTERPOL + L_DIV + 1); /* 411 + 17 + 256 + 1 = 685 */
    762   C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
    763                         M_LP_FILTER_ORDER + L_DIV); /* 16 + 256 = 272 */
    764   /* use same memory for code[L_SUBFR] and exc2[L_SUBFR] */
    765   C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_SUBFR); /* 64 */
    766   /* make sure they don't overlap if they are accessed alternatingly in
    767    * BuildAdaptiveExcitation() */
    768 #if (COD_BITS == FRACT_BITS)
    769   code = (FIXP_COD *)(tmp_buf + L_SUBFR / 2);
    770 #elif (COD_BITS == DFRACT_BITS)
    771   code = (FIXP_COD *)tmp_buf;
    772 #endif
    773   exc2 = (FIXP_DBL *)tmp_buf;
    774 
    775   syn = syn_buf + M_LP_FILTER_ORDER;
    776   exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
    777 
    778   FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
    779             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
    780   FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
    781             (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
    782 
    783   FDKmemclear(exc_buf + (PIT_MAX_MAX + L_INTERPOL),
    784               (L_DIV + 1) * sizeof(FIXP_DBL));
    785 
    786   l_div = coreCoderFrameLength / NB_DIV;
    787 
    788   for (i_subfr = 0, subfr_nr = 0; i_subfr < l_div;
    789        i_subfr += L_SUBFR, subfr_nr++) {
    790     /*-------------------------------------------------*
    791      * - Decode pitch lag (T0 and T0_frac)             *
    792      *-------------------------------------------------*/
    793     if (bfi) {
    794       ConcealPitchLag(acelp_mem, PIT_MAX, &T0, &T0_frac);
    795     } else {
    796       T0 = (int)pAcelpData->T0[subfr_nr];
    797       T0_frac = (int)pAcelpData->T0_frac[subfr_nr];
    798     }
    799 
    800     /*-------------------------------------------------*
    801      * - Find the pitch gain, the interpolation filter *
    802      *   and the adaptive codebook vector.             *
    803      *-------------------------------------------------*/
    804     Pred_lt4(&exc[i_subfr], T0, T0_frac);
    805 
    806     if ((!bfi && pAcelpData->ltp_filtering_flag[subfr_nr] == 0) ||
    807         (bfi && numLostSubframes == 1 && stab_fac < FL2FXCONST_SGL(0.25f))) {
    808       /* find pitch excitation with lp filter: v'(n) => v(n) */
    809       Pred_lt4_postfilter(&exc[i_subfr]);
    810     }
    811 
    812     /*-------------------------------------------------------*
    813      * - Decode innovative codebook.                         *
    814      * - Add the fixed-gain pitch contribution to code[].    *
    815      *-------------------------------------------------------*/
    816     if (bfi) {
    817       for (n = 0; n < L_SUBFR; n++) {
    818         code[n] =
    819             FX_SGL2FX_COD((FIXP_SGL)E_UTIL_random(&acelp_mem->seed_ace)) >> 4;
    820       }
    821     } else {
    822       int nbits = MapCoreMode2NBits((int)pAcelpData->acelp_core_mode);
    823       D_ACELP_decode_4t64(pAcelpData->icb_index[subfr_nr], nbits, &code[0]);
    824     }
    825 
    826     T = T0;
    827     if (T0_frac > 2) {
    828       T += 1;
    829     }
    830 
    831     Preemph_code(code);
    832     Pit_shrp(code, T);
    833 
    834     /* Output pitch lag for bass post-filter */
    835     if (T > PIT_MAX) {
    836       pT[subfr_nr] = PIT_MAX;
    837     } else {
    838       pT[subfr_nr] = T;
    839     }
    840     D_gain2_plus(
    841         pAcelpData->gains[subfr_nr],
    842         code,       /* (i)  : Innovative code vector, exponent = SF_CODE */
    843         &gain_pit,  /* (o)  : Quantized pitch gain, exponent = SF_GAIN_P */
    844         &gain_code, /* (o)  : Quantized codebook gain                    */
    845         pAcelpData
    846             ->mean_energy, /* (i)  : mean_ener defined in open-loop (2 bits) */
    847         bfi, &acelp_mem->past_gpit, &acelp_mem->past_gcode,
    848         &Ener_code,    /* (o)  : Innovative code vector energy              */
    849         &Ener_code_e); /* (o)  : Innovative code vector energy exponent     */
    850 
    851     pit_gain[pit_gain_index++] = FX_SGL2FX_DBL(gain_pit);
    852 
    853     /* calc periodicity factor r_v */
    854     period_fac =
    855         calc_period_factor(/* (o) : factor (-1=unvoiced to 1=voiced)    */
    856                            &exc[i_subfr], /* (i) : pitch excitation, exponent =
    857                                              SF_EXC */
    858                            gain_pit,      /* (i) : gain of pitch, exponent =
    859                                              SF_GAIN_P */
    860                            gain_code,     /* (i) : gain of code     */
    861                            Ener_code,     /* (i) : Energy of code[]     */
    862                            Ener_code_e);  /* (i) : Exponent of energy of code[]
    863                                            */
    864 
    865     if (lastLpcLost && frameCnt == 0) {
    866       if (gain_pit > FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P))) {
    867         gain_pit = FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P));
    868       }
    869     }
    870 
    871     gain_code_smooth =
    872         noise_enhancer(/* (o) : smoothed gain g_sc exponent = SF_GAIN_C */
    873                        gain_code,  /* (i) : Quantized codebook gain  */
    874                        period_fac, /* (i) : periodicity factor (-1=unvoiced to
    875                                       1=voiced)  */
    876                        stab_fac,   /* (i) : stability factor (0 <= ... < 1),
    877                                       exponent = 1 */
    878                        &acelp_mem->gc_threshold);
    879 
    880     /* Compute adaptive codebook update u'(n), pitch enhancement c'(n) and
    881      * post-processed excitation u(n). */
    882     BuildAdaptiveExcitation(code, exc + i_subfr, gain_pit, gain_code,
    883                             gain_code_smooth, period_fac, exc2);
    884 
    885     /* Interpolate filter coeffs for current subframe in lsp domain and convert
    886      * to LP domain */
    887     int_lpc_acelp(lsp_old,  /* input : LSPs from past frame              */
    888                   lsp_new,  /* input : LSPs from present frame           */
    889                   subfr_nr, /* input : ACELP subframe index              */
    890                   coreCoderFrameLength / L_DIV,
    891                   A, /* output: LP coefficients of this subframe  */
    892                   &A_exp);
    893 
    894     Syn_filt(A, /* (i) : a[m] prediction coefficients               */
    895              A_exp, L_SUBFR, /* (i) : length */
    896              exc2, /* (i) : input signal                               */
    897              &syn[i_subfr] /* (i/o) : filter states / output signal */
    898     );
    899 
    900   } /* end of subframe loop */
    901 
    902   /* update pitch value for bfi procedure */
    903   acelp_mem->old_T0_frac = T0_frac;
    904   acelp_mem->old_T0 = T0;
    905 
    906   /* save old excitation and old synthesis memory for next ACELP frame */
    907   FDKmemcpy(acelp_mem->old_exc_mem, exc + l_div - (PIT_MAX_MAX + L_INTERPOL),
    908             sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
    909   FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + l_div,
    910             sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
    911 
    912   Deemph(syn, synth, l_div,
    913          &acelp_mem->de_emph_mem); /* ref soft: mem = synth[-1] */
    914 
    915   scaleValues(synth, l_div, -ACELP_OUTSCALE);
    916   acelp_mem->deemph_mem_wsyn = acelp_mem->de_emph_mem;
    917 
    918   C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_SUBFR);
    919   C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
    920   C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV + 1);
    921   return;
    922 }
    923 
    924 void CLpd_AcelpReset(CAcelpStaticMem *acelp) {
    925   acelp->gc_threshold = (FIXP_DBL)0;
    926 
    927   acelp->past_gpit = (FIXP_SGL)0;
    928   acelp->past_gcode = (FIXP_DBL)0;
    929   acelp->old_T0 = 64;
    930   acelp->old_T0_frac = 0;
    931   acelp->deemph_mem_wsyn = (FIXP_DBL)0;
    932   acelp->wsyn_rms = (FIXP_DBL)0;
    933   acelp->seed_ace = 0;
    934 }
    935 
    936 /* TCX time domain concealment */
    937 /*   Compare to figure 13a on page 54 in 3GPP TS 26.290 */
    938 void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
    939                        const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
    940                        const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
    941                        const FIXP_SGL stab_fac, INT nLostSf, FIXP_DBL synth[],
    942                        INT coreCoderFrameLength, UCHAR last_tcx_noise_factor) {
    943   /* repeat past excitation with pitch from previous decoded TCX frame */
    944   C_ALLOC_SCRATCH_START(
    945       exc_buf, FIXP_DBL,
    946       PIT_MAX_MAX + L_INTERPOL + L_DIV); /* 411 +  17 + 256 + 1 =  */
    947   C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
    948                         M_LP_FILTER_ORDER + L_DIV); /* 256 +  16           =  */
    949                                                     /*                    +=  */
    950   FIXP_DBL ns_buf[L_DIV + 1];
    951   FIXP_DBL *syn = syn_buf + M_LP_FILTER_ORDER;
    952   FIXP_DBL *exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
    953   FIXP_DBL *ns = ns_buf + 1;
    954   FIXP_DBL tmp, fact_exc;
    955   INT T = fMin(*pitch, (SHORT)PIT_MAX_MAX);
    956   int i, i_subfr, subfr_nr;
    957   int lDiv = coreCoderFrameLength / NB_DIV;
    958 
    959   FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
    960             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
    961   FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
    962             (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
    963 
    964   /* if we lost all packets (i.e. 1 packet of TCX-20 ms, 2 packets of
    965      the TCX-40 ms or 4 packets of the TCX-80ms), we lost the whole
    966      coded frame extrapolation strategy: repeat lost excitation and
    967      use extrapolated LSFs */
    968 
    969   /* AMR-WB+ like TCX TD concealment */
    970 
    971   /* number of lost frame cmpt */
    972   if (nLostSf < 2) {
    973     fact_exc = FL2FXCONST_DBL(0.8f);
    974   } else {
    975     fact_exc = FL2FXCONST_DBL(0.4f);
    976   }
    977 
    978   /* repeat past excitation */
    979   for (i = 0; i < lDiv; i++) {
    980     exc[i] = fMult(fact_exc, exc[i - T]);
    981   }
    982 
    983   tmp = fMult(fact_exc, acelp_mem->wsyn_rms);
    984   acelp_mem->wsyn_rms = tmp;
    985 
    986   /* init deemph_mem_wsyn */
    987   acelp_mem->deemph_mem_wsyn = exc[-1];
    988 
    989   ns[-1] = acelp_mem->deemph_mem_wsyn;
    990 
    991   for (i_subfr = 0, subfr_nr = 0; i_subfr < lDiv;
    992        i_subfr += L_SUBFR, subfr_nr++) {
    993     FIXP_DBL tRes[L_SUBFR];
    994     FIXP_LPC A[M_LP_FILTER_ORDER];
    995     INT A_exp;
    996 
    997     /* interpolate LPC coefficients */
    998     int_lpc_acelp(lsp_old, lsp_new, subfr_nr, lDiv / L_SUBFR, A, &A_exp);
    999 
   1000     Syn_filt(A,              /* (i) : a[m] prediction coefficients         */
   1001              A_exp, L_SUBFR, /* (i) : length                               */
   1002              &exc[i_subfr],  /* (i) : input signal                         */
   1003              &syn[i_subfr]   /* (i/o) : filter states / output signal      */
   1004     );
   1005 
   1006     E_LPC_a_weight(
   1007         A, A,
   1008         M_LP_FILTER_ORDER); /* overwrite A as it is not needed any longer */
   1009 
   1010     E_UTIL_residu(A, A_exp, &syn[i_subfr], tRes, L_SUBFR);
   1011 
   1012     Deemph(tRes, &ns[i_subfr], L_SUBFR, &acelp_mem->deemph_mem_wsyn);
   1013 
   1014     /* Amplitude limiter (saturate at wsyn_rms) */
   1015     for (i = i_subfr; i < i_subfr + L_SUBFR; i++) {
   1016       if (ns[i] > tmp) {
   1017         ns[i] = tmp;
   1018       } else {
   1019         if (ns[i] < -tmp) {
   1020           ns[i] = -tmp;
   1021         }
   1022       }
   1023     }
   1024 
   1025     E_UTIL_preemph(&ns[i_subfr], tRes, L_SUBFR);
   1026 
   1027     Syn_filt(A,              /* (i) : a[m] prediction coefficients         */
   1028              A_exp, L_SUBFR, /* (i) : length                               */
   1029              tRes,           /* (i) : input signal                         */
   1030              &syn[i_subfr]   /* (i/o) : filter states / output signal      */
   1031     );
   1032 
   1033     FDKmemmove(&synth[i_subfr], &syn[i_subfr], L_SUBFR * sizeof(FIXP_DBL));
   1034   }
   1035 
   1036   /* save old excitation and old synthesis memory for next ACELP frame */
   1037   FDKmemcpy(acelp_mem->old_exc_mem, exc + lDiv - (PIT_MAX_MAX + L_INTERPOL),
   1038             sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
   1039   FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + lDiv,
   1040             sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
   1041   acelp_mem->de_emph_mem = acelp_mem->deemph_mem_wsyn;
   1042 
   1043   C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
   1044   C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV);
   1045 }
   1046 
   1047 void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
   1048                          INT *old_T_pf, FIXP_DBL *pit_gain,
   1049                          FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
   1050                          INT coreCoderFrameLength, INT synSfd,
   1051                          INT nbSubfrSuperfr) {
   1052   int n;
   1053 
   1054   /* init beginning of synth_buf with old synthesis from previous frame */
   1055   FDKmemcpy(synth_buf, old_synth, sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
   1056 
   1057   /* calculate pitch lag offset for ACELP decoder */
   1058   *i_offset =
   1059       (samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
   1060       PIT_MIN_12k8;
   1061 
   1062   /* for bass postfilter */
   1063   for (n = 0; n < synSfd; n++) {
   1064     pitch[n] = old_T_pf[n];
   1065     pit_gain[n] = old_gain_pf[n];
   1066   }
   1067   for (n = 0; n < nbSubfrSuperfr; n++) {
   1068     pitch[n + synSfd] = L_SUBFR;
   1069     pit_gain[n + synSfd] = (FIXP_DBL)0;
   1070   }
   1071 }
   1072 
   1073 void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
   1074                           INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
   1075                           INT nbSubfrSuperfr) {
   1076   int n;
   1077 
   1078   /* store last part of synth_buf (which is not handled by the IMDCT overlap)
   1079    * for next frame */
   1080   FDKmemcpy(old_synth, synth_buf + coreCoderFrameLength,
   1081             sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
   1082 
   1083   /* for bass postfilter */
   1084   for (n = 0; n < synSfd; n++) {
   1085     old_T_pf[n] = pitch[nbSubfrSuperfr + n];
   1086   }
   1087 }
   1088 
   1089 #define L_FAC_ZIR (LFAC)
   1090 
   1091 void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
   1092                     CAcelpStaticMem *acelp_mem, const INT length,
   1093                     FIXP_DBL zir[], int doDeemph) {
   1094   C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
   1095   FDK_ASSERT(length <= L_FAC_ZIR);
   1096 
   1097   FDKmemcpy(tmp_buf, acelp_mem->old_syn_mem,
   1098             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
   1099   FDKmemset(tmp_buf + M_LP_FILTER_ORDER, 0, L_FAC_ZIR * sizeof(FIXP_DBL));
   1100 
   1101   Syn_filt(A, A_exp, length, &tmp_buf[M_LP_FILTER_ORDER],
   1102            &tmp_buf[M_LP_FILTER_ORDER]);
   1103   if (!doDeemph) {
   1104     /* if last lpd mode was TD concealment, then bypass deemph */
   1105     FDKmemcpy(zir, tmp_buf, length * sizeof(*zir));
   1106   } else {
   1107     Deemph(&tmp_buf[M_LP_FILTER_ORDER], &zir[0], length,
   1108            &acelp_mem->de_emph_mem);
   1109     scaleValues(zir, length, -ACELP_OUTSCALE);
   1110   }
   1111   C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
   1112 }
   1113 
   1114 void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
   1115                                   UCHAR last_last_lpd_mode,
   1116                                   const FIXP_LPC *A_new, const INT A_new_exp,
   1117                                   const FIXP_LPC *A_old, const INT A_old_exp,
   1118                                   CAcelpStaticMem *acelp_mem,
   1119                                   INT coreCoderFrameLength, INT clearOldExc,
   1120                                   UCHAR lpd_mode) {
   1121   int l_div =
   1122       coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */
   1123   int l_div_partial;
   1124   FIXP_DBL *syn, *old_exc_mem;
   1125 
   1126   C_ALLOC_SCRATCH_START(synth_buf, FIXP_DBL,
   1127                         PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
   1128   syn = &synth_buf[M_LP_FILTER_ORDER];
   1129 
   1130   l_div_partial = PIT_MAX_MAX + L_INTERPOL - l_div;
   1131   old_exc_mem = acelp_mem->old_exc_mem;
   1132 
   1133   if (lpd_mode == 4) {
   1134     /* Bypass Domain conversion. TCXTD Concealment does no deemphasis in the
   1135      * end. */
   1136     FDKmemcpy(
   1137         synth_buf, &synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
   1138         (PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER) * sizeof(FIXP_DBL));
   1139     /* Set deemphasis memory state for TD concealment */
   1140     acelp_mem->deemph_mem_wsyn = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
   1141   } else {
   1142     /* convert past [PIT_MAX_MAX+L_INTERPOL+M_LP_FILTER_ORDER] synthesis to
   1143      * preemph domain */
   1144     E_UTIL_preemph(&synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
   1145                    synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
   1146     scaleValuesSaturate(synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER,
   1147                         ACELP_OUTSCALE);
   1148   }
   1149 
   1150   /* Set deemphasis memory state */
   1151   acelp_mem->de_emph_mem = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
   1152 
   1153   /* update acelp synth filter memory */
   1154   FDKmemcpy(acelp_mem->old_syn_mem,
   1155             &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER],
   1156             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
   1157 
   1158   if (clearOldExc) {
   1159     FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
   1160     C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
   1161                         PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
   1162     return;
   1163   }
   1164 
   1165   /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */
   1166   if (last_lpd_mode == 1) {        /* last frame was TCX20 */
   1167     if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */
   1168       /* Delay valid part of excitation buffer (from previous ACELP frame) by
   1169        * l_div samples */
   1170       FDKmemmove(old_exc_mem, old_exc_mem + l_div,
   1171                  sizeof(FIXP_DBL) * l_div_partial);
   1172     } else if (last_last_lpd_mode > 0) { /* TCX -> TCX20 -> ACELP transition */
   1173       E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, l_div_partial);
   1174     }
   1175     E_UTIL_residu(A_new, A_new_exp, syn + l_div_partial,
   1176                   old_exc_mem + l_div_partial, l_div);
   1177   } else { /* prev frame was FD, TCX40 or TCX80 */
   1178     int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL)
   1179                                ? PIT_MAX_MAX + L_INTERPOL
   1180                                : coreCoderFrameLength / 2;
   1181     int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length;
   1182     E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length);
   1183     E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length],
   1184                   &old_exc_mem[exc_A_old_length], exc_A_new_length);
   1185   }
   1186   C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
   1187                       PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
   1188 
   1189   return;
   1190 }
   1191 
   1192 FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length) {
   1193   FDK_ASSERT(length <= PIT_MAX_MAX + L_INTERPOL);
   1194   return acelp_mem->old_exc_mem;
   1195 }
   1196 
   1197 INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelp,
   1198                    INT acelp_core_mode, INT coreCoderFrameLength,
   1199                    INT i_offset) {
   1200   int nb_subfr = coreCoderFrameLength / L_DIV;
   1201   const UCHAR *num_acb_index_bits =
   1202       (nb_subfr == 4) ? num_acb_idx_bits_table[0] : num_acb_idx_bits_table[1];
   1203   int nbits;
   1204   int error = 0;
   1205 
   1206   const int PIT_MIN = PIT_MIN_12k8 + i_offset;
   1207   const int PIT_FR2 = PIT_FR2_12k8 - i_offset;
   1208   const int PIT_FR1 = PIT_FR1_12k8;
   1209   const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset);
   1210   int T0, T0_frac, T0_min = 0, T0_max;
   1211 
   1212   if (PIT_MAX > PIT_MAX_MAX) {
   1213     error = AAC_DEC_DECODE_FRAME_ERROR;
   1214     goto bail;
   1215   }
   1216 
   1217   acelp->acelp_core_mode = acelp_core_mode;
   1218 
   1219   nbits = MapCoreMode2NBits(acelp_core_mode);
   1220 
   1221   /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */
   1222   acelp->mean_energy = FDKreadBits(hBs, 2);
   1223 
   1224   for (int sfr = 0; sfr < nb_subfr; sfr++) {
   1225     /* read ACB index and store T0 and T0_frac for each ACELP subframe. */
   1226     error = DecodePitchLag(hBs, num_acb_index_bits[sfr], PIT_MIN, PIT_FR2,
   1227                            PIT_FR1, PIT_MAX, &T0, &T0_frac, &T0_min, &T0_max);
   1228     if (error) {
   1229       goto bail;
   1230     }
   1231     acelp->T0[sfr] = (USHORT)T0;
   1232     acelp->T0_frac[sfr] = (UCHAR)T0_frac;
   1233     acelp->ltp_filtering_flag[sfr] = FDKreadBits(hBs, 1);
   1234     switch (nbits) {
   1235       case 12: /* 12 bits AMR-WB codebook is used */
   1236         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
   1237         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
   1238         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 1);
   1239         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
   1240         break;
   1241       case 16: /* 16 bits AMR-WB codebook is used */
   1242         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
   1243         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
   1244         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
   1245         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
   1246         break;
   1247       case 20: /* 20 bits AMR-WB codebook is used */
   1248         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 5);
   1249         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
   1250         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
   1251         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
   1252         break;
   1253       case 28: /* 28 bits AMR-WB codebook is used */
   1254         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
   1255         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
   1256         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
   1257         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
   1258         break;
   1259       case 36: /* 36 bits AMR-WB codebook is used */
   1260         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
   1261         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
   1262         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
   1263         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
   1264         break;
   1265       case 44: /* 44 bits AMR-WB codebook is used */
   1266         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
   1267         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
   1268         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
   1269         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
   1270         break;
   1271       case 52: /* 52 bits AMR-WB codebook is used */
   1272         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
   1273         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
   1274         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 13);
   1275         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 13);
   1276         break;
   1277       case 64: /* 64 bits AMR-WB codebook is used */
   1278         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 2);
   1279         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 2);
   1280         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 2);
   1281         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 2);
   1282         acelp->icb_index[sfr][4] = FDKreadBits(hBs, 14);
   1283         acelp->icb_index[sfr][5] = FDKreadBits(hBs, 14);
   1284         acelp->icb_index[sfr][6] = FDKreadBits(hBs, 14);
   1285         acelp->icb_index[sfr][7] = FDKreadBits(hBs, 14);
   1286         break;
   1287       default:
   1288         FDK_ASSERT(0);
   1289         break;
   1290     }
   1291     acelp->gains[sfr] = FDKreadBits(hBs, 7);
   1292   }
   1293 
   1294 bail:
   1295   return error;
   1296 }
   1297