• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 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,FIXP_PCM * syn_out,FIXP_DBL * noise,const FIXP_SGL * filt,INT stop,int len)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 
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,FIXP_PCM * synth_out,FIXP_DBL mem_bpf[])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*/
CLpd_AdaptLowFreqDeemph(FIXP_DBL x[],int lg,FIXP_DBL alfd_gains[],INT s)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 
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)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  */
calcEnergy(const FIXP_DBL * r,const SHORT rs,const INT lg,INT * rms_e)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  */
calcTCXGain(CAacDecoderChannelInfo * pAacDecoderChannelInfo,FIXP_DBL * r,FIXP_DBL rms_m,INT rms_e,const INT frame,const INT lg)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 */
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)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  */
find_mpitch(FIXP_DBL xri[],int lg)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  */
CLpd_TcxDecode(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,UINT flags,int mod,int last_mod,int frame,int frameOk)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  */
CLpd_TCX_Read(HANDLE_FDK_BITSTREAM hBs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,int lg,int first_tcx_flag,int frame,UINT flags)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  */
CLpd_ReadAndMapLpdModeToModArray(UCHAR mod[4],HANDLE_FDK_BITSTREAM hBs,UINT elFlags)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 
CLpd_Reset(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,int keep_past_signal)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 
CLpdChannelStream_Read(HANDLE_FDK_BITSTREAM hBs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,UINT flags)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 
CLpdChannelStream_Decode(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,UINT flags)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 
CLpd_RenderTimeSignal(CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,FIXP_PCM * pTimeData,INT lFrame,SamplingRateInfo * pSamplingRateInfo,UINT frameOk,UINT flags,UINT strmFlags)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