• 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     s = fMin(31, s);
422 
423     k = 8;
424     i_max = lg / 4; /* ALFD range = 1600Hz (lg = 6400Hz) */
425 
426     /* find spectral peak */
427     max = FL2FX_DBL(0.01f) >> s;
428     for (i = 0; i < i_max; i += k) {
429       FIXP_DBL tmp;
430 
431       tmp = FIXP_DBL(0);
432       FIXP_DBL *pX = &x[i];
433 
434       j = 8;
435       do {
436         FIXP_DBL x0 = *pX++;
437         FIXP_DBL x1 = *pX++;
438         x0 = fPow2Div2(x0);
439         x1 = fPow2Div2(x1);
440         tmp = tmp + (x0 >> (ALFDPOW2_SCALE - 1));
441         tmp = tmp + (x1 >> (ALFDPOW2_SCALE - 1));
442       } while ((j = j - 2) != 0);
443       tmp = fMax(tmp, (FL2FX_DBL(0.01f) >> s));
444       tmp_pow2[i >> 3] = tmp;
445       if (tmp > max) {
446         max = tmp;
447       }
448     }
449 
450     /* deemphasis of all blocks below the peak */
451     fac = FL2FX_DBL(0.1f) >> 1;
452     for (i = 0; i < i_max; i += k) {
453       FIXP_DBL tmp;
454       INT shifti;
455 
456       tmp = tmp_pow2[i >> 3];
457 
458       /* tmp = (float)sqrt(tmp/max); */
459 
460       /* value of tmp is between 8/2*max^2 and max^2 / 2. */
461       /* required shift factor of division can grow up to 27
462          (grows exponentially for values toward zero)
463          thus using normalized division to assure valid result. */
464       {
465         INT sd;
466 
467         if (tmp != (FIXP_DBL)0) {
468           tmp = fDivNorm(max, tmp, &sd);
469           if (sd & 1) {
470             sd++;
471             tmp >>= 1;
472           }
473         } else {
474           tmp = (FIXP_DBL)MAXVAL_DBL;
475           sd = 0;
476         }
477         tmp = invSqrtNorm2(tmp, &shifti);
478         tmp = scaleValue(tmp, shifti - 1 - (sd / 2));
479       }
480       if (tmp > fac) {
481         fac = tmp;
482       }
483       FIXP_DBL *pX = &x[i];
484 
485       j = 8;
486       do {
487         FIXP_DBL x0 = pX[0];
488         FIXP_DBL x1 = pX[1];
489         x0 = fMultDiv2(x0, fac);
490         x1 = fMultDiv2(x1, fac);
491         x0 = x0 << 2;
492         x1 = x1 << 2;
493         *pX++ = x0;
494         *pX++ = x1;
495 
496       } while ((j = j - 2) != 0);
497       /* Store gains for FAC */
498       *alfd_gains++ = fac;
499     }
500   }
501 }
502 
503 /**
504  * \brief Interpolated Noise Shaping for mdct coefficients.
505  * This algorithm shapes temporally the spectral noise between
506  * the two spectral noise represention (FDNS_NPTS of resolution).
507  * The noise is shaped monotonically between the two points
508  * using a curved shape to favor the lower gain in mid-frame.
509  * ODFT and amplitud calculation are applied to the 2 LPC coefficients first.
510  *
511  * \param r pointer to spectrum data.
512  * \param rms RMS of output spectrum.
513  * \param lg length of r.
514  * \param A1 pointer to old input LPC coefficients of length M_LP_FILTER_ORDER
515  * scaled by SF_A_COEFFS.
516  * \param A2 pointer to new input LPC coefficients of length M_LP_FILTER_ORDER
517  * scaled by SF_A_COEFFS.
518  * \param bLpc2Mdct flags control lpc2mdct conversion and noise shaping.
519  * \param gainLpc1 pointer to gain based on old input LPC coefficients.
520  * \param gainLpc2 pointer to gain based on new input LPC coefficients.
521  * \param gLpc_e pointer to exponent of gainLpc1 and gainLpc2.
522  */
523 /* static */
524 #define NSHAPE_SCALE (4)
525 
526 #define LPC2MDCT_CALC (1)
527 #define LPC2MDCT_GAIN_LOAD (2)
528 #define LPC2MDCT_GAIN_SAVE (4)
529 #define LPC2MDCT_APPLY_NSHAPE (8)
530 
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)531 void lpc2mdctAndNoiseShaping(FIXP_DBL *r, SHORT *pScale, const INT lg,
532                              const INT fdns_npts, const FIXP_LPC *A1,
533                              const INT A1_exp, const FIXP_LPC *A2,
534                              const INT A2_exp) {
535   FIXP_DBL *tmp2 = NULL;
536   FIXP_DBL rr_minus_one;
537   int i, k, s, step;
538 
539   C_AALLOC_SCRATCH_START(tmp1, FIXP_DBL, FDNS_NPTS * 8)
540 
541   {
542     tmp2 = tmp1 + fdns_npts * 4;
543 
544     /* lpc2mdct() */
545 
546     /* ODFT. E_LPC_a_weight() for A1 and A2 vectors is included into the loop
547      * below. */
548     FIXP_DBL f = FL2FXCONST_DBL(0.92f);
549 
550     const FIXP_STP *SinTab;
551     int k_step;
552     /* needed values: sin(phi), cos(phi); phi = i*PI/(2*fdns_npts), i = 0 ...
553      * M_LP_FILTER_ORDER */
554     switch (fdns_npts) {
555       case 64:
556         SinTab = SineTable512;
557         k_step = (512 / 64);
558         FDK_ASSERT(512 >= 64);
559         break;
560       case 48:
561         SinTab = SineTable384;
562         k_step = 384 / 48;
563         FDK_ASSERT(384 >= 48);
564         break;
565       default:
566         FDK_ASSERT(0);
567         return;
568     }
569 
570     for (i = 0, k = k_step; i < M_LP_FILTER_ORDER; i++, k += k_step) {
571       FIXP_STP cs = SinTab[k];
572       FIXP_DBL wA1, wA2;
573 
574       wA1 = fMult(A1[i], f);
575       wA2 = fMult(A2[i], f);
576 
577       /* r[i] = A[i]*cos() */
578       tmp1[2 + i * 2] = fMult(wA1, cs.v.re);
579       tmp2[2 + i * 2] = fMult(wA2, cs.v.re);
580       /* i[i] = A[i]*sin() */
581       tmp1[3 + i * 2] = -fMult(wA1, cs.v.im);
582       tmp2[3 + i * 2] = -fMult(wA2, cs.v.im);
583 
584       f = fMult(f, FL2FXCONST_DBL(0.92f));
585     }
586 
587     /* Guarantee at least 2 bits of headroom for the FFT */
588     /* "3" stands for 1.0 with 2 bits of headroom; (A1_exp + 2) guarantess 2
589      * bits of headroom if A1_exp > 1 */
590     int A1_exp_fix = fMax(3, A1_exp + 2);
591     int A2_exp_fix = fMax(3, A2_exp + 2);
592 
593     /* Set 1.0 in the proper format */
594     tmp1[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A1_exp_fix);
595     tmp2[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A2_exp_fix);
596 
597     tmp1[1] = tmp2[1] = (FIXP_DBL)0;
598 
599     /* Clear the resto of the array */
600     FDKmemclear(
601         tmp1 + 2 * (M_LP_FILTER_ORDER + 1),
602         2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
603     FDKmemclear(
604         tmp2 + 2 * (M_LP_FILTER_ORDER + 1),
605         2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
606 
607     /* Guarantee 2 bits of headroom for FFT */
608     scaleValues(&tmp1[2], (2 * M_LP_FILTER_ORDER), (A1_exp - A1_exp_fix));
609     scaleValues(&tmp2[2], (2 * M_LP_FILTER_ORDER), (A2_exp - A2_exp_fix));
610 
611     INT s2;
612     s = A1_exp_fix;
613     s2 = A2_exp_fix;
614 
615     fft(2 * fdns_npts, tmp1, &s);
616     fft(2 * fdns_npts, tmp2, &s2);
617 
618     /* Adjust the exponents of both fft outputs if necessary*/
619     if (s > s2) {
620       scaleValues(tmp2, 2 * fdns_npts, s2 - s);
621       s2 = s;
622     } else if (s < s2) {
623       scaleValues(tmp1, 2 * fdns_npts, s - s2);
624       s = s2;
625     }
626 
627     FDK_ASSERT(s == s2);
628   }
629 
630   /* Get amplitude and apply gains */
631   step = lg / fdns_npts;
632   rr_minus_one = (FIXP_DBL)0;
633 
634   for (k = 0; k < fdns_npts; k++) {
635     FIXP_DBL g1, g2, inv_g1_g2, a, b;
636     INT inv_g1_g2_e;
637     int g_e, shift;
638 
639     {
640       FIXP_DBL real, imag;
641       int si1, si2, sInput;
642 
643       real = tmp1[k * 2];
644       imag = tmp1[k * 2 + 1];
645       sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
646       real <<= sInput;
647       imag <<= sInput;
648       /* g1_e = si1 - 2*s/2 */
649       g1 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si1);
650       si1 += sInput;
651 
652       real = tmp2[k * 2];
653       imag = tmp2[k * 2 + 1];
654       sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
655       real <<= sInput;
656       imag <<= sInput;
657       /* g2_e = si2 - 2*s/2 */
658       g2 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si2);
659       si2 += sInput;
660 
661       /* Pick a common scale factor for g1 and g2 */
662       if (si1 > si2) {
663         g2 >>= si1 - si2;
664         g_e = si1 - s;
665       } else {
666         g1 >>= si2 - si1;
667         g_e = si2 - s;
668       }
669     }
670 
671     /* end of lpc2mdct() */
672 
673     FDK_ASSERT(g1 >= (FIXP_DBL)0);
674     FDK_ASSERT(g2 >= (FIXP_DBL)0);
675 
676     /* mdct_IntNoiseShaping() */
677     {
678       /* inv_g1_g2 * 2^inv_g1_g2_e = 1/(g1+g2) */
679       inv_g1_g2 = (g1 >> 1) + (g2 >> 1);
680       if (inv_g1_g2 != (FIXP_DBL)0) {
681         inv_g1_g2 = fDivNorm(FL2FXCONST_DBL(0.5f), inv_g1_g2, &inv_g1_g2_e);
682         inv_g1_g2_e = inv_g1_g2_e - g_e;
683       } else {
684         inv_g1_g2 = (FIXP_DBL)MAXVAL_DBL;
685         inv_g1_g2_e = 0;
686       }
687 
688       if (g_e < 0) {
689         /* a_e = g_e + inv_g1_g2_e + 1 */
690         a = scaleValue(fMult(fMult(g1, g2), inv_g1_g2), g_e);
691         /* b_e = g_e + inv_g1_g2_e */
692         b = fMult(g2 - g1, inv_g1_g2);
693         shift = g_e + inv_g1_g2_e + 1 - NSHAPE_SCALE;
694       } else {
695         /* a_e = (g_e+g_e) + inv_g1_g2_e + 1 */
696         a = fMult(fMult(g1, g2), inv_g1_g2);
697         /* b_e = (g_e+g_e) + inv_g1_g2_e */
698         b = scaleValue(fMult(g2 - g1, inv_g1_g2), -g_e);
699         shift = (g_e + g_e) + inv_g1_g2_e + 1 - NSHAPE_SCALE;
700       }
701 
702       for (i = k * step; i < (k + 1) * step; i++) {
703         FIXP_DBL tmp;
704 
705         /* rr[i] = 2*a*r[i] + b*rr[i-1] */
706         tmp = fMult(a, r[i]);
707         tmp += scaleValue(fMultDiv2(b, rr_minus_one), NSHAPE_SCALE);
708         tmp = scaleValueSaturate(tmp, shift);
709         rr_minus_one = tmp;
710         r[i] = tmp;
711       }
712     }
713   }
714 
715   /* end of mdct_IntNoiseShaping() */
716   { *pScale += NSHAPE_SCALE; }
717 
718   C_AALLOC_SCRATCH_END(tmp1, FIXP_DBL, FDNS_NPTS * 8)
719 }
720 
721 /**
722  * \brief Calculates the energy.
723  * \param r pointer to spectrum.
724  * \param rs scale factor of spectrum r.
725  * \param lg frame length in audio samples.
726  * \param rms_e pointer to exponent of energy value.
727  * \return mantissa of energy value.
728  */
calcEnergy(const FIXP_DBL * r,const SHORT rs,const INT lg,INT * rms_e)729 static FIXP_DBL calcEnergy(const FIXP_DBL *r, const SHORT rs, const INT lg,
730                            INT *rms_e) {
731   int headroom = getScalefactor(r, lg);
732 
733   FIXP_DBL rms_m = 0;
734 
735   /* Calculate number of growth bits due to addition */
736   INT shift = (INT)(fNormz((FIXP_DBL)lg));
737   shift = 31 - shift;
738 
739   /* Generate 1e-2 in Q-6.37 */
740   const FIXP_DBL value0_01 = 0x51eb851e;
741   const INT value0_01_exp = -6;
742 
743   /* Find the exponent of the resulting energy value */
744   *rms_e = ((rs - headroom) << 1) + shift + 1;
745 
746   INT delta = *rms_e - value0_01_exp;
747   if (delta > 0) {
748     /* Limit shift_to 31*/
749     delta = fMin(31, delta);
750     rms_m = value0_01 >> delta;
751   } else {
752     rms_m = value0_01;
753     *rms_e = value0_01_exp;
754     shift = shift - delta;
755     /* Limit shift_to 31*/
756     shift = fMin(31, shift);
757   }
758 
759   for (int i = 0; i < lg; i++) {
760     rms_m += fPow2Div2(r[i] << headroom) >> shift;
761   }
762 
763   return rms_m;
764 }
765 
766 /**
767  * \brief TCX gain calculation.
768  * \param pAacDecoderChannelInfo channel context data.
769  * \param r output spectrum.
770  * \param rms_e pointer to mantissa of energy value.
771  * \param rms_e pointer to exponent of energy value.
772  * \param frame the frame index of the LPD super frame.
773  * \param lg the frame length in audio samples.
774  * \param gain_m pointer to mantissa of TCX gain.
775  * \param gain_e pointer to exponent of TCX gain.
776  * \param elFlags element specific parser guidance flags.
777  * \param lg_fb the fullband frame length in audio samples.
778  * \param IGF_bgn the IGF start index.
779  */
calcTCXGain(CAacDecoderChannelInfo * pAacDecoderChannelInfo,FIXP_DBL * r,FIXP_DBL rms_m,INT rms_e,const INT frame,const INT lg)780 static void calcTCXGain(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
781                         FIXP_DBL *r, FIXP_DBL rms_m, INT rms_e, const INT frame,
782                         const INT lg) {
783   if ((rms_m != (FIXP_DBL)0)) {
784     FIXP_DBL tcx_gain_m;
785     INT tcx_gain_e;
786 
787     CLpd_DecodeGain(&tcx_gain_m, &tcx_gain_e,
788                     pAacDecoderChannelInfo->pDynData->specificTo.usac
789                         .tcx_global_gain[frame]);
790 
791     /* rms * 2^rms_e = lg/sqrt(sum(spec^2)) */
792     if (rms_e & 1) {
793       rms_m >>= 1;
794       rms_e++;
795     }
796 
797     {
798       FIXP_DBL fx_lg;
799       INT fx_lg_e, s;
800       INT inv_e;
801 
802       /* lg = fx_lg * 2^fx_lg_e */
803       s = fNorm((FIXP_DBL)lg);
804       fx_lg = (FIXP_DBL)lg << s;
805       fx_lg_e = DFRACT_BITS - 1 - s;
806       /* 1/sqrt(rms) */
807       rms_m = invSqrtNorm2(rms_m, &inv_e);
808       rms_m = fMult(rms_m, fx_lg);
809       rms_e = inv_e - (rms_e >> 1) + fx_lg_e;
810     }
811 
812     {
813       int s = fNorm(tcx_gain_m);
814       tcx_gain_m = tcx_gain_m << s;
815       tcx_gain_e -= s;
816     }
817 
818     tcx_gain_m = fMultDiv2(tcx_gain_m, rms_m);
819     tcx_gain_e = tcx_gain_e + rms_e;
820 
821     /* global_gain * 2^(global_gain_e+rms_e) = (10^(global_gain/28)) * rms *
822      * 2^rms_e */
823     {
824       { tcx_gain_e += 1; }
825     }
826 
827     pAacDecoderChannelInfo->data.usac.tcx_gain[frame] = tcx_gain_m;
828     pAacDecoderChannelInfo->data.usac.tcx_gain_e[frame] = tcx_gain_e;
829 
830     pAacDecoderChannelInfo->specScale[frame] += tcx_gain_e;
831   }
832 }
833 
834 /**
835  * \brief FDNS decoding.
836  * \param pAacDecoderChannelInfo channel context data.
837  * \param pAacDecoderStaticChannelInfo channel context static data.
838  * \param r output spectrum.
839  * \param lg the frame length in audio samples.
840  * \param frame the frame index of the LPD super frame.
841  * \param pScale pointer to current scale shift factor of r[].
842  * \param A1 old input LPC coefficients of length M_LP_FILTER_ORDER.
843  * \param A2 new input LPC coefficients of length M_LP_FILTER_ORDER.
844  * \param pAlfdGains pointer for ALFD gains output scaled by 1.
845  * \param fdns_npts number of lines (FDNS_NPTS).
846  * \param inf_mask pointer to noise mask.
847  * \param IGF_win_mode IGF window mode (LONG, SHORT, TCX10, TCX20).
848  * \param frameType (IGF_FRAME_DIVISION_AAC_OR_TCX_LONG or
849  * IGF_FRAME_DIVISION_TCX_SHORT_1).
850  * \param elFlags element specific parser guidance flags.
851  * \param lg_fb the fullband frame length in audio samples.
852  * \param IGF_bgn the IGF start index.
853  * \param rms_m mantisse of energy.
854  * \param rms_e exponent of energy.
855  */
856 /* 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)857 void CLpd_FdnsDecode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
858                      CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
859                      FIXP_DBL r[], const INT lg, const INT frame, SHORT *pScale,
860                      const FIXP_LPC A1[M_LP_FILTER_ORDER], const INT A1_exp,
861                      const FIXP_LPC A2[M_LP_FILTER_ORDER], const INT A2_exp,
862                      FIXP_DBL pAlfdGains[LFAC / 4], const INT fdns_npts) {
863   /* Weight LPC coefficients using Rm values */
864   CLpd_AdaptLowFreqDeemph(r, lg, pAlfdGains, *pScale);
865 
866   FIXP_DBL rms_m = (FIXP_DBL)0;
867   INT rms_e = 0;
868   {
869     /* Calculate Energy */
870     rms_m = calcEnergy(r, *pScale, lg, &rms_e);
871   }
872 
873   calcTCXGain(pAacDecoderChannelInfo, r, rms_m, rms_e, frame, lg);
874 
875   /* Apply ODFT and Noise Shaping. LP coefficient (A1, A2) weighting is done
876    * inside on the fly. */
877 
878   lpc2mdctAndNoiseShaping(r, pScale, lg, fdns_npts, A1, A1_exp, A2, A2_exp);
879 }
880 
881 /**
882  * find pitch for TCX20 (time domain) concealment.
883  */
find_mpitch(FIXP_DBL xri[],int lg)884 static int find_mpitch(FIXP_DBL xri[], int lg) {
885   FIXP_DBL max, pitch;
886   INT pitch_e;
887   int i, n;
888 
889   max = (FIXP_DBL)0;
890   n = 2;
891 
892   /* find maximum below 400Hz */
893   for (i = 2; i < (lg >> 4); i += 2) {
894     FIXP_DBL tmp = fPow2Div2(xri[i]) + fPow2Div2(xri[i + 1]);
895     if (tmp > max) {
896       max = tmp;
897       n = i;
898     }
899   }
900 
901   // pitch = ((float)lg<<1)/(float)n;
902   pitch = fDivNorm((FIXP_DBL)lg << 1, (FIXP_DBL)n, &pitch_e);
903   pitch >>= fixMax(0, DFRACT_BITS - 1 - pitch_e - 16);
904 
905   /* find pitch multiple under 20ms */
906   if (pitch >= (FIXP_DBL)((256 << 16) - 1)) { /*231.0f*/
907     n = 256;
908   } else {
909     FIXP_DBL mpitch = pitch;
910     while (mpitch < (FIXP_DBL)(255 << 16)) {
911       mpitch += pitch;
912     }
913     n = (int)(mpitch - pitch) >> 16;
914   }
915 
916   return (n);
917 }
918 
919 /**
920  * number of spectral coefficients / time domain samples using frame mode as
921  * index.
922  */
923 static const int lg_table_ccfl[2][4] = {
924     {256, 256, 512, 1024}, /* coreCoderFrameLength = 1024 */
925     {192, 192, 384, 768}   /* coreCoderFrameLength = 768  */
926 };
927 
928 /**
929  * \brief Decode and render one MDCT-TCX frame.
930  * \param pAacDecoderChannelInfo channel context data.
931  * \param lg the frame length in audio samples.
932  * \param frame the frame index of the LPD super frame.
933  */
CLpd_TcxDecode(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,UINT flags,int mod,int last_mod,int frame,int frameOk)934 static void CLpd_TcxDecode(
935     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
936     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags,
937     int mod, int last_mod, int frame, int frameOk) {
938   FIXP_DBL *pAlfd_gains = pAacDecoderStaticChannelInfo->last_alfd_gains;
939   ULONG *pSeed = &pAacDecoderStaticChannelInfo->nfRandomSeed;
940   int lg = (pAacDecoderChannelInfo->granuleLength == 128)
941                ? lg_table_ccfl[0][mod + 0]
942                : lg_table_ccfl[1][mod + 0];
943   int next_frame = frame + (1 << (mod - 1));
944   int isFullBandLpd = 0;
945 
946   /* Obtain r[] vector by combining the quant[] and noise[] vectors */
947   {
948     FIXP_DBL noise_level;
949     FIXP_DBL *coeffs =
950         SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
951                  pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
952     int scale = pAacDecoderChannelInfo->specScale[frame];
953     int i, nfBgn, nfEnd;
954     UCHAR tcx_noise_factor = pAacDecoderChannelInfo->pDynData->specificTo.usac
955                                  .tcx_noise_factor[frame];
956 
957     /* find pitch for bfi case */
958     pAacDecoderStaticChannelInfo->last_tcx_pitch = find_mpitch(coeffs, lg);
959 
960     if (frameOk) {
961       /* store for concealment */
962       pAacDecoderStaticChannelInfo->last_tcx_noise_factor = tcx_noise_factor;
963     } else {
964       /* restore last frames value */
965       tcx_noise_factor = pAacDecoderStaticChannelInfo->last_tcx_noise_factor;
966     }
967 
968     noise_level =
969         (FIXP_DBL)((LONG)FL2FXCONST_DBL(0.0625f) * (8 - tcx_noise_factor));
970     noise_level = scaleValue(noise_level, -scale);
971 
972     const FIXP_DBL neg_noise_level = -noise_level;
973 
974     {
975       nfBgn = lg / 6;
976       nfEnd = lg;
977     }
978 
979     for (i = nfBgn; i < nfEnd - 7; i += 8) {
980       LONG tmp;
981 
982       /* Fill all 8 consecutive zero coeffs with noise */
983       tmp = coeffs[i + 0] | coeffs[i + 1] | coeffs[i + 2] | coeffs[i + 3] |
984             coeffs[i + 4] | coeffs[i + 5] | coeffs[i + 6] | coeffs[i + 7];
985 
986       if (tmp == 0) {
987         for (int k = i; k < i + 8; k++) {
988           UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
989                                 : (coeffs[k] = noise_level);
990         }
991       }
992     }
993     if ((nfEnd - i) >
994         0) { /* noise filling for last "band" with less than 8 bins */
995       LONG tmp = (LONG)coeffs[i];
996       int k;
997 
998       FDK_ASSERT((nfEnd - i) < 8);
999       for (k = 1; k < (nfEnd - i); k++) {
1000         tmp |= (LONG)coeffs[i + k];
1001       }
1002       if (tmp == 0) {
1003         for (k = i; k < nfEnd; k++) {
1004           UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
1005                                 : (coeffs[k] = noise_level);
1006         }
1007       }
1008     }
1009   }
1010 
1011   {
1012     /* Convert LPC to LP domain */
1013     if (last_mod == 0) {
1014       /* Note: The case where last_mod == 255 is handled by other means
1015        * in CLpdChannelStream_Read() */
1016       E_LPC_f_lsp_a_conversion(
1017           pAacDecoderChannelInfo->data.usac.lsp_coeff[frame],
1018           pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
1019           &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame]);
1020     }
1021 
1022     E_LPC_f_lsp_a_conversion(
1023         pAacDecoderChannelInfo->data.usac.lsp_coeff[next_frame],
1024         pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
1025         &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame]);
1026 
1027     /* FDNS decoding */
1028     CLpd_FdnsDecode(
1029         pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
1030         SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
1031                  pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
1032         lg, frame, pAacDecoderChannelInfo->specScale + frame,
1033         pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
1034         pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame],
1035         pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
1036         pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame], pAlfd_gains,
1037         pAacDecoderChannelInfo->granuleLength / 2 /* == FDNS_NPTS(ccfl) */
1038     );
1039   }
1040 }
1041 
1042 /**
1043  * \brief Read the tcx_coding bitstream part
1044  * \param hBs bitstream handle to read from.
1045  * \param pAacDecoderChannelInfo channel context info to store data into.
1046  * \param lg the frame length in audio samples.
1047  * \param first_tcx_flag flag indicating that this is the first TCX frame.
1048  * \param frame the frame index of the LPD super frame.
1049  */
CLpd_TCX_Read(HANDLE_FDK_BITSTREAM hBs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,int lg,int first_tcx_flag,int frame,UINT flags)1050 static AAC_DECODER_ERROR CLpd_TCX_Read(
1051     HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
1052     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, int lg,
1053     int first_tcx_flag, int frame, UINT flags) {
1054   AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
1055   ARITH_CODING_ERROR error = ARITH_CODER_OK;
1056   FIXP_DBL *pSpec;
1057   int arith_reset_flag = 0;
1058   int isFullBandLpd = 0;
1059 
1060   pSpec = SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
1061                    pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
1062 
1063   /* TCX noise level */
1064   {
1065     pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_noise_factor[frame] =
1066         FDKreadBits(hBs, 3);
1067   }
1068   /* TCX global gain */
1069   pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_global_gain[frame] =
1070       FDKreadBits(hBs, 7);
1071 
1072   /* Arithmetic coded residual/spectrum */
1073   if (first_tcx_flag) {
1074     if (flags & AC_INDEP) {
1075       arith_reset_flag = 1;
1076     } else {
1077       arith_reset_flag = FDKreadBits(hBs, 1);
1078     }
1079   }
1080 
1081   /* CArco_DecodeArithData() output scale of "pSpec" is DFRACT_BITS-1 */
1082   error = CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs, pSpec,
1083                                 lg, lg, arith_reset_flag);
1084 
1085   /* Rescale residual/spectrum */
1086   {
1087     int scale = getScalefactor(pSpec, lg) - 2; /* Leave 2 bits headroom */
1088 
1089     /* Exponent of CArco_DecodeArithData() output is DFRACT_BITS; integer
1090      * values. */
1091     scaleValues(pSpec, lg, scale);
1092     scale = DFRACT_BITS - 1 - scale;
1093 
1094     pAacDecoderChannelInfo->specScale[frame] = scale;
1095   }
1096 
1097   if (error == ARITH_CODER_ERROR) errorAAC = AAC_DEC_UNKNOWN;
1098 
1099   return errorAAC;
1100 }
1101 
1102 /**
1103  * \brief translate lpd_mode into the mod[] array which describes the mode of
1104  * each each LPD frame
1105  * \param mod[] the array that will be filled with the mode indexes of the
1106  * inidividual frames.
1107  * \param lpd_mode the lpd_mode field read from the lpd_channel_stream
1108  */
CLpd_ReadAndMapLpdModeToModArray(UCHAR mod[4],HANDLE_FDK_BITSTREAM hBs,UINT elFlags)1109 static AAC_DECODER_ERROR CLpd_ReadAndMapLpdModeToModArray(
1110     UCHAR mod[4], HANDLE_FDK_BITSTREAM hBs, UINT elFlags) {
1111   int lpd_mode;
1112 
1113   {
1114     lpd_mode = FDKreadBits(hBs, 5);
1115 
1116     if (lpd_mode > 25 || lpd_mode < 0) {
1117       return AAC_DEC_PARSE_ERROR;
1118     }
1119 
1120     switch (lpd_mode) {
1121       case 25:
1122         /* 1 80MS frame */
1123         mod[0] = mod[1] = mod[2] = mod[3] = 3;
1124         break;
1125       case 24:
1126         /* 2 40MS frames */
1127         mod[0] = mod[1] = mod[2] = mod[3] = 2;
1128         break;
1129       default:
1130         switch (lpd_mode >> 2) {
1131           case 4:
1132             /* lpd_mode 19 - 16  => 1 40MS and 2 20MS frames */
1133             mod[0] = mod[1] = 2;
1134             mod[2] = (lpd_mode & 1) ? 1 : 0;
1135             mod[3] = (lpd_mode & 2) ? 1 : 0;
1136             break;
1137           case 5:
1138             /* lpd_mode 23 - 20 => 2 20MS and 1 40MS frames */
1139             mod[2] = mod[3] = 2;
1140             mod[0] = (lpd_mode & 1) ? 1 : 0;
1141             mod[1] = (lpd_mode & 2) ? 1 : 0;
1142             break;
1143           default:
1144             /* lpd_mode < 16 => 4 20MS frames */
1145             mod[0] = (lpd_mode & 1) ? 1 : 0;
1146             mod[1] = (lpd_mode & 2) ? 1 : 0;
1147             mod[2] = (lpd_mode & 4) ? 1 : 0;
1148             mod[3] = (lpd_mode & 8) ? 1 : 0;
1149             break;
1150         }
1151         break;
1152     }
1153   }
1154   return AAC_DEC_OK;
1155 }
1156 
CLpd_Reset(CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,int keep_past_signal)1157 static void CLpd_Reset(
1158     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
1159     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
1160     int keep_past_signal) {
1161   int i;
1162 
1163   /* Reset TCX / ACELP common memory */
1164   if (!keep_past_signal) {
1165     FDKmemclear(pAacDecoderStaticChannelInfo->old_synth,
1166                 sizeof(pAacDecoderStaticChannelInfo->old_synth));
1167   }
1168 
1169   /* Initialize the LSFs */
1170   for (i = 0; i < M_LP_FILTER_ORDER; i++) {
1171     pAacDecoderStaticChannelInfo->lpc4_lsf[i] = fdk_dec_lsf_init[i];
1172   }
1173 
1174   /* Reset memory needed by bass post-filter */
1175   FDKmemclear(pAacDecoderStaticChannelInfo->mem_bpf,
1176               sizeof(pAacDecoderStaticChannelInfo->mem_bpf));
1177 
1178   pAacDecoderStaticChannelInfo->old_bpf_control_info = 0;
1179   for (i = 0; i < SYN_SFD; i++) {
1180     pAacDecoderStaticChannelInfo->old_T_pf[i] = 64;
1181     pAacDecoderStaticChannelInfo->old_gain_pf[i] = (FIXP_DBL)0;
1182   }
1183 
1184   /* Reset ACELP memory */
1185   CLpd_AcelpReset(&pAacDecoderStaticChannelInfo->acelp);
1186 
1187   pAacDecoderStaticChannelInfo->last_lpc_lost = 0;      /* prev_lpc_lost */
1188   pAacDecoderStaticChannelInfo->last_tcx_pitch = L_DIV; /* pitch_tcx     */
1189   pAacDecoderStaticChannelInfo->numLostLpdFrames = 0;   /* nbLostCmpt    */
1190 }
1191 
1192 /*
1193  * Externally visible functions
1194  */
1195 
CLpdChannelStream_Read(HANDLE_FDK_BITSTREAM hBs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,UINT flags)1196 AAC_DECODER_ERROR CLpdChannelStream_Read(
1197     HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
1198     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
1199     const SamplingRateInfo *pSamplingRateInfo, UINT flags) {
1200   AAC_DECODER_ERROR error = AAC_DEC_OK;
1201   int first_tcx_flag;
1202   int k, nbDiv, fFacDataPresent, first_lpd_flag, acelp_core_mode,
1203       facGetMemState = 0;
1204   UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
1205   int lpd_mode_last, prev_frame_was_lpd;
1206   USAC_COREMODE core_mode_last;
1207   const int lg_table_offset = 0;
1208   const int *lg_table = (pAacDecoderChannelInfo->granuleLength == 128)
1209                             ? &lg_table_ccfl[0][lg_table_offset]
1210                             : &lg_table_ccfl[1][lg_table_offset];
1211   int last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
1212 
1213   int last_frame_ok = CConcealment_GetLastFrameOk(
1214       &pAacDecoderStaticChannelInfo->concealmentInfo, 1);
1215 
1216   INT i_offset;
1217   UINT samplingRate;
1218 
1219   samplingRate = pSamplingRateInfo->samplingRate;
1220 
1221   i_offset =
1222       (INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
1223       (INT)PIT_MIN_12k8;
1224 
1225   if ((samplingRate < 6000) || (samplingRate > 24000)) {
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