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