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):   Manuel Jander
     98 
     99    Description: USAC Linear Prediction Domain coding
    100 
    101 *******************************************************************************/
    102 
    103 #include "usacdec_lpd.h"
    104 
    105 #include "usacdec_rom.h"
    106 #include "usacdec_fac.h"
    107 #include "usacdec_lpc.h"
    108 #include "FDK_tools_rom.h"
    109 #include "fft.h"
    110 #include "mdct.h"
    111 #include "usacdec_acelp.h"
    112 #include "overlapadd.h"
    113 
    114 #include "conceal.h"
    115 
    116 #include "block.h"
    117 
    118 #define SF_PITCH_TRACK 6
    119 #define SF_GAIN 3
    120 #define MIN_VAL FL2FXCONST_DBL(0.0f)
    121 #define MAX_VAL (FIXP_DBL) MAXVAL_DBL
    122 
    123 #include "ac_arith_coder.h"
    124 
    125 void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
    126             const FIXP_SGL *filt, INT stop, int len) {
    127   INT i, j;
    128   FIXP_DBL tmp;
    129 
    130   for (i = 0; i < stop; i++) {
    131     tmp = fMultDiv2(noise[i], filt[0]);  // Filt in Q-1.16
    132     for (j = 1; j <= len; j++) {
    133       tmp += fMultDiv2((noise[i - j] + noise[i + j]), filt[j]);
    134     }
    135     syn_out[i] = (FIXP_PCM)(IMDCT_SCALE(syn[i] - tmp));
    136   }
    137 }
    138 
    139 void bass_pf_1sf_delay(
    140     FIXP_DBL *syn,   /* (i) : 12.8kHz synthesis to postfilter              */
    141     const INT *T_sf, /* (i) : Pitch period for all subframes (T_sf[16])    */
    142     FIXP_DBL *pit_gain,
    143     const int frame_length, /* (i) : frame length (should be 768|1024) */
    144     const INT l_frame,
    145     const INT l_next, /* (i) : look ahead for symmetric filtering           */
    146     FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
    147     FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR]                */
    148 {
    149   INT i, sf, i_subfr, T, T2, lg;
    150 
    151   FIXP_DBL tmp, ener, corr, gain;
    152   FIXP_DBL *noise, *noise_in;
    153   FIXP_DBL
    154   noise_buf[L_FILT + (2 * L_SUBFR)];  // L_FILT = 12, L_SUBFR = 64 => 140
    155   const FIXP_DBL *x, *y;
    156 
    157   {
    158     noise = noise_buf + L_FILT;  // L_FILT = 12 delay of upsampling filter
    159     noise_in = noise_buf + L_FILT + L_SUBFR;
    160     /* Input scaling of the BPF memory */
    161     scaleValues(mem_bpf, (L_FILT + L_SUBFR), 1);
    162   }
    163 
    164   int gain_exp = 17;
    165 
    166   sf = 0;
    167   for (i_subfr = 0; i_subfr < l_frame; i_subfr += L_SUBFR, sf++) {
    168     T = T_sf[sf];
    169     gain = pit_gain[sf];
    170 
    171     /* Gain is in Q17.14 */
    172     /* If gain > 1 set to 1 */
    173     if (gain > (FIXP_DBL)(1 << 14)) gain = (FIXP_DBL)(1 << 14);
    174 
    175     /* If gain < 0 set to 0 */
    176     if (gain < (FIXP_DBL)0) gain = (FIXP_DBL)0;
    177 
    178     if (gain > (FIXP_DBL)0) {
    179       /* pitch tracker: test pitch/2 to avoid continuous pitch doubling */
    180       /* Note: pitch is limited to PIT_MIN (34 = 376Hz) at the encoder  */
    181       T2 = T >> 1;
    182       x = &syn[i_subfr - L_EXTRA];
    183       y = &syn[i_subfr - T2 - L_EXTRA];
    184 
    185       ener = (FIXP_DBL)0;
    186       corr = (FIXP_DBL)0;
    187       tmp = (FIXP_DBL)0;
    188 
    189       int headroom_x = getScalefactor(x, L_SUBFR + L_EXTRA);
    190       int headroom_y = getScalefactor(y, L_SUBFR + L_EXTRA);
    191 
    192       int width_shift = 7;
    193 
    194       for (i = 0; i < (L_SUBFR + L_EXTRA); i++) {
    195         ener += fPow2Div2((x[i] << headroom_x)) >> width_shift;
    196         corr += fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >>
    197                 width_shift;
    198         tmp += fPow2Div2((y[i] << headroom_y)) >> width_shift;
    199       }
    200 
    201       int exp_ener = ((17 - headroom_x) << 1) + width_shift + 1;
    202       int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
    203       int exp_tmp = ((17 - headroom_y) << 1) + width_shift + 1;
    204 
    205       /* Add 0.01 to "ener". Adjust exponents */
    206       FIXP_DBL point_zero_one = (FIXP_DBL)0x51eb851f; /* In Q-6.37 */
    207       int diff;
    208       ener = fAddNorm(ener, exp_ener, point_zero_one, -6, &exp_ener);
    209       corr = fAddNorm(corr, exp_corr, point_zero_one, -6, &exp_corr);
    210       tmp = fAddNorm(tmp, exp_tmp, point_zero_one, -6, &exp_tmp);
    211 
    212       /* use T2 if normalized correlation > 0.95 */
    213       INT s1, s2;
    214       s1 = CntLeadingZeros(ener) - 1;
    215       s2 = CntLeadingZeros(tmp) - 1;
    216 
    217       FIXP_DBL ener_by_tmp = fMultDiv2(ener << s1, tmp << s2);
    218       int ener_by_tmp_exp = (exp_ener - s1) + (exp_tmp - s2) + 1;
    219 
    220       if (ener_by_tmp_exp & 1) {
    221         ener_by_tmp <<= 1;
    222         ener_by_tmp_exp -= 1;
    223       }
    224 
    225       int temp_exp = 0;
    226 
    227       FIXP_DBL temp1 = invSqrtNorm2(ener_by_tmp, &temp_exp);
    228 
    229       int temp1_exp = temp_exp - (ener_by_tmp_exp >> 1);
    230 
    231       FIXP_DBL tmp_result = fMult(corr, temp1);
    232 
    233       int tmp_result_exp = exp_corr + temp1_exp;
    234 
    235       diff = tmp_result_exp - 0;
    236       FIXP_DBL point95 = FL2FXCONST_DBL(0.95f);
    237       if (diff >= 0) {
    238         diff = fMin(diff, 31);
    239         point95 = FL2FXCONST_DBL(0.95f) >> diff;
    240       } else {
    241         diff = fMax(diff, -31);
    242         tmp_result >>= (-diff);
    243       }
    244 
    245       if (tmp_result > point95) T = T2;
    246 
    247       /* prevent that noise calculation below reaches into not defined signal
    248          parts at the end of the synth_buf or in other words restrict the below
    249          used index (i+i_subfr+T) < l_frame + l_next
    250       */
    251       lg = l_frame + l_next - T - i_subfr;
    252 
    253       if (lg > L_SUBFR)
    254         lg = L_SUBFR;
    255       else if (lg < 0)
    256         lg = 0;
    257 
    258       /* limit gain to avoid problem on burst */
    259       if (lg > 0) {
    260         FIXP_DBL tmp1;
    261 
    262         /* max(lg) = 64 => scale with 6 bits minus 1 (fPow2Div2) */
    263 
    264         s1 = getScalefactor(&syn[i_subfr], lg);
    265         s2 = getScalefactor(&syn[i_subfr + T], lg);
    266         INT s = fixMin(s1, s2);
    267 
    268         tmp = (FIXP_DBL)0;
    269         ener = (FIXP_DBL)0;
    270         for (i = 0; i < lg; i++) {
    271           tmp += fPow2Div2(syn[i + i_subfr] << s1) >> (SF_PITCH_TRACK);
    272           ener += fPow2Div2(syn[i + i_subfr + T] << s2) >> (SF_PITCH_TRACK);
    273         }
    274         tmp = tmp >> fMin(DFRACT_BITS - 1, (2 * (s1 - s)));
    275         ener = ener >> fMin(DFRACT_BITS - 1, (2 * (s2 - s)));
    276 
    277         /* error robustness: for the specific case syn[...] == -1.0f for all 64
    278            samples ener or tmp might overflow and become negative. For all sane
    279            cases we have enough headroom.
    280         */
    281         if (ener <= (FIXP_DBL)0) {
    282           ener = (FIXP_DBL)1;
    283         }
    284         if (tmp <= (FIXP_DBL)0) {
    285           tmp = (FIXP_DBL)1;
    286         }
    287         FDK_ASSERT(ener > (FIXP_DBL)0);
    288 
    289         /* tmp = sqrt(tmp/ener) */
    290         int result_e = 0;
    291         tmp1 = fDivNorm(tmp, ener, &result_e);
    292         if (result_e & 1) {
    293           tmp1 >>= 1;
    294           result_e += 1;
    295         }
    296         tmp = sqrtFixp(tmp1);
    297         result_e >>= 1;
    298 
    299         gain_exp = 17;
    300 
    301         diff = result_e - gain_exp;
    302 
    303         FIXP_DBL gain1 = gain;
    304 
    305         if (diff >= 0) {
    306           diff = fMin(diff, 31);
    307           gain1 >>= diff;
    308         } else {
    309           result_e += (-diff);
    310           diff = fMax(diff, -31);
    311           tmp >>= (-diff);
    312         }
    313 
    314         if (tmp < gain1) {
    315           gain = tmp;
    316           gain_exp = result_e;
    317         }
    318       }
    319 
    320       /* calculate noise based on voiced pitch */
    321       /* fMultDiv2() replaces weighting of gain with 0.5 */
    322       diff = gain_exp - 17;
    323       if (diff >= 0) {
    324         gain <<= diff;
    325       } else {
    326         gain >>= (-diff);
    327       }
    328 
    329       s1 = CntLeadingZeros(gain) - 1;
    330       s1 -= 16; /* Leading bits for SGL */
    331 
    332       FIXP_SGL gainSGL = FX_DBL2FX_SGL(gain << 16);
    333 
    334       gainSGL = gainSGL << s1;
    335 
    336       {
    337         for (i = 0; i < lg; i++) {
    338           /* scaled with SF_SYNTH + gain_sf + 1 */
    339           noise_in[i] =
    340               (fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) -
    341                                   (syn[i + i_subfr + T] >> 1))) >>
    342               s1;
    343         }
    344 
    345         for (i = lg; i < L_SUBFR; i++) {
    346           /* scaled with SF_SYNTH + gain_sf + 1 */
    347           noise_in[i] =
    348               (fMult(gainSGL, syn[i + i_subfr] - syn[i + i_subfr - T])) >> s1;
    349         }
    350       }
    351     } else {
    352       FDKmemset(noise_in, (FIXP_DBL)0, L_SUBFR * sizeof(FIXP_DBL));
    353     }
    354 
    355     {
    356       FDKmemcpy(noise_buf, mem_bpf, (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));
    357 
    358       FDKmemcpy(mem_bpf, noise_buf + L_SUBFR,
    359                 (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));
    360     }
    361 
    362     /* substract from voiced speech low-pass filtered noise */
    363     /* filter coefficients are scaled with factor SF_FILT_LP (1) */
    364 
    365     {
    366       filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise,
    367              fdk_dec_filt_lp, L_SUBFR, L_FILT);
    368     }
    369   }
    370 
    371   {
    372 
    373   }
    374 
    375   // To be determined (info from Ben)
    376   {
    377     /* Output scaling of the BPF memory */
    378     scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
    379     /* Copy the rest of the signal (after the fac) */
    380     scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame],
    381                         (FIXP_DBL *)&syn[l_frame - L_SUBFR],
    382                         (frame_length - l_frame), MDCT_OUT_HEADROOM);
    383   }
    384 
    385   return;
    386 }
    387 
    388 /*
    389  * Frequency Domain Noise Shaping
    390  */
    391 
    392 /**
    393  * \brief Adaptive Low Frequencies Deemphasis of spectral coefficients.
    394  *
    395  * Ensure quantization of low frequencies in case where the
    396  * signal dynamic is higher than the LPC noise shaping.
    397  * This is the inverse operation of adap_low_freq_emph().
    398  * Output gain of all blocks.
    399  *
    400  * \param x pointer to the spectral coefficients, requires 1 bit headroom.
    401  * \param lg length of x.
    402  * \param bUseNewAlfe if set, apply ALFD for fullband lpd.
    403  * \param gainLpc1 pointer to gain based on old input LPC coefficients.
    404  * \param gainLpc2 pointer to gain based on new input LPC coefficients.
    405  * \param alfd_gains pointer to output gains.
    406  * \param s current scale shift factor of x.
    407  */
    408 #define ALFDPOW2_SCALE 3
    409 /*static*/
    410 void CLpd_AdaptLowFreqDeemph(FIXP_DBL x[], int lg, FIXP_DBL alfd_gains[],
    411                              INT s) {
    412   {
    413     int i, j, k, i_max;
    414     FIXP_DBL max, fac;
    415     /* Note: This stack array saves temporary accumulation results to be used in
    416      * a second run */
    417     /*       The size should be limited to (1024/4)/8=32 */
    418     FIXP_DBL tmp_pow2[32];
    419 
    420     s = s * 2 + ALFDPOW2_SCALE;
    421 
    422     k = 8;
    423     i_max = lg / 4; /* ALFD range = 1600Hz (lg = 6400Hz) */
    424 
    425     /* find spectral peak */
    426     max = FL2FX_DBL(0.01f) >> s;
    427     for (i = 0; i < i_max; i += k) {
    428       FIXP_DBL tmp;
    429 
    430       tmp = FIXP_DBL(0);
    431       FIXP_DBL *pX = &x[i];
    432 
    433       j = 8;
    434       do {
    435         FIXP_DBL x0 = *pX++;
    436         FIXP_DBL x1 = *pX++;
    437         x0 = fPow2Div2(x0);
    438         x1 = fPow2Div2(x1);
    439         tmp = tmp + (x0 >> (ALFDPOW2_SCALE - 1));
    440         tmp = tmp + (x1 >> (ALFDPOW2_SCALE - 1));
    441       } while ((j = j - 2) != 0);
    442       tmp = fMax(tmp, (FL2FX_DBL(0.01f) >> s));
    443       tmp_pow2[i >> 3] = tmp;
    444       if (tmp > max) {
    445         max = tmp;
    446       }
    447     }
    448 
    449     /* deemphasis of all blocks below the peak */
    450     fac = FL2FX_DBL(0.1f) >> 1;
    451     for (i = 0; i < i_max; i += k) {
    452       FIXP_DBL tmp;
    453       INT shifti;
    454 
    455       tmp = tmp_pow2[i >> 3];
    456 
    457       /* tmp = (float)sqrt(tmp/max); */
    458 
    459       /* value of tmp is between 8/2*max^2 and max^2 / 2. */
    460       /* required shift factor of division can grow up to 27
    461          (grows exponentially for values toward zero)
    462          thus using normalized division to assure valid result. */
    463       {
    464         INT sd;
    465 
    466         if (tmp != (FIXP_DBL)0) {
    467           tmp = fDivNorm(max, tmp, &sd);
    468           if (sd & 1) {
    469             sd++;
    470             tmp >>= 1;
    471           }
    472         } else {
    473           tmp = (FIXP_DBL)MAXVAL_DBL;
    474           sd = 0;
    475         }
    476         tmp = invSqrtNorm2(tmp, &shifti);
    477         tmp = scaleValue(tmp, shifti - 1 - (sd / 2));
    478       }
    479       if (tmp > fac) {
    480         fac = tmp;
    481       }
    482       FIXP_DBL *pX = &x[i];
    483 
    484       j = 8;
    485       do {
    486         FIXP_DBL x0 = pX[0];
    487         FIXP_DBL x1 = pX[1];
    488         x0 = fMultDiv2(x0, fac);
    489         x1 = fMultDiv2(x1, fac);
    490         x0 = x0 << 2;
    491         x1 = x1 << 2;
    492         *pX++ = x0;
    493         *pX++ = x1;
    494 
    495       } while ((j = j - 2) != 0);
    496       /* Store gains for FAC */
    497       *alfd_gains++ = fac;
    498     }
    499   }
    500 }
    501 
    502 /**
    503  * \brief Interpolated Noise Shaping for mdct coefficients.
    504  * This algorithm shapes temporally the spectral noise between
    505  * the two spectral noise represention (FDNS_NPTS of resolution).
    506  * The noise is shaped monotonically between the two points
    507  * using a curved shape to favor the lower gain in mid-frame.
    508  * ODFT and amplitud calculation are applied to the 2 LPC coefficients first.
    509  *
    510  * \param r pointer to spectrum data.
    511  * \param rms RMS of output spectrum.
    512  * \param lg length of r.
    513  * \param A1 pointer to old input LPC coefficients of length M_LP_FILTER_ORDER
    514  * scaled by SF_A_COEFFS.
    515  * \param A2 pointer to new input LPC coefficients of length M_LP_FILTER_ORDER
    516  * scaled by SF_A_COEFFS.
    517  * \param bLpc2Mdct flags control lpc2mdct conversion and noise shaping.
    518  * \param gainLpc1 pointer to gain based on old input LPC coefficients.
    519  * \param gainLpc2 pointer to gain based on new input LPC coefficients.
    520  * \param gLpc_e pointer to exponent of gainLpc1 and gainLpc2.
    521  */
    522 /* static */
    523 #define NSHAPE_SCALE (4)
    524 
    525 #define LPC2MDCT_CALC (1)
    526 #define LPC2MDCT_GAIN_LOAD (2)
    527 #define LPC2MDCT_GAIN_SAVE (4)
    528 #define LPC2MDCT_APPLY_NSHAPE (8)
    529 
    530 void lpc2mdctAndNoiseShaping(FIXP_DBL *r, SHORT *pScale, const INT lg,
    531                              const INT fdns_npts, const FIXP_LPC *A1,
    532                              const INT A1_exp, const FIXP_LPC *A2,
    533                              const INT A2_exp) {
    534   FIXP_DBL *tmp2 = NULL;
    535   FIXP_DBL rr_minus_one;
    536   int i, k, s, step;
    537 
    538   C_AALLOC_SCRATCH_START(tmp1, FIXP_DBL, FDNS_NPTS * 8)
    539 
    540   {
    541     tmp2 = tmp1 + fdns_npts * 4;
    542 
    543     /* lpc2mdct() */
    544 
    545     /* ODFT. E_LPC_a_weight() for A1 and A2 vectors is included into the loop
    546      * below. */
    547     FIXP_DBL f = FL2FXCONST_DBL(0.92f);
    548 
    549     const FIXP_STP *SinTab;
    550     int k_step;
    551     /* needed values: sin(phi), cos(phi); phi = i*PI/(2*fdns_npts), i = 0 ...
    552      * M_LP_FILTER_ORDER */
    553     switch (fdns_npts) {
    554       case 64:
    555         SinTab = SineTable512;
    556         k_step = (512 / 64);
    557         FDK_ASSERT(512 >= 64);
    558         break;
    559       case 48:
    560         SinTab = SineTable384;
    561         k_step = 384 / 48;
    562         FDK_ASSERT(384 >= 48);
    563         break;
    564       default:
    565         FDK_ASSERT(0);
    566         return;
    567     }
    568 
    569     for (i = 0, k = k_step; i < M_LP_FILTER_ORDER; i++, k += k_step) {
    570       FIXP_STP cs = SinTab[k];
    571       FIXP_DBL wA1, wA2;
    572 
    573       wA1 = fMult(A1[i], f);
    574       wA2 = fMult(A2[i], f);
    575 
    576       /* r[i] = A[i]*cos() */
    577       tmp1[2 + i * 2] = fMult(wA1, cs.v.re);
    578       tmp2[2 + i * 2] = fMult(wA2, cs.v.re);
    579       /* i[i] = A[i]*sin() */
    580       tmp1[3 + i * 2] = -fMult(wA1, cs.v.im);
    581       tmp2[3 + i * 2] = -fMult(wA2, cs.v.im);
    582 
    583       f = fMult(f, FL2FXCONST_DBL(0.92f));
    584     }
    585 
    586     /* Guarantee at least 2 bits of headroom for the FFT */
    587     /* "3" stands for 1.0 with 2 bits of headroom; (A1_exp + 2) guarantess 2
    588      * bits of headroom if A1_exp > 1 */
    589     int A1_exp_fix = fMax(3, A1_exp + 2);
    590     int A2_exp_fix = fMax(3, A2_exp + 2);
    591 
    592     /* Set 1.0 in the proper format */
    593     tmp1[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A1_exp_fix);
    594     tmp2[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A2_exp_fix);
    595 
    596     tmp1[1] = tmp2[1] = (FIXP_DBL)0;
    597 
    598     /* Clear the resto of the array */
    599     FDKmemclear(
    600         tmp1 + 2 * (M_LP_FILTER_ORDER + 1),
    601         2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
    602     FDKmemclear(
    603         tmp2 + 2 * (M_LP_FILTER_ORDER + 1),
    604         2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
    605 
    606     /* Guarantee 2 bits of headroom for FFT */
    607     scaleValues(&tmp1[2], (2 * M_LP_FILTER_ORDER), (A1_exp - A1_exp_fix));
    608     scaleValues(&tmp2[2], (2 * M_LP_FILTER_ORDER), (A2_exp - A2_exp_fix));
    609 
    610     INT s2;
    611     s = A1_exp_fix;
    612     s2 = A2_exp_fix;
    613 
    614     fft(2 * fdns_npts, tmp1, &s);
    615     fft(2 * fdns_npts, tmp2, &s2);
    616 
    617     /* Adjust the exponents of both fft outputs if necessary*/
    618     if (s > s2) {
    619       scaleValues(tmp2, 2 * fdns_npts, s2 - s);
    620       s2 = s;
    621     } else if (s < s2) {
    622       scaleValues(tmp1, 2 * fdns_npts, s - s2);
    623       s = s2;
    624     }
    625 
    626     FDK_ASSERT(s == s2);
    627   }
    628 
    629   /* Get amplitude and apply gains */
    630   step = lg / fdns_npts;
    631   rr_minus_one = (FIXP_DBL)0;
    632 
    633   for (k = 0; k < fdns_npts; k++) {
    634     FIXP_DBL g1, g2, inv_g1_g2, a, b;
    635     INT inv_g1_g2_e;
    636     int g_e, shift;
    637 
    638     {
    639       FIXP_DBL real, imag;
    640       int si1, si2, sInput;
    641 
    642       real = tmp1[k * 2];
    643       imag = tmp1[k * 2 + 1];
    644       sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
    645       real <<= sInput;
    646       imag <<= sInput;
    647       /* g1_e = si1 - 2*s/2 */
    648       g1 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si1);
    649       si1 += sInput;
    650 
    651       real = tmp2[k * 2];
    652       imag = tmp2[k * 2 + 1];
    653       sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
    654       real <<= sInput;
    655       imag <<= sInput;
    656       /* g2_e = si2 - 2*s/2 */
    657       g2 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si2);
    658       si2 += sInput;
    659 
    660       /* Pick a common scale factor for g1 and g2 */
    661       if (si1 > si2) {
    662         g2 >>= si1 - si2;
    663         g_e = si1 - s;
    664       } else {
    665         g1 >>= si2 - si1;
    666         g_e = si2 - s;
    667       }
    668     }
    669 
    670     /* end of lpc2mdct() */
    671 
    672     FDK_ASSERT(g1 >= (FIXP_DBL)0);
    673     FDK_ASSERT(g2 >= (FIXP_DBL)0);
    674 
    675     /* mdct_IntNoiseShaping() */
    676     {
    677       /* inv_g1_g2 * 2^inv_g1_g2_e = 1/(g1+g2) */
    678       inv_g1_g2 = (g1 >> 1) + (g2 >> 1);
    679       if (inv_g1_g2 != (FIXP_DBL)0) {
    680         inv_g1_g2 = fDivNorm(FL2FXCONST_DBL(0.5f), inv_g1_g2, &inv_g1_g2_e);
    681         inv_g1_g2_e = inv_g1_g2_e - g_e;
    682       } else {
    683         inv_g1_g2 = (FIXP_DBL)MAXVAL_DBL;
    684         inv_g1_g2_e = 0;
    685       }
    686 
    687       if (g_e < 0) {
    688         /* a_e = g_e + inv_g1_g2_e + 1 */
    689         a = scaleValue(fMult(fMult(g1, g2), inv_g1_g2), g_e);
    690         /* b_e = g_e + inv_g1_g2_e */
    691         b = fMult(g2 - g1, inv_g1_g2);
    692         shift = g_e + inv_g1_g2_e + 1 - NSHAPE_SCALE;
    693       } else {
    694         /* a_e = (g_e+g_e) + inv_g1_g2_e + 1 */
    695         a = fMult(fMult(g1, g2), inv_g1_g2);
    696         /* b_e = (g_e+g_e) + inv_g1_g2_e */
    697         b = scaleValue(fMult(g2 - g1, inv_g1_g2), -g_e);
    698         shift = (g_e + g_e) + inv_g1_g2_e + 1 - NSHAPE_SCALE;
    699       }
    700 
    701       for (i = k * step; i < (k + 1) * step; i++) {
    702         FIXP_DBL tmp;
    703 
    704         /* rr[i] = 2*a*r[i] + b*rr[i-1] */
    705         tmp = fMult(a, r[i]);
    706         tmp += scaleValue(fMultDiv2(b, rr_minus_one), NSHAPE_SCALE);
    707         tmp = scaleValueSaturate(tmp, shift);
    708         rr_minus_one = tmp;
    709         r[i] = tmp;
    710       }
    711     }
    712   }
    713 
    714   /* end of mdct_IntNoiseShaping() */
    715   { *pScale += NSHAPE_SCALE; }
    716 
    717   C_AALLOC_SCRATCH_END(tmp1, FIXP_DBL, FDNS_NPTS * 8)
    718 }
    719 
    720 /**
    721  * \brief Calculates the energy.
    722  * \param r pointer to spectrum.
    723  * \param rs scale factor of spectrum r.
    724  * \param lg frame length in audio samples.
    725  * \param rms_e pointer to exponent of energy value.
    726  * \return mantissa of energy value.
    727  */
    728 static FIXP_DBL calcEnergy(const FIXP_DBL *r, const SHORT rs, const INT lg,
    729                            INT *rms_e) {
    730   int headroom = getScalefactor(r, lg);
    731 
    732   FIXP_DBL rms_m = 0;
    733 
    734   /* Calculate number of growth bits due to addition */
    735   INT shift = (INT)(fNormz((FIXP_DBL)lg));
    736   shift = 31 - shift;
    737 
    738   /* Generate 1e-2 in Q-6.37 */
    739   const FIXP_DBL value0_01 = 0x51eb851e;
    740   const INT value0_01_exp = -6;
    741 
    742   /* Find the exponent of the resulting energy value */
    743   *rms_e = ((rs - headroom) << 1) + shift + 1;
    744 
    745   INT delta = *rms_e - value0_01_exp;
    746   if (delta > 0) {
    747     /* Limit shift_to 31*/
    748     delta = fMin(31, delta);
    749     rms_m = value0_01 >> delta;
    750   } else {
    751     rms_m = value0_01;
    752     *rms_e = value0_01_exp;
    753     shift = shift - delta;
    754     /* Limit shift_to 31*/
    755     shift = fMin(31, shift);
    756   }
    757 
    758   for (int i = 0; i < lg; i++) {
    759     rms_m += fPow2Div2(r[i] << headroom) >> shift;
    760   }
    761 
    762   return rms_m;
    763 }
    764 
    765 /**
    766  * \brief TCX gain calculation.
    767  * \param pAacDecoderChannelInfo channel context data.
    768  * \param r output spectrum.
    769  * \param rms_e pointer to mantissa of energy value.
    770  * \param rms_e pointer to exponent of energy value.
    771  * \param frame the frame index of the LPD super frame.
    772  * \param lg the frame length in audio samples.
    773  * \param gain_m pointer to mantissa of TCX gain.
    774  * \param gain_e pointer to exponent of TCX gain.
    775  * \param elFlags element specific parser guidance flags.
    776  * \param lg_fb the fullband frame length in audio samples.
    777  * \param IGF_bgn the IGF start index.
    778  */
    779 static void calcTCXGain(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    780                         FIXP_DBL *r, FIXP_DBL rms_m, INT rms_e, const INT frame,
    781                         const INT lg) {
    782   if ((rms_m != (FIXP_DBL)0)) {
    783     FIXP_DBL tcx_gain_m;
    784     INT tcx_gain_e;
    785 
    786     CLpd_DecodeGain(&tcx_gain_m, &tcx_gain_e,
    787                     pAacDecoderChannelInfo->pDynData->specificTo.usac
    788                         .tcx_global_gain[frame]);
    789 
    790     /* rms * 2^rms_e = lg/sqrt(sum(spec^2)) */
    791     if (rms_e & 1) {
    792       rms_m >>= 1;
    793       rms_e++;
    794     }
    795 
    796     {
    797       FIXP_DBL fx_lg;
    798       INT fx_lg_e, s;
    799       INT inv_e;
    800 
    801       /* lg = fx_lg * 2^fx_lg_e */
    802       s = fNorm((FIXP_DBL)lg);
    803       fx_lg = (FIXP_DBL)lg << s;
    804       fx_lg_e = DFRACT_BITS - 1 - s;
    805       /* 1/sqrt(rms) */
    806       rms_m = invSqrtNorm2(rms_m, &inv_e);
    807       rms_m = fMult(rms_m, fx_lg);
    808       rms_e = inv_e - (rms_e >> 1) + fx_lg_e;
    809     }
    810 
    811     {
    812       int s = fNorm(tcx_gain_m);
    813       tcx_gain_m = tcx_gain_m << s;
    814       tcx_gain_e -= s;
    815     }
    816 
    817     tcx_gain_m = fMultDiv2(tcx_gain_m, rms_m);
    818     tcx_gain_e = tcx_gain_e + rms_e;
    819 
    820     /* global_gain * 2^(global_gain_e+rms_e) = (10^(global_gain/28)) * rms *
    821      * 2^rms_e */
    822     {
    823       { tcx_gain_e += 1; }
    824     }
    825 
    826     pAacDecoderChannelInfo->data.usac.tcx_gain[frame] = tcx_gain_m;
    827     pAacDecoderChannelInfo->data.usac.tcx_gain_e[frame] = tcx_gain_e;
    828 
    829     pAacDecoderChannelInfo->specScale[frame] += tcx_gain_e;
    830   }
    831 }
    832 
    833 /**
    834  * \brief FDNS decoding.
    835  * \param pAacDecoderChannelInfo channel context data.
    836  * \param pAacDecoderStaticChannelInfo channel context static data.
    837  * \param r output spectrum.
    838  * \param lg the frame length in audio samples.
    839  * \param frame the frame index of the LPD super frame.
    840  * \param pScale pointer to current scale shift factor of r[].
    841  * \param A1 old input LPC coefficients of length M_LP_FILTER_ORDER.
    842  * \param A2 new input LPC coefficients of length M_LP_FILTER_ORDER.
    843  * \param pAlfdGains pointer for ALFD gains output scaled by 1.
    844  * \param fdns_npts number of lines (FDNS_NPTS).
    845  * \param inf_mask pointer to noise mask.
    846  * \param IGF_win_mode IGF window mode (LONG, SHORT, TCX10, TCX20).
    847  * \param frameType (IGF_FRAME_DIVISION_AAC_OR_TCX_LONG or
    848  * IGF_FRAME_DIVISION_TCX_SHORT_1).
    849  * \param elFlags element specific parser guidance flags.
    850  * \param lg_fb the fullband frame length in audio samples.
    851  * \param IGF_bgn the IGF start index.
    852  * \param rms_m mantisse of energy.
    853  * \param rms_e exponent of energy.
    854  */
    855 /* static */
    856 void CLpd_FdnsDecode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    857                      CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
    858                      FIXP_DBL r[], const INT lg, const INT frame, SHORT *pScale,
    859                      const FIXP_LPC A1[M_LP_FILTER_ORDER], const INT A1_exp,
    860                      const FIXP_LPC A2[M_LP_FILTER_ORDER], const INT A2_exp,
    861                      FIXP_DBL pAlfdGains[LFAC / 4], const INT fdns_npts) {
    862   /* Weight LPC coefficients using Rm values */
    863   CLpd_AdaptLowFreqDeemph(r, lg, pAlfdGains, *pScale);
    864 
    865   FIXP_DBL rms_m = (FIXP_DBL)0;
    866   INT rms_e = 0;
    867   {
    868     /* Calculate Energy */
    869     rms_m = calcEnergy(r, *pScale, lg, &rms_e);
    870   }
    871 
    872   calcTCXGain(pAacDecoderChannelInfo, r, rms_m, rms_e, frame, lg);
    873 
    874   /* Apply ODFT and Noise Shaping. LP coefficient (A1, A2) weighting is done
    875    * inside on the fly. */
    876 
    877   lpc2mdctAndNoiseShaping(r, pScale, lg, fdns_npts, A1, A1_exp, A2, A2_exp);
    878 }
    879 
    880 /**
    881  * find pitch for TCX20 (time domain) concealment.
    882  */
    883 static int find_mpitch(FIXP_DBL xri[], int lg) {
    884   FIXP_DBL max, pitch;
    885   INT pitch_e;
    886   int i, n;
    887 
    888   max = (FIXP_DBL)0;
    889   n = 2;
    890 
    891   /* find maximum below 400Hz */
    892   for (i = 2; i < (lg >> 4); i += 2) {
    893     FIXP_DBL tmp = fPow2Div2(xri[i]) + fPow2Div2(xri[i + 1]);
    894     if (tmp > max) {
    895       max = tmp;
    896       n = i;
    897     }
    898   }
    899 
    900   // pitch = ((float)lg<<1)/(float)n;
    901   pitch = fDivNorm((FIXP_DBL)lg << 1, (FIXP_DBL)n, &pitch_e);
    902   pitch >>= fixMax(0, DFRACT_BITS - 1 - pitch_e - 16);
    903 
    904   /* find pitch multiple under 20ms */
    905   if (pitch >= (FIXP_DBL)((256 << 16) - 1)) { /*231.0f*/
    906     n = 256;
    907   } else {
    908     FIXP_DBL mpitch = pitch;
    909     while (mpitch < (FIXP_DBL)(255 << 16)) {
    910       mpitch += pitch;
    911     }
    912     n = (int)(mpitch - pitch) >> 16;
    913   }
    914 
    915   return (n);
    916 }
    917 
    918 /**
    919  * number of spectral coefficients / time domain samples using frame mode as
    920  * index.
    921  */
    922 static const int lg_table_ccfl[2][4] = {
    923     {256, 256, 512, 1024}, /* coreCoderFrameLength = 1024 */
    924     {192, 192, 384, 768}   /* coreCoderFrameLength = 768  */
    925 };
    926 
    927 /**
    928  * \brief Decode and render one MDCT-TCX frame.
    929  * \param pAacDecoderChannelInfo channel context data.
    930  * \param lg the frame length in audio samples.
    931  * \param frame the frame index of the LPD super frame.
    932  */
    933 static void CLpd_TcxDecode(
    934     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
    935     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags,
    936     int mod, int last_mod, int frame, int frameOk) {
    937   FIXP_DBL *pAlfd_gains = pAacDecoderStaticChannelInfo->last_alfd_gains;
    938   ULONG *pSeed = &pAacDecoderStaticChannelInfo->nfRandomSeed;
    939   int lg = (pAacDecoderChannelInfo->granuleLength == 128)
    940                ? lg_table_ccfl[0][mod + 0]
    941                : lg_table_ccfl[1][mod + 0];
    942   int next_frame = frame + (1 << (mod - 1));
    943   int isFullBandLpd = 0;
    944 
    945   /* Obtain r[] vector by combining the quant[] and noise[] vectors */
    946   {
    947     FIXP_DBL noise_level;
    948     FIXP_DBL *coeffs =
    949         SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
    950                  pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
    951     int scale = pAacDecoderChannelInfo->specScale[frame];
    952     int i, nfBgn, nfEnd;
    953     UCHAR tcx_noise_factor = pAacDecoderChannelInfo->pDynData->specificTo.usac
    954                                  .tcx_noise_factor[frame];
    955 
    956     /* find pitch for bfi case */
    957     pAacDecoderStaticChannelInfo->last_tcx_pitch = find_mpitch(coeffs, lg);
    958 
    959     if (frameOk) {
    960       /* store for concealment */
    961       pAacDecoderStaticChannelInfo->last_tcx_noise_factor = tcx_noise_factor;
    962     } else {
    963       /* restore last frames value */
    964       tcx_noise_factor = pAacDecoderStaticChannelInfo->last_tcx_noise_factor;
    965     }
    966 
    967     noise_level =
    968         (FIXP_DBL)((LONG)FL2FXCONST_DBL(0.0625f) * (8 - tcx_noise_factor));
    969     noise_level = scaleValue(noise_level, -scale);
    970 
    971     const FIXP_DBL neg_noise_level = -noise_level;
    972 
    973     {
    974       nfBgn = lg / 6;
    975       nfEnd = lg;
    976     }
    977 
    978     for (i = nfBgn; i < nfEnd - 7; i += 8) {
    979       LONG tmp;
    980 
    981       /* Fill all 8 consecutive zero coeffs with noise */
    982       tmp = coeffs[i + 0] | coeffs[i + 1] | coeffs[i + 2] | coeffs[i + 3] |
    983             coeffs[i + 4] | coeffs[i + 5] | coeffs[i + 6] | coeffs[i + 7];
    984 
    985       if (tmp == 0) {
    986         for (int k = i; k < i + 8; k++) {
    987           UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
    988                                 : (coeffs[k] = noise_level);
    989         }
    990       }
    991     }
    992     if ((nfEnd - i) >
    993         0) { /* noise filling for last "band" with less than 8 bins */
    994       LONG tmp = (LONG)coeffs[i];
    995       int k;
    996 
    997       FDK_ASSERT((nfEnd - i) < 8);
    998       for (k = 1; k < (nfEnd - i); k++) {
    999         tmp |= (LONG)coeffs[i + k];
   1000       }
   1001       if (tmp == 0) {
   1002         for (k = i; k < nfEnd; k++) {
   1003           UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
   1004                                 : (coeffs[k] = noise_level);
   1005         }
   1006       }
   1007     }
   1008   }
   1009 
   1010   {
   1011     /* Convert LPC to LP domain */
   1012     if (last_mod == 0) {
   1013       /* Note: The case where last_mod == 255 is handled by other means
   1014        * in CLpdChannelStream_Read() */
   1015       E_LPC_f_lsp_a_conversion(
   1016           pAacDecoderChannelInfo->data.usac.lsp_coeff[frame],
   1017           pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
   1018           &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame]);
   1019     }
   1020 
   1021     E_LPC_f_lsp_a_conversion(
   1022         pAacDecoderChannelInfo->data.usac.lsp_coeff[next_frame],
   1023         pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
   1024         &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame]);
   1025 
   1026     /* FDNS decoding */
   1027     CLpd_FdnsDecode(
   1028         pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
   1029         SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
   1030                  pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
   1031         lg, frame, pAacDecoderChannelInfo->specScale + frame,
   1032         pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
   1033         pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame],
   1034         pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
   1035         pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame], pAlfd_gains,
   1036         pAacDecoderChannelInfo->granuleLength / 2 /* == FDNS_NPTS(ccfl) */
   1037     );
   1038   }
   1039 }
   1040 
   1041 /**
   1042  * \brief Read the tcx_coding bitstream part
   1043  * \param hBs bitstream handle to read from.
   1044  * \param pAacDecoderChannelInfo channel context info to store data into.
   1045  * \param lg the frame length in audio samples.
   1046  * \param first_tcx_flag flag indicating that this is the first TCX frame.
   1047  * \param frame the frame index of the LPD super frame.
   1048  */
   1049 static AAC_DECODER_ERROR CLpd_TCX_Read(
   1050     HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
   1051     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, int lg,
   1052     int first_tcx_flag, int frame, UINT flags) {
   1053   AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
   1054   ARITH_CODING_ERROR error = ARITH_CODER_OK;
   1055   FIXP_DBL *pSpec;
   1056   int arith_reset_flag = 0;
   1057   int isFullBandLpd = 0;
   1058 
   1059   pSpec = SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
   1060                    pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
   1061 
   1062   /* TCX noise level */
   1063   {
   1064     pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_noise_factor[frame] =
   1065         FDKreadBits(hBs, 3);
   1066   }
   1067   /* TCX global gain */
   1068   pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_global_gain[frame] =
   1069       FDKreadBits(hBs, 7);
   1070 
   1071   /* Arithmetic coded residual/spectrum */
   1072   if (first_tcx_flag) {
   1073     if (flags & AC_INDEP) {
   1074       arith_reset_flag = 1;
   1075     } else {
   1076       arith_reset_flag = FDKreadBits(hBs, 1);
   1077     }
   1078   }
   1079 
   1080   /* CArco_DecodeArithData() output scale of "pSpec" is DFRACT_BITS-1 */
   1081   error = CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs, pSpec,
   1082                                 lg, lg, arith_reset_flag);
   1083 
   1084   /* Rescale residual/spectrum */
   1085   {
   1086     int scale = getScalefactor(pSpec, lg) - 2; /* Leave 2 bits headroom */
   1087 
   1088     /* Exponent of CArco_DecodeArithData() output is DFRACT_BITS; integer
   1089      * values. */
   1090     scaleValues(pSpec, lg, scale);
   1091     scale = DFRACT_BITS - 1 - scale;
   1092 
   1093     pAacDecoderChannelInfo->specScale[frame] = scale;
   1094   }
   1095 
   1096   if (error == ARITH_CODER_ERROR) errorAAC = AAC_DEC_UNKNOWN;
   1097 
   1098   return errorAAC;
   1099 }
   1100 
   1101 /**
   1102  * \brief translate lpd_mode into the mod[] array which describes the mode of
   1103  * each each LPD frame
   1104  * \param mod[] the array that will be filled with the mode indexes of the
   1105  * inidividual frames.
   1106  * \param lpd_mode the lpd_mode field read from the lpd_channel_stream
   1107  */
   1108 static AAC_DECODER_ERROR CLpd_ReadAndMapLpdModeToModArray(
   1109     UCHAR mod[4], HANDLE_FDK_BITSTREAM hBs, UINT elFlags) {
   1110   int lpd_mode;
   1111 
   1112   {
   1113     lpd_mode = FDKreadBits(hBs, 5);
   1114 
   1115     if (lpd_mode > 25 || lpd_mode < 0) {
   1116       return AAC_DEC_PARSE_ERROR;
   1117     }
   1118 
   1119     switch (lpd_mode) {
   1120       case 25:
   1121         /* 1 80MS frame */
   1122         mod[0] = mod[1] = mod[2] = mod[3] = 3;
   1123         break;
   1124       case 24:
   1125         /* 2 40MS frames */
   1126         mod[0] = mod[1] = mod[2] = mod[3] = 2;
   1127         break;
   1128       default:
   1129         switch (lpd_mode >> 2) {
   1130           case 4:
   1131             /* lpd_mode 19 - 16  => 1 40MS and 2 20MS frames */
   1132             mod[0] = mod[1] = 2;
   1133             mod[2] = (lpd_mode & 1) ? 1 : 0;
   1134             mod[3] = (lpd_mode & 2) ? 1 : 0;
   1135             break;
   1136           case 5:
   1137             /* lpd_mode 23 - 20 => 2 20MS and 1 40MS frames */
   1138             mod[2] = mod[3] = 2;
   1139             mod[0] = (lpd_mode & 1) ? 1 : 0;
   1140             mod[1] = (lpd_mode & 2) ? 1 : 0;
   1141             break;
   1142           default:
   1143             /* lpd_mode < 16 => 4 20MS frames */
   1144             mod[0] = (lpd_mode & 1) ? 1 : 0;
   1145             mod[1] = (lpd_mode & 2) ? 1 : 0;
   1146             mod[2] = (lpd_mode & 4) ? 1 : 0;
   1147             mod[3] = (lpd_mode & 8) ? 1 : 0;
   1148             break;
   1149         }
   1150         break;
   1151     }
   1152   }
   1153   return AAC_DEC_OK;
   1154 }
   1155 
   1156 static void CLpd_Reset(
   1157     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
   1158     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
   1159     int keep_past_signal) {
   1160   int i;
   1161 
   1162   /* Reset TCX / ACELP common memory */
   1163   if (!keep_past_signal) {
   1164     FDKmemclear(pAacDecoderStaticChannelInfo->old_synth,
   1165                 sizeof(pAacDecoderStaticChannelInfo->old_synth));
   1166   }
   1167 
   1168   /* Initialize the LSFs */
   1169   for (i = 0; i < M_LP_FILTER_ORDER; i++) {
   1170     pAacDecoderStaticChannelInfo->lpc4_lsf[i] = fdk_dec_lsf_init[i];
   1171   }
   1172 
   1173   /* Reset memory needed by bass post-filter */
   1174   FDKmemclear(pAacDecoderStaticChannelInfo->mem_bpf,
   1175               sizeof(pAacDecoderStaticChannelInfo->mem_bpf));
   1176 
   1177   pAacDecoderStaticChannelInfo->old_bpf_control_info = 0;
   1178   for (i = 0; i < SYN_SFD; i++) {
   1179     pAacDecoderStaticChannelInfo->old_T_pf[i] = 64;
   1180     pAacDecoderStaticChannelInfo->old_gain_pf[i] = (FIXP_DBL)0;
   1181   }
   1182 
   1183   /* Reset ACELP memory */
   1184   CLpd_AcelpReset(&pAacDecoderStaticChannelInfo->acelp);
   1185 
   1186   pAacDecoderStaticChannelInfo->last_lpc_lost = 0;      /* prev_lpc_lost */
   1187   pAacDecoderStaticChannelInfo->last_tcx_pitch = L_DIV; /* pitch_tcx     */
   1188   pAacDecoderStaticChannelInfo->numLostLpdFrames = 0;   /* nbLostCmpt    */
   1189 }
   1190 
   1191 /*
   1192  * Externally visible functions
   1193  */
   1194 
   1195 AAC_DECODER_ERROR CLpdChannelStream_Read(
   1196     HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
   1197     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
   1198     const SamplingRateInfo *pSamplingRateInfo, UINT flags) {
   1199   AAC_DECODER_ERROR error = AAC_DEC_OK;
   1200   int first_tcx_flag;
   1201   int k, nbDiv, fFacDataPresent, first_lpd_flag, acelp_core_mode,
   1202       facGetMemState = 0;
   1203   UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
   1204   int lpd_mode_last, prev_frame_was_lpd;
   1205   USAC_COREMODE core_mode_last;
   1206   const int lg_table_offset = 0;
   1207   const int *lg_table = (pAacDecoderChannelInfo->granuleLength == 128)
   1208                             ? &lg_table_ccfl[0][lg_table_offset]
   1209                             : &lg_table_ccfl[1][lg_table_offset];
   1210   int last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
   1211 
   1212   int last_frame_ok = CConcealment_GetLastFrameOk(
   1213       &pAacDecoderStaticChannelInfo->concealmentInfo, 1);
   1214 
   1215   INT i_offset;
   1216   UINT samplingRate;
   1217 
   1218   samplingRate = pSamplingRateInfo->samplingRate;
   1219 
   1220   i_offset =
   1221       (INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
   1222       (INT)PIT_MIN_12k8;
   1223 
   1224   if (pSamplingRateInfo->samplingRate >
   1225       FAC_FSCALE_MAX /* maximum allowed core sampling frequency */) {
   1226     error = AAC_DEC_PARSE_ERROR;
   1227     goto bail;
   1228   }
   1229 
   1230   acelp_core_mode = FDKreadBits(hBs, 3);
   1231 
   1232   /* lpd_mode */
   1233   error = CLpd_ReadAndMapLpdModeToModArray(mod, hBs, 0);
   1234   if (error != AAC_DEC_OK) {
   1235     goto bail;
   1236   }
   1237 
   1238   /* bpf_control_info */
   1239   pAacDecoderChannelInfo->data.usac.bpf_control_info = FDKreadBit(hBs);
   1240 
   1241   /* last_core_mode */
   1242   prev_frame_was_lpd = FDKreadBit(hBs);
   1243   /* fac_data_present */
   1244   fFacDataPresent = FDKreadBit(hBs);
   1245 
   1246   /* Set valid values from
   1247    * pAacDecoderStaticChannelInfo->{last_core_mode,last_lpd_mode} */
   1248   pAacDecoderChannelInfo->data.usac.core_mode_last =
   1249       pAacDecoderStaticChannelInfo->last_core_mode;
   1250   lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last =
   1251       pAacDecoderStaticChannelInfo->last_lpd_mode;
   1252 
   1253   if (prev_frame_was_lpd == 0) {
   1254     /* Last frame was FD */
   1255     pAacDecoderChannelInfo->data.usac.core_mode_last = FD_LONG;
   1256     pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
   1257   } else {
   1258     /* Last frame was LPD */
   1259     pAacDecoderChannelInfo->data.usac.core_mode_last = LPD;
   1260     if (((mod[0] == 0) && fFacDataPresent) ||
   1261         ((mod[0] != 0) && !fFacDataPresent)) {
   1262       /* Currend mod is ACELP, fac data present -> TCX, current mod TCX, no fac
   1263        * data -> TCX */
   1264       if (lpd_mode_last == 0) {
   1265         /* Bit stream interruption detected. Assume last TCX mode as TCX20. */
   1266         pAacDecoderChannelInfo->data.usac.lpd_mode_last = 1;
   1267       }
   1268       /* Else assume that remembered TCX mode is correct. */
   1269     } else {
   1270       pAacDecoderChannelInfo->data.usac.lpd_mode_last = 0;
   1271     }
   1272   }
   1273 
   1274   first_lpd_flag = (pAacDecoderChannelInfo->data.usac.core_mode_last !=
   1275                     LPD); /* Depends on bitstream configuration */
   1276   first_tcx_flag = 1;
   1277 
   1278   if (pAacDecoderStaticChannelInfo->last_core_mode !=
   1279       LPD) { /* ATTENTION: Reset depends on what we rendered before! */
   1280     CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo, 0);
   1281 
   1282     if (!last_frame_ok) {
   1283       /* If last rendered frame was not LPD and first lpd flag is not set, this
   1284        * must be an error - set last_lpc_lost flag */
   1285       last_lpc_lost |= (first_lpd_flag) ? 0 : 1;
   1286     }
   1287   }
   1288 
   1289   core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last;
   1290   lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last;
   1291 
   1292   nbDiv = NB_DIV;
   1293 
   1294   /* k is the frame index. If a frame is of size 40MS or 80MS,
   1295      this frame index is incremented 2 or 4 instead of 1 respectively. */
   1296 
   1297   k = 0;
   1298   while (k < nbDiv) {
   1299     /* Reset FAC data pointers in order to avoid applying old random FAC data.
   1300      */
   1301     pAacDecoderChannelInfo->data.usac.fac_data[k] = NULL;
   1302 
   1303     if ((k == 0 && core_mode_last == LPD && fFacDataPresent) ||
   1304         (lpd_mode_last == 0 && mod[k] > 0) ||
   1305         ((lpd_mode_last != 255) && lpd_mode_last > 0 && mod[k] == 0)) {
   1306       int err;
   1307 
   1308       /* Assign FAC memory */
   1309       pAacDecoderChannelInfo->data.usac.fac_data[k] =
   1310           CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);
   1311 
   1312       /* FAC for (ACELP -> TCX) or (TCX -> ACELP) */
   1313       err = CLpd_FAC_Read(
   1314           hBs, pAacDecoderChannelInfo->data.usac.fac_data[k],
   1315           pAacDecoderChannelInfo->data.usac.fac_data_e,
   1316           pAacDecoderChannelInfo->granuleLength, /* == fac_length */
   1317           0, k);
   1318       if (err != 0) {
   1319         error = AAC_DEC_PARSE_ERROR;
   1320         goto bail;
   1321       }
   1322     }
   1323 
   1324     if (mod[k] == 0) /* acelp-mode */
   1325     {
   1326       int err;
   1327       err = CLpd_AcelpRead(
   1328           hBs, &pAacDecoderChannelInfo->data.usac.acelp[k], acelp_core_mode,
   1329           pAacDecoderChannelInfo->granuleLength * 8 /* coreCoderFrameLength */,
   1330           i_offset);
   1331       if (err != 0) {
   1332         error = AAC_DEC_PARSE_ERROR;
   1333         goto bail;
   1334       }
   1335 
   1336       lpd_mode_last = 0;
   1337       k++;
   1338     } else /* mode != 0  =>  TCX */
   1339     {
   1340       error = CLpd_TCX_Read(hBs, pAacDecoderChannelInfo,
   1341                             pAacDecoderStaticChannelInfo, lg_table[mod[k]],
   1342                             first_tcx_flag, k, flags);
   1343 
   1344       lpd_mode_last = mod[k];
   1345       first_tcx_flag = 0;
   1346       k += 1 << (mod[k] - 1);
   1347     }
   1348     if (error != AAC_DEC_OK) {
   1349       error = AAC_DEC_PARSE_ERROR;
   1350       goto bail;
   1351     }
   1352   }
   1353 
   1354   {
   1355     int err;
   1356 
   1357     /* Read LPC coefficients */
   1358     err = CLpc_Read(
   1359         hBs, pAacDecoderChannelInfo->data.usac.lsp_coeff,
   1360         pAacDecoderStaticChannelInfo->lpc4_lsf,
   1361         pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
   1362         pAacDecoderChannelInfo->data.usac.aStability, mod, first_lpd_flag,
   1363         /* if last lpc4 is available from concealment do not extrapolate lpc0
   1364            from lpc2 */
   1365         (mod[0] & 0x3) ? 0
   1366                        : (last_lpc_lost &&
   1367                           pAacDecoderStaticChannelInfo->last_core_mode != LPD),
   1368         last_frame_ok);
   1369     if (err != 0) {
   1370       error = AAC_DEC_PARSE_ERROR;
   1371       goto bail;
   1372     }
   1373   }
   1374 
   1375   /* adjust old lsp[] following to a bad frame (to avoid overshoot) (ref:
   1376    * dec_LPD.c) */
   1377   if (last_lpc_lost && !last_frame_ok) {
   1378     int k_next;
   1379     k = 0;
   1380     while (k < nbDiv) {
   1381       int i;
   1382       k_next = k + (((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1)));
   1383       FIXP_LPC *lsp_old = pAacDecoderChannelInfo->data.usac.lsp_coeff[k];
   1384       FIXP_LPC *lsp_new = pAacDecoderChannelInfo->data.usac.lsp_coeff[k_next];
   1385 
   1386       for (i = 0; i < M_LP_FILTER_ORDER; i++) {
   1387         if (lsp_new[i] < lsp_old[i]) {
   1388           lsp_old[i] = lsp_new[i];
   1389         }
   1390       }
   1391       k = k_next;
   1392     }
   1393   }
   1394 
   1395   if (!CConcealment_GetLastFrameOk(
   1396           &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
   1397     E_LPC_f_lsp_a_conversion(
   1398         pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
   1399         pAacDecoderChannelInfo->data.usac.lp_coeff[0],
   1400         &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
   1401   } else if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) {
   1402     if (pAacDecoderStaticChannelInfo->last_lpd_mode == 255) {
   1403       /* We need it for TCX decoding or ACELP excitation update */
   1404       E_LPC_f_lsp_a_conversion(
   1405           pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
   1406           pAacDecoderChannelInfo->data.usac.lp_coeff[0],
   1407           &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
   1408     } else { /* last_lpd_mode was TCX */
   1409       /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
   1410        * converting LSP coefficients again). */
   1411       FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
   1412                 pAacDecoderStaticChannelInfo->lp_coeff_old[0],
   1413                 M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
   1414       pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
   1415           pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
   1416     }
   1417   } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */
   1418 
   1419   if (fFacDataPresent && (core_mode_last != LPD)) {
   1420     int prev_frame_was_short;
   1421 
   1422     prev_frame_was_short = FDKreadBit(hBs);
   1423 
   1424     if (prev_frame_was_short) {
   1425       core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last =
   1426           FD_SHORT;
   1427       pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
   1428 
   1429       if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) &&
   1430           CConcealment_GetLastFrameOk(
   1431               &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
   1432         /* USAC Conformance document:
   1433            short_fac_flag   shall be encoded with a value of 1 if the
   1434            window_sequence of the previous frame was 2 (EIGHT_SHORT_SEQUENCE).
   1435                             Otherwise short_fac_flag shall be encoded with a
   1436            value of 0. */
   1437         error = AAC_DEC_PARSE_ERROR;
   1438         goto bail;
   1439       }
   1440     }
   1441 
   1442     /* Assign memory */
   1443     pAacDecoderChannelInfo->data.usac.fac_data[0] =
   1444         CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);
   1445 
   1446     {
   1447       int err;
   1448 
   1449       /* FAC for FD -> ACELP */
   1450       err = CLpd_FAC_Read(
   1451           hBs, pAacDecoderChannelInfo->data.usac.fac_data[0],
   1452           pAacDecoderChannelInfo->data.usac.fac_data_e,
   1453           CLpd_FAC_getLength(core_mode_last != FD_SHORT,
   1454                              pAacDecoderChannelInfo->granuleLength),
   1455           1, 0);
   1456       if (err != 0) {
   1457         error = AAC_DEC_PARSE_ERROR;
   1458         goto bail;
   1459       }
   1460     }
   1461   }
   1462 
   1463 bail:
   1464   if (error == AAC_DEC_OK) {
   1465     /* check consitency of last core/lpd mode values */
   1466     if ((pAacDecoderChannelInfo->data.usac.core_mode_last !=
   1467          pAacDecoderStaticChannelInfo->last_core_mode) &&
   1468         (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
   1469       /* Something got wrong! */
   1470       /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
   1471     } else if ((pAacDecoderChannelInfo->data.usac.core_mode_last == LPD) &&
   1472                (pAacDecoderChannelInfo->data.usac.lpd_mode_last !=
   1473                 pAacDecoderStaticChannelInfo->last_lpd_mode) &&
   1474                (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
   1475       /* Something got wrong! */
   1476       /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
   1477     }
   1478   }
   1479 
   1480   return error;
   1481 }
   1482 
   1483 void CLpdChannelStream_Decode(
   1484     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
   1485     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags) {
   1486   UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
   1487   int k;
   1488   UCHAR last_lpd_mode;
   1489   int nbDiv = NB_DIV;
   1490 
   1491   /* k is the frame index. If a frame is of size 40MS or 80MS,
   1492      this frame index is incremented 2 or 4 instead of 1 respectively. */
   1493   k = 0;
   1494   last_lpd_mode =
   1495       pAacDecoderChannelInfo->data.usac
   1496           .lpd_mode_last; /* could be different to what has been rendered */
   1497   while (k < nbDiv) {
   1498     if (mod[k] == 0) {
   1499       /* ACELP */
   1500 
   1501       /* If FAC (fac_data[k] != NULL), and previous frame was TCX, apply (TCX)
   1502        * gains to FAC data */
   1503       if (last_lpd_mode > 0 && last_lpd_mode != 255 &&
   1504           pAacDecoderChannelInfo->data.usac.fac_data[k]) {
   1505         CFac_ApplyGains(pAacDecoderChannelInfo->data.usac.fac_data[k],
   1506                         pAacDecoderChannelInfo->granuleLength,
   1507                         pAacDecoderStaticChannelInfo->last_tcx_gain,
   1508                         pAacDecoderStaticChannelInfo->last_alfd_gains,
   1509                         (last_lpd_mode < 4) ? last_lpd_mode : 3);
   1510 
   1511         pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
   1512             pAacDecoderStaticChannelInfo->last_tcx_gain_e;
   1513       }
   1514     } else {
   1515       /* TCX */
   1516       CLpd_TcxDecode(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
   1517                      flags, mod[k], last_lpd_mode, k, 1 /* frameOk == 1 */
   1518       );
   1519 
   1520       /* Store TCX gain scale for next possible FAC transition. */
   1521       pAacDecoderStaticChannelInfo->last_tcx_gain =
   1522           pAacDecoderChannelInfo->data.usac.tcx_gain[k];
   1523       pAacDecoderStaticChannelInfo->last_tcx_gain_e =
   1524           pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];
   1525 
   1526       /* If FAC (fac_data[k] != NULL), apply gains */
   1527       if (last_lpd_mode == 0 && pAacDecoderChannelInfo->data.usac.fac_data[k]) {
   1528         CFac_ApplyGains(
   1529             pAacDecoderChannelInfo->data.usac.fac_data[k],
   1530             pAacDecoderChannelInfo->granuleLength /* == fac_length */,
   1531             pAacDecoderChannelInfo->data.usac.tcx_gain[k],
   1532             pAacDecoderStaticChannelInfo->last_alfd_gains, mod[k]);
   1533 
   1534         pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
   1535             pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];
   1536       }
   1537     }
   1538 
   1539     /* remember previous mode */
   1540     last_lpd_mode = mod[k];
   1541 
   1542     /* Increase k to next frame */
   1543     k += (mod[k] == 0) ? 1 : (1 << (mod[k] - 1));
   1544   }
   1545 }
   1546 
   1547 AAC_DECODER_ERROR CLpd_RenderTimeSignal(
   1548     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
   1549     CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
   1550     INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags,
   1551     UINT strmFlags) {
   1552   UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
   1553   AAC_DECODER_ERROR error = AAC_DEC_OK;
   1554   int k, i_offset;
   1555   int last_k;
   1556   int nrSamples = 0;
   1557   int facFB = 1;
   1558   int nbDiv = NB_DIV;
   1559   int lDiv = lFrame / nbDiv; /* length of division (acelp or tcx20 frame)*/
   1560   int lFac = lDiv / 2;
   1561   int nbSubfr =
   1562       lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
   1563   int nbSubfrSuperfr = nbDiv * nbSubfr;
   1564   int synSfd = (nbSubfrSuperfr / 2) - BPF_SFD;
   1565   int SynDelay = synSfd * L_SUBFR;
   1566   int aacDelay = lFrame / 2;
   1567 
   1568   /*
   1569    In respect to the reference software, the synth pointer here is lagging by
   1570    aacDelay ( == SYN_DELAY + BPF_DELAY ) samples. The corresponding old
   1571    synthesis samples are handled by the IMDCT overlap.
   1572    */
   1573 
   1574   FIXP_DBL *synth_buf =
   1575       pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->synth_buf;
   1576   FIXP_DBL *synth = synth_buf + PIT_MAX_MAX - BPF_DELAY;
   1577   UCHAR last_lpd_mode, last_last_lpd_mode, last_lpc_lost, last_frame_lost;
   1578 
   1579   INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
   1580   FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];
   1581 
   1582   const int *lg_table;
   1583   int lg_table_offset = 0;
   1584 
   1585   UINT samplingRate = pSamplingRateInfo->samplingRate;
   1586 
   1587   FDKmemclear(pitch, (NB_SUBFR_SUPERFR + SYN_SFD) * sizeof(INT));
   1588 
   1589   if (flags & AACDEC_FLUSH) {
   1590     CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
   1591                flags & AACDEC_FLUSH);
   1592     frameOk = 0;
   1593   }
   1594 
   1595   switch (lFrame) {
   1596     case 1024:
   1597       lg_table = &lg_table_ccfl[0][lg_table_offset];
   1598       break;
   1599     case 768:
   1600       lg_table = &lg_table_ccfl[1][lg_table_offset];
   1601       break;
   1602     default:
   1603       FDK_ASSERT(0);
   1604       return AAC_DEC_UNKNOWN;
   1605   }
   1606 
   1607   last_frame_lost = !CConcealment_GetLastFrameOk(
   1608       &pAacDecoderStaticChannelInfo->concealmentInfo, 0);
   1609 
   1610   /* Maintain LPD mode from previous frame */
   1611   if ((pAacDecoderStaticChannelInfo->last_core_mode == FD_LONG) ||
   1612       (pAacDecoderStaticChannelInfo->last_core_mode == FD_SHORT)) {
   1613     pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
   1614   }
   1615 
   1616   if (!frameOk) {
   1617     FIXP_DBL old_tcx_gain;
   1618     FIXP_SGL old_stab;
   1619     SCHAR old_tcx_gain_e;
   1620     int nLostSf;
   1621 
   1622     last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
   1623     old_tcx_gain = pAacDecoderStaticChannelInfo->last_tcx_gain;
   1624     old_tcx_gain_e = pAacDecoderStaticChannelInfo->last_tcx_gain_e;
   1625     old_stab = pAacDecoderStaticChannelInfo->oldStability;
   1626     nLostSf = pAacDecoderStaticChannelInfo->numLostLpdFrames;
   1627 
   1628     /* patch the last LPD mode */
   1629     pAacDecoderChannelInfo->data.usac.lpd_mode_last = last_lpd_mode;
   1630 
   1631     /* Do mode extrapolation and repeat the previous mode:
   1632        if previous mode = ACELP        -> ACELP
   1633        if previous mode = TCX-20/40    -> TCX-20
   1634        if previous mode = TCX-80       -> TCX-80
   1635        notes:
   1636        - ACELP is not allowed after TCX (no pitch information to reuse)
   1637        - TCX-40 is not allowed in the mode repetition to keep the logic simple
   1638      */
   1639     switch (last_lpd_mode) {
   1640       case 0:
   1641         mod[0] = mod[1] = mod[2] = mod[3] = 0; /* -> ACELP concealment */
   1642         break;
   1643       case 3:
   1644         mod[0] = mod[1] = mod[2] = mod[3] = 3; /* -> TCX FD concealment */
   1645         break;
   1646       case 2:
   1647         mod[0] = mod[1] = mod[2] = mod[3] = 2; /* -> TCX FD concealment */
   1648         break;
   1649       case 1:
   1650       default:
   1651         mod[0] = mod[1] = mod[2] = mod[3] = 4; /* -> TCX TD concealment */
   1652         break;
   1653     }
   1654 
   1655     /* LPC extrapolation */
   1656     CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
   1657                  pAacDecoderStaticChannelInfo->lpc4_lsf,
   1658                  pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
   1659                  /*(pAacDecoderStaticChannelInfo->numLostLpdFrames == 0) ||*/
   1660                  (last_lpd_mode == 255));
   1661 
   1662     if ((last_lpd_mode > 0) && (last_lpd_mode < 255)) {
   1663       /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
   1664        * converting LSP coefficients again). */
   1665       FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
   1666                 pAacDecoderStaticChannelInfo->lp_coeff_old[0],
   1667                 M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
   1668       pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
   1669           pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
   1670     } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */
   1671     /* case last_lpd_mode was Time domain TCX concealment is handled after this
   1672      * "if (!frameOk)"-block */
   1673 
   1674     /* k is the frame index. If a frame is of size 40MS or 80MS,
   1675        this frame index is incremented 2 or 4 instead of 1 respectively. */
   1676     k = 0;
   1677     while (k < nbDiv) {
   1678       pAacDecoderChannelInfo->data.usac.tcx_gain[k] = old_tcx_gain;
   1679       pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] = old_tcx_gain_e;
   1680 
   1681       /* restore stability value from last frame */
   1682       pAacDecoderChannelInfo->data.usac.aStability[k] = old_stab;
   1683 
   1684       /* Increase k to next frame */
   1685       k += ((mod[k] & 0x3) == 0) ? 1 : (1 << ((mod[k] & 0x3) - 1));
   1686 
   1687       nLostSf++;
   1688     }
   1689   } else {
   1690     if ((pAacDecoderStaticChannelInfo->last_lpd_mode == 4) && (mod[0] > 0)) {
   1691       /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
   1692        * converting LSP coefficients again). */
   1693       FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
   1694                 pAacDecoderStaticChannelInfo->lp_coeff_old[0],
   1695                 M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
   1696       pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
   1697           pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
   1698     }
   1699   }
   1700 
   1701   Acelp_PreProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth, pitch,
   1702                       pAacDecoderStaticChannelInfo->old_T_pf, pit_gain,
   1703                       pAacDecoderStaticChannelInfo->old_gain_pf, samplingRate,
   1704                       &i_offset, lFrame, synSfd, nbSubfrSuperfr);
   1705 
   1706   /* k is the frame index. If a frame is of size 40MS or 80MS,
   1707      this frame index is incremented 2 or 4 instead of 1 respectively. */
   1708   k = 0;
   1709   last_k = -1; /* mark invalid */
   1710   last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
   1711   last_last_lpd_mode = pAacDecoderStaticChannelInfo->last_last_lpd_mode;
   1712   last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost | last_frame_lost;
   1713 
   1714   /* This buffer must be avalable for the case of FD->ACELP transition. The
   1715   beginning of the buffer is used after the BPF to overwrite the output signal.
   1716   Only the FAC area must be affected by the BPF */
   1717 
   1718   while (k < nbDiv) {
   1719     if (frameOk == 0) {
   1720       pAacDecoderStaticChannelInfo->numLostLpdFrames++;
   1721     } else {
   1722       last_frame_lost |=
   1723           (pAacDecoderStaticChannelInfo->numLostLpdFrames > 0) ? 1 : 0;
   1724       pAacDecoderStaticChannelInfo->numLostLpdFrames = 0;
   1725     }
   1726     if (mod[k] == 0 || mod[k] == 4) {
   1727       /* ACELP or TCX time domain concealment */
   1728       FIXP_DBL *acelp_out;
   1729 
   1730       /* FAC management */
   1731       if ((last_lpd_mode != 0) && (last_lpd_mode != 4)) /* TCX TD concealment */
   1732       {
   1733         FIXP_DBL *pFacData = NULL;
   1734 
   1735         if (frameOk && !last_frame_lost) {
   1736           pFacData = pAacDecoderChannelInfo->data.usac.fac_data[k];
   1737         }
   1738 
   1739         nrSamples += CLpd_FAC_Mdct2Acelp(
   1740             &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples, pFacData,
   1741             pAacDecoderChannelInfo->data.usac.fac_data_e[k],
   1742             pAacDecoderChannelInfo->data.usac.lp_coeff[k],
   1743             pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
   1744             lFrame - nrSamples,
   1745             CLpd_FAC_getLength(
   1746                 (pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) ||
   1747                     (k > 0),
   1748                 lFac),
   1749             (pAacDecoderStaticChannelInfo->last_core_mode != LPD) && (k == 0),
   1750             0);
   1751 
   1752         FDKmemcpy(
   1753             synth + nrSamples, pAacDecoderStaticChannelInfo->IMdct.overlap.time,
   1754             pAacDecoderStaticChannelInfo->IMdct.ov_offset * sizeof(FIXP_DBL));
   1755         {
   1756           FIXP_LPC *lp_prev =
   1757               pAacDecoderChannelInfo->data.usac
   1758                   .lp_coeff[0]; /* init value does not real matter */
   1759           INT lp_prev_exp = pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0];
   1760 
   1761           if (last_lpd_mode != 255) { /* last mode was tcx */
   1762             last_k = k - (1 << (last_lpd_mode - 1));
   1763             if (last_k < 0) {
   1764               lp_prev = pAacDecoderStaticChannelInfo->lp_coeff_old[1];
   1765               lp_prev_exp = pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1];
   1766             } else {
   1767               lp_prev = pAacDecoderChannelInfo->data.usac.lp_coeff[last_k];
   1768               lp_prev_exp =
   1769                   pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
   1770             }
   1771           }
   1772 
   1773           CLpd_AcelpPrepareInternalMem(
   1774               synth + aacDelay + k * lDiv, last_lpd_mode,
   1775               (last_last_lpd_mode == 4) ? 0 : last_last_lpd_mode,
   1776               pAacDecoderChannelInfo->data.usac.lp_coeff[k],
   1777               pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k], lp_prev,
   1778               lp_prev_exp, &pAacDecoderStaticChannelInfo->acelp, lFrame,
   1779               (last_frame_lost && k < 2), mod[k]);
   1780         }
   1781       } else {
   1782         if (k == 0 && pAacDecoderStaticChannelInfo->IMdct.ov_offset !=
   1783                           lFrame / facFB / 2) {
   1784           pAacDecoderStaticChannelInfo->IMdct.ov_offset = lFrame / facFB / 2;
   1785         }
   1786         nrSamples += imdct_drain(&pAacDecoderStaticChannelInfo->IMdct,
   1787                                  synth + nrSamples, lFrame / facFB - nrSamples);
   1788       }
   1789 
   1790       if (nrSamples >= lFrame / facFB) {
   1791         /* Write ACELP time domain samples into IMDCT overlap buffer at
   1792          * pAacDecoderStaticChannelInfo->IMdct.overlap.time +
   1793          * pAacDecoderStaticChannelInfo->IMdct.ov_offset
   1794          */
   1795         acelp_out = pAacDecoderStaticChannelInfo->IMdct.overlap.time +
   1796                     pAacDecoderStaticChannelInfo->IMdct.ov_offset;
   1797 
   1798         /* Account ACELP time domain output samples to overlap buffer */
   1799         pAacDecoderStaticChannelInfo->IMdct.ov_offset += lDiv;
   1800       } else {
   1801         /* Write ACELP time domain samples into output buffer at pTimeData +
   1802          * nrSamples */
   1803         acelp_out = synth + nrSamples;
   1804 
   1805         /* Account ACELP time domain output samples to output buffer */
   1806         nrSamples += lDiv;
   1807       }
   1808 
   1809       if (mod[k] == 4) {
   1810         pAacDecoderStaticChannelInfo->acelp.wsyn_rms = scaleValue(
   1811             pAacDecoderChannelInfo->data.usac.tcx_gain[k],
   1812             fixMin(0,
   1813                    pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] - SF_EXC));
   1814         CLpd_TcxTDConceal(&pAacDecoderStaticChannelInfo->acelp,
   1815                           &pAacDecoderStaticChannelInfo->last_tcx_pitch,
   1816                           pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
   1817                           pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
   1818                           pAacDecoderChannelInfo->data.usac.aStability[k],
   1819                           pAacDecoderStaticChannelInfo->numLostLpdFrames,
   1820                           acelp_out, lFrame,
   1821                           pAacDecoderStaticChannelInfo->last_tcx_noise_factor);
   1822 
   1823       } else {
   1824         FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[k] >=
   1825                    (FIXP_SGL)0);
   1826         CLpd_AcelpDecode(&pAacDecoderStaticChannelInfo->acelp, i_offset,
   1827                          pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
   1828                          pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
   1829                          pAacDecoderChannelInfo->data.usac.aStability[k],
   1830                          &pAacDecoderChannelInfo->data.usac.acelp[k],
   1831                          pAacDecoderStaticChannelInfo->numLostLpdFrames,
   1832                          last_lpc_lost, k, acelp_out,
   1833                          &pitch[(k * nbSubfr) + synSfd],
   1834                          &pit_gain[(k * nbSubfr) + synSfd], lFrame);
   1835       }
   1836 
   1837       if (mod[k] != 4) {
   1838         if (last_lpd_mode != 0 &&
   1839             pAacDecoderChannelInfo->data.usac
   1840                 .bpf_control_info) { /* FD/TCX -> ACELP transition */
   1841           /* bass post-filter past FAC area (past two (one for FD short)
   1842            * subframes) */
   1843           int currentSf = synSfd + k * nbSubfr;
   1844 
   1845           if ((k > 0) || (pAacDecoderStaticChannelInfo->last_core_mode !=
   1846                           FD_SHORT)) { /* TCX or FD long -> ACELP */
   1847             pitch[currentSf - 2] = pitch[currentSf - 1] = pitch[currentSf];
   1848             pit_gain[currentSf - 2] = pit_gain[currentSf - 1] =
   1849                 pit_gain[currentSf];
   1850           } else { /* FD short -> ACELP */
   1851             pitch[currentSf - 1] = pitch[currentSf];
   1852             pit_gain[currentSf - 1] = pit_gain[currentSf];
   1853           }
   1854         }
   1855       }
   1856     } else { /* TCX */
   1857       int lg = lg_table[mod[k]];
   1858       int isFullBandLpd = 0;
   1859 
   1860       /* FAC management */
   1861       if ((last_lpd_mode == 0) || (last_lpd_mode == 4)) /* TCX TD concealment */
   1862       {
   1863         C_AALLOC_SCRATCH_START(fac_buf, FIXP_DBL, 1024 / 8);
   1864 
   1865         /* pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL means no FAC
   1866          * data available. */
   1867         if (last_frame_lost == 1 ||
   1868             pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL) {
   1869           FDKmemclear(fac_buf, 1024 / 8 * sizeof(FIXP_DBL));
   1870           pAacDecoderChannelInfo->data.usac.fac_data[k] = fac_buf;
   1871           pAacDecoderChannelInfo->data.usac.fac_data_e[k] = 0;
   1872         }
   1873 
   1874         nrSamples += CLpd_FAC_Acelp2Mdct(
   1875             &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
   1876             SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
   1877                      pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
   1878             pAacDecoderChannelInfo->specScale + k, 1,
   1879             pAacDecoderChannelInfo->data.usac.fac_data[k],
   1880             pAacDecoderChannelInfo->data.usac.fac_data_e[k],
   1881             pAacDecoderChannelInfo->granuleLength /* == fac_length */,
   1882             lFrame - nrSamples, lg,
   1883             FDKgetWindowSlope(lDiv,
   1884                               GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
   1885             lDiv, pAacDecoderChannelInfo->data.usac.lp_coeff[k],
   1886             pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
   1887             &pAacDecoderStaticChannelInfo->acelp,
   1888             pAacDecoderChannelInfo->data.usac.tcx_gain[k],
   1889             (last_frame_lost || !frameOk), 0 /* is not FD FAC */
   1890             ,
   1891             last_lpd_mode, k,
   1892             pAacDecoderChannelInfo
   1893                 ->currAliasingSymmetry /* Note: The current aliasing
   1894                                           symmetry for a TCX (i.e. LPD)
   1895                                           frame must always be 0 */
   1896         );
   1897 
   1898         pitch[(k * nbSubfr) + synSfd + 1] = pitch[(k * nbSubfr) + synSfd] =
   1899             pitch[(k * nbSubfr) + synSfd - 1];
   1900         pit_gain[(k * nbSubfr) + synSfd + 1] =
   1901             pit_gain[(k * nbSubfr) + synSfd] =
   1902                 pit_gain[(k * nbSubfr) + synSfd - 1];
   1903 
   1904         C_AALLOC_SCRATCH_END(fac_buf, FIXP_DBL, 1024 / 8);
   1905       } else {
   1906         int tl = lg;
   1907         int fl = lDiv;
   1908         int fr = lDiv;
   1909 
   1910         nrSamples += imlt_block(
   1911             &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
   1912             SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
   1913                      pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
   1914             pAacDecoderChannelInfo->specScale + k, 1, lFrame - nrSamples, tl,
   1915             FDKgetWindowSlope(fl,
   1916                               GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
   1917             fl,
   1918             FDKgetWindowSlope(fr,
   1919                               GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
   1920             fr, pAacDecoderChannelInfo->data.usac.tcx_gain[k],
   1921             pAacDecoderChannelInfo->currAliasingSymmetry
   1922                 ? MLT_FLAG_CURR_ALIAS_SYMMETRY
   1923                 : 0);
   1924       }
   1925     }
   1926     /* remember previous mode */
   1927     last_last_lpd_mode = last_lpd_mode;
   1928     last_lpd_mode = mod[k];
   1929     last_lpc_lost = (frameOk == 0) ? 1 : 0;
   1930 
   1931     /* Increase k to next frame */
   1932     last_k = k;
   1933     k += ((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1));
   1934   }
   1935 
   1936   if (frameOk) {
   1937     /* assume data was ok => store for concealment */
   1938     FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[last_k] >=
   1939                (FIXP_SGL)0);
   1940     pAacDecoderStaticChannelInfo->oldStability =
   1941         pAacDecoderChannelInfo->data.usac.aStability[last_k];
   1942     FDKmemcpy(pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
   1943               pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
   1944               M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
   1945   }
   1946 
   1947   /* store past lp coeffs for next superframe (they are only valid and needed if
   1948    * last_lpd_mode was tcx) */
   1949   if (last_lpd_mode > 0) {
   1950     FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[0],
   1951               pAacDecoderChannelInfo->data.usac.lp_coeff[nbDiv],
   1952               M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
   1953     pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0] =
   1954         pAacDecoderChannelInfo->data.usac.lp_coeff_exp[nbDiv];
   1955     FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[1],
   1956               pAacDecoderChannelInfo->data.usac.lp_coeff[last_k],
   1957               M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
   1958     pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1] =
   1959         pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
   1960   }
   1961 
   1962   FDK_ASSERT(nrSamples == lFrame);
   1963 
   1964   /* check whether usage of bass postfilter was de-activated in the bitstream;
   1965    if yes, set pitch gain to 0 */
   1966   if (!(pAacDecoderChannelInfo->data.usac.bpf_control_info)) {
   1967     if (mod[0] != 0 && (pAacDecoderStaticChannelInfo->old_bpf_control_info)) {
   1968       for (int i = 2; i < nbSubfrSuperfr; i++)
   1969         pit_gain[synSfd + i] = (FIXP_DBL)0;
   1970     } else {
   1971       for (int i = 0; i < nbSubfrSuperfr; i++)
   1972         pit_gain[synSfd + i] = (FIXP_DBL)0;
   1973     }
   1974   }
   1975 
   1976   /* for bass postfilter */
   1977   for (int n = 0; n < synSfd; n++) {
   1978     pAacDecoderStaticChannelInfo->old_T_pf[n] = pitch[nbSubfrSuperfr + n];
   1979     pAacDecoderStaticChannelInfo->old_gain_pf[n] = pit_gain[nbSubfrSuperfr + n];
   1980   }
   1981 
   1982   pAacDecoderStaticChannelInfo->old_bpf_control_info =
   1983       pAacDecoderChannelInfo->data.usac.bpf_control_info;
   1984 
   1985   {
   1986     INT lookahead = -BPF_DELAY;
   1987     int copySamp = (mod[nbDiv - 1] == 0) ? (aacDelay) : (aacDelay - lFac);
   1988 
   1989     /* Copy enough time domain samples from MDCT to synthesis buffer as needed
   1990      * by the bass postfilter */
   1991 
   1992     lookahead += imdct_copy_ov_and_nr(&pAacDecoderStaticChannelInfo->IMdct,
   1993                                       synth + nrSamples, copySamp);
   1994 
   1995     FDK_ASSERT(lookahead == copySamp - BPF_DELAY);
   1996 
   1997     FIXP_DBL *p2_synth = synth + BPF_DELAY;
   1998 
   1999     /* recalculate pitch gain to allow postfilering on FAC area */
   2000     for (int i = 0; i < nbSubfrSuperfr; i++) {
   2001       int T = pitch[i];
   2002       FIXP_DBL gain = pit_gain[i];
   2003 
   2004       if (gain > (FIXP_DBL)0) {
   2005         gain = get_gain(&p2_synth[i * L_SUBFR], &p2_synth[(i * L_SUBFR) - T],
   2006                         L_SUBFR);
   2007         pit_gain[i] = gain;
   2008       }
   2009     }
   2010 
   2011     {
   2012       bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB,
   2013                         mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay,
   2014                         pTimeData, pAacDecoderStaticChannelInfo->mem_bpf);
   2015     }
   2016   }
   2017 
   2018   Acelp_PostProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth,
   2019                        pitch, pAacDecoderStaticChannelInfo->old_T_pf, lFrame,
   2020                        synSfd, nbSubfrSuperfr);
   2021 
   2022   /* Store last mode for next super frame */
   2023   { pAacDecoderStaticChannelInfo->last_core_mode = LPD; }
   2024   pAacDecoderStaticChannelInfo->last_lpd_mode = last_lpd_mode;
   2025   pAacDecoderStaticChannelInfo->last_last_lpd_mode = last_last_lpd_mode;
   2026   pAacDecoderStaticChannelInfo->last_lpc_lost = last_lpc_lost;
   2027 
   2028   return error;
   2029 }
   2030