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