/src/libxaac/decoder/ixheaacd_imdct.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * * |
3 | | * Copyright (C) 2018 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | #include <math.h> |
21 | | #include <stdio.h> |
22 | | #include <stdlib.h> |
23 | | #include <string.h> |
24 | | |
25 | | #include "ixheaac_type_def.h" |
26 | | #include "ixheaacd_interface.h" |
27 | | |
28 | | #include "ixheaacd_defines.h" |
29 | | #include "ixheaacd_aac_rom.h" |
30 | | |
31 | | #include "ixheaacd_bitbuffer.h" |
32 | | |
33 | | #include "ixheaacd_tns_usac.h" |
34 | | #include "ixheaacd_cnst.h" |
35 | | #include "ixheaacd_acelp_info.h" |
36 | | |
37 | | #include "ixheaacd_td_mdct.h" |
38 | | |
39 | | #include "ixheaacd_sbrdecsettings.h" |
40 | | #include "ixheaacd_info.h" |
41 | | #include "ixheaacd_sbr_common.h" |
42 | | #include "ixheaacd_drc_data_struct.h" |
43 | | #include "ixheaacd_drc_dec.h" |
44 | | #include "ixheaacd_sbrdecoder.h" |
45 | | #include "ixheaacd_mps_polyphase.h" |
46 | | #include "ixheaac_sbr_const.h" |
47 | | |
48 | | #include "ixheaacd_pulsedata.h" |
49 | | #include "ixheaacd_pns.h" |
50 | | #include "ixheaacd_lt_predict.h" |
51 | | #include "ixheaacd_ec_defines.h" |
52 | | #include "ixheaacd_ec_struct_def.h" |
53 | | #include "ixheaacd_main.h" |
54 | | #include "ixheaacd_channelinfo.h" |
55 | | #include "ixheaacd_ec.h" |
56 | | #include "ixheaacd_arith_dec.h" |
57 | | #include "ixheaacd_windows.h" |
58 | | |
59 | | #include "ixheaacd_vec_baisc_ops.h" |
60 | | #include "ixheaac_constants.h" |
61 | | #include "ixheaacd_function_selector.h" |
62 | | #include "ixheaac_basic_ops32.h" |
63 | | #include "ixheaac_basic_ops40.h" |
64 | | |
65 | | #include "ixheaacd_func_def.h" |
66 | | |
67 | | #include "ixheaacd_windows.h" |
68 | | |
69 | | extern const WORD32 ixheaacd_pre_post_twid_cos_512[512]; |
70 | | extern const WORD32 ixheaacd_pre_post_twid_sin_512[512]; |
71 | | extern const WORD32 ixheaacd_pre_post_twid_cos_384[384]; |
72 | | extern const WORD32 ixheaacd_pre_post_twid_sin_384[384]; |
73 | | extern const WORD32 ixheaacd_pre_post_twid_cos_64[64]; |
74 | | extern const WORD32 ixheaacd_pre_post_twid_sin_64[64]; |
75 | | extern const WORD32 ixheaacd_pre_post_twid_cos_48[48]; |
76 | | extern const WORD32 ixheaacd_pre_post_twid_sin_48[48]; |
77 | | extern const FLOAT64 ixheaacd_power_10_table[28]; |
78 | | extern const ia_usac_samp_rate_info ixheaacd_samp_rate_info[]; |
79 | | |
80 | 27.5M | #define ABS(A) ((A) < 0 ? (-A) : (A)) |
81 | | |
82 | 701k | static WORD32 ixheaacd_calc_max_spectralline(WORD32 *p_in_ibuffer, WORD32 n) { |
83 | 701k | WORD32 k, shiftp, itemp = 0; |
84 | 702M | for (k = 0; k < n; k++) { |
85 | 701M | if (ixheaac_abs32_sat(p_in_ibuffer[k]) > itemp) |
86 | 2.76M | itemp = ixheaac_abs32_sat(p_in_ibuffer[k]); |
87 | 701M | } |
88 | | |
89 | 701k | shiftp = ixheaac_norm32(itemp); |
90 | | |
91 | 701k | return (shiftp); |
92 | 701k | } |
93 | | |
94 | 701k | static void ixheaacd_normalize(WORD32 *buff, WORD32 shift, WORD len) { |
95 | 701k | WORD32 i; |
96 | | |
97 | 702M | for (i = 0; i < len; i++) { |
98 | 701M | buff[i] = buff[i] << shift; |
99 | 701M | } |
100 | 701k | } |
101 | | |
102 | 97.3k | static FLOAT32 ixheaacd_pow10(WORD32 input) { |
103 | 97.3k | FLOAT32 output = 1; |
104 | 203k | while (input > 0) { |
105 | 106k | output *= 10; |
106 | 106k | input--; |
107 | 106k | } |
108 | 97.3k | return (output); |
109 | 97.3k | } |
110 | | |
111 | | void ixheaacd_calc_pre_twid_dec(WORD32 *ptr_x, WORD32 *r_ptr, WORD32 *i_ptr, |
112 | | WORD32 nlength, const WORD32 *cos_ptr, |
113 | 990k | const WORD32 *sin_ptr) { |
114 | 990k | WORD32 i; |
115 | 990k | WORD32 *ptr_y; |
116 | | |
117 | 990k | ptr_y = &ptr_x[2 * nlength - 1]; |
118 | | |
119 | 176M | for (i = 0; i < nlength; i++) { |
120 | 175M | *r_ptr++ = ((ixheaac_mult32(ixheaac_negate32_sat(*ptr_x), (*cos_ptr)) - |
121 | 175M | ixheaac_mult32((*ptr_y), (*sin_ptr)))); |
122 | 175M | *i_ptr++ = ((ixheaac_mult32((*ptr_y), (*cos_ptr++)) - |
123 | 175M | ixheaac_mult32((*ptr_x), (*sin_ptr++)))); |
124 | 175M | ptr_x += 2; |
125 | 175M | ptr_y -= 2; |
126 | 175M | } |
127 | 990k | } |
128 | | |
129 | | void ixheaacd_calc_post_twid_dec(WORD32 *xptr, WORD32 *r_ptr, WORD32 *i_ptr, |
130 | | WORD32 nlength, const WORD32 *cos_ptr, |
131 | | const WORD32 *sin_ptr |
132 | | |
133 | 990k | ) { |
134 | 990k | WORD32 i; |
135 | 990k | WORD32 *yptr; |
136 | | |
137 | 990k | yptr = &xptr[2 * nlength - 1]; |
138 | | |
139 | 176M | for (i = 0; i < nlength; i++) { |
140 | 175M | *xptr = (-(ixheaac_mult32((r_ptr[i]), (*cos_ptr)) - |
141 | 175M | ixheaac_mult32((i_ptr[i]), (*sin_ptr)))); |
142 | 175M | *yptr = (-(ixheaac_mult32((i_ptr[i]), (*cos_ptr++)) + |
143 | 175M | ixheaac_mult32((r_ptr[i]), (*sin_ptr++)))); |
144 | 175M | xptr += 2; |
145 | 175M | yptr -= 2; |
146 | 175M | } |
147 | 990k | } |
148 | | |
149 | | static VOID ixheaacd_fft_based_imdct(WORD32 *data, WORD32 npoints, WORD32 *preshift, |
150 | 990k | WORD32 *tmp_data) { |
151 | 990k | WORD32 *data_r; |
152 | 990k | WORD32 *data_i; |
153 | 990k | WORD32 nlength = npoints >> 1; |
154 | 990k | const WORD32 *cos_ptr; |
155 | 990k | const WORD32 *sin_ptr; |
156 | | |
157 | 990k | data_r = tmp_data; |
158 | 990k | data_i = tmp_data + 512; |
159 | | |
160 | 990k | if (nlength == 512) { |
161 | 236k | cos_ptr = ixheaacd_pre_post_twid_cos_512; |
162 | 236k | sin_ptr = ixheaacd_pre_post_twid_sin_512; |
163 | 754k | } else if (nlength == 384) { |
164 | 22.7k | cos_ptr = ixheaacd_pre_post_twid_cos_384; |
165 | 22.7k | sin_ptr = ixheaacd_pre_post_twid_sin_384; |
166 | 731k | } else if (nlength == 64) { |
167 | 659k | cos_ptr = ixheaacd_pre_post_twid_cos_64; |
168 | 659k | sin_ptr = ixheaacd_pre_post_twid_sin_64; |
169 | 659k | } else if (nlength == 48) { |
170 | 72.2k | cos_ptr = ixheaacd_pre_post_twid_cos_48; |
171 | 72.2k | sin_ptr = ixheaacd_pre_post_twid_sin_48; |
172 | 72.2k | } else { |
173 | 0 | cos_ptr = ixheaacd_pre_post_twid_cos_48; |
174 | 0 | sin_ptr = ixheaacd_pre_post_twid_sin_48; |
175 | 0 | } |
176 | | |
177 | 990k | (*ixheaacd_calc_pre_twid)(data, data_r, data_i, nlength, cos_ptr, sin_ptr); |
178 | 990k | ixheaacd_complex_fft(data_r, data_i, nlength, 1, preshift); |
179 | | |
180 | 990k | (*ixheaacd_calc_post_twid)(data, data_r, data_i, nlength, cos_ptr, sin_ptr); |
181 | 990k | return; |
182 | 990k | } |
183 | | |
184 | | #define N_LONG_LEN_MAX 1024 |
185 | | |
186 | | VOID ixheaacd_acelp_imdct(WORD32 *imdct_in, WORD32 npoints, WORD8 *qshift, |
187 | 990k | WORD32 *tmp_data) { |
188 | 990k | WORD32 preshift = 0; |
189 | 990k | WORD32 i; |
190 | 990k | WORD32 k = (npoints / 2); |
191 | | |
192 | 8.51M | while (((k & 1) == 0) & (k != 1)) { |
193 | 7.52M | k = k >> 1; |
194 | 7.52M | preshift++; |
195 | 7.52M | } |
196 | | |
197 | 990k | if ((k != 1)) { |
198 | 24.5M | for (i = 0; i < (npoints / 2); i++) { |
199 | 24.4M | imdct_in[i] = (imdct_in[i] / 3) << 1; |
200 | 24.4M | } |
201 | 95.0k | preshift++; |
202 | 95.0k | } |
203 | | |
204 | 990k | ixheaacd_fft_based_imdct(imdct_in, npoints / 2, &preshift, tmp_data); |
205 | 990k | preshift += 2; |
206 | 990k | *qshift -= preshift; |
207 | 990k | return; |
208 | 990k | } |
209 | | |
210 | | IA_ERRORCODE ixheaacd_cal_fac_data(ia_usac_data_struct *usac_data, WORD32 i_ch, |
211 | | WORD32 n_long, WORD32 lfac, |
212 | 97.3k | WORD32 *fac_idata, WORD8 *q_fac) { |
213 | 97.3k | WORD32 gain_fac, scale, k, *i_aq, itemp = 0, *izir; |
214 | 97.3k | WORD32 int_aq[ORDER + 1] = {0}; |
215 | 97.3k | WORD32 intzir[2 * LEN_FRAME] = {0}; |
216 | 97.3k | WORD32 x_in[FAC_LENGTH] = {0}; |
217 | 97.3k | FLOAT32 gain, ztemp, ftemp, pow10, rem10; |
218 | 97.3k | FLOAT32 qfac1; |
219 | 97.3k | WORD8 qshift1 = 0; |
220 | 97.3k | WORD8 qshift2 = 0; |
221 | 97.3k | WORD8 qshift3 = 0; |
222 | 97.3k | WORD32 preshift = 0; |
223 | | |
224 | 97.3k | FLOAT32 *last_lpc = usac_data->lpc_prev[i_ch]; |
225 | 97.3k | FLOAT32 *acelp_in = usac_data->acelp_in[i_ch]; |
226 | 97.3k | WORD32 *fac_data = usac_data->fac_data[i_ch]; |
227 | 97.3k | WORD32 *ptr_scratch = &usac_data->scratch_buffer[0]; |
228 | | |
229 | 97.3k | WORD32 quo = fac_data[0] / 28; |
230 | 97.3k | WORD32 rem = fac_data[0] % 28; |
231 | 97.3k | pow10 = ixheaacd_pow10(quo); |
232 | 97.3k | rem10 = (FLOAT32)ixheaacd_power_10_table[rem]; |
233 | | |
234 | 97.3k | gain = pow10 * rem10; |
235 | 97.3k | scale = (WORD32)(ixheaac_norm32((WORD32)((ABS(gain) + 1)))); |
236 | 97.3k | gain_fac = (WORD32)(gain * (FLOAT32)((WORD64)1 << scale)); |
237 | 97.3k | scale += 4; |
238 | 97.3k | qfac1 = 1.0f / (gain); |
239 | | |
240 | 97.3k | if (acelp_in != NULL) { |
241 | 97.3k | izir = intzir; |
242 | 97.3k | ftemp = 0.0; |
243 | 24.9M | for (k = 0; k < n_long / 4; k++) { |
244 | 24.8M | ztemp = acelp_in[k] * (qfac1); |
245 | 24.8M | if (ABS(ztemp) > ftemp) ftemp = ABS(ztemp); |
246 | 24.8M | } |
247 | | |
248 | 97.3k | itemp = (WORD32)(ftemp); |
249 | 97.3k | qshift3 = ixheaac_norm32(itemp); |
250 | | |
251 | 24.9M | for (k = 0; k < n_long / 4; k++) { |
252 | 24.8M | izir[k] = |
253 | 24.8M | (WORD32)((acelp_in[k] * (qfac1)) * (FLOAT32)((WORD64)1 << qshift3)); |
254 | 24.8M | } |
255 | 97.3k | } else |
256 | 0 | izir = NULL; |
257 | | |
258 | 97.3k | if (last_lpc != NULL) { |
259 | 97.3k | ftemp = 0.0; |
260 | 97.3k | i_aq = int_aq; |
261 | 1.75M | for (k = 0; k < ORDER + 1; k++) { |
262 | 1.65M | if (ABS(last_lpc[k]) > ftemp) ftemp = ABS(last_lpc[k]); |
263 | 1.65M | } |
264 | | |
265 | 97.3k | itemp = (WORD32)(ftemp); |
266 | 97.3k | qshift2 = ixheaac_norm32(itemp); |
267 | | |
268 | 1.75M | for (k = 0; k < ORDER + 1; k++) { |
269 | 1.65M | i_aq[k] = (WORD32)(last_lpc[k] * (FLOAT32)((WORD64)1 << qshift2)); |
270 | 1.65M | } |
271 | 97.3k | } else |
272 | 0 | i_aq = NULL; |
273 | | |
274 | 12.1M | for (k = 0; k < lfac; k++) { |
275 | 12.0M | if (ixheaac_abs32_sat(fac_data[k + 1]) > itemp) |
276 | 159k | itemp = ixheaac_abs32_sat(fac_data[k + 1]); |
277 | 12.0M | } |
278 | | |
279 | 97.3k | qshift1 = ixheaac_norm32(itemp); |
280 | | |
281 | 12.1M | for (k = 0; k < lfac; k++) { |
282 | 12.0M | fac_data[k + 1] = |
283 | 12.0M | (WORD32)(fac_data[k + 1] * (FLOAT32)((WORD64)1 << qshift1)); |
284 | 12.0M | } |
285 | | |
286 | 6.11M | for (k = 0; k < lfac / 2; k++) { |
287 | 6.02M | x_in[k] = fac_data[2 * k + 1]; |
288 | 6.02M | x_in[lfac / 2 + k] = fac_data[lfac - 2 * k]; |
289 | 6.02M | } |
290 | | |
291 | 97.3k | if (FAC_LENGTH < lfac) { |
292 | 0 | if (usac_data->ec_flag == 0) |
293 | 0 | return -1; |
294 | 0 | else |
295 | 0 | lfac = FAC_LENGTH; |
296 | 0 | } |
297 | | |
298 | 97.3k | if ((n_long / 8) < lfac) { |
299 | 96 | if (usac_data->ec_flag == 0) |
300 | 96 | return -1; |
301 | 0 | else |
302 | 0 | lfac = (n_long / 8); |
303 | 96 | } |
304 | | |
305 | 97.2k | if ((n_long / 8 + 1) > (2 * LEN_FRAME - lfac - 1)) { |
306 | 0 | if (usac_data->ec_flag == 0) |
307 | 0 | return -1; |
308 | 0 | else |
309 | 0 | lfac = (2 * LEN_FRAME) - (n_long / 8); |
310 | 0 | } |
311 | | |
312 | 97.2k | if (lfac & (lfac - 1)) { |
313 | 791 | if ((lfac != 48) && (lfac != 96) && (lfac != 192) && (lfac != 384) && (lfac != 768)) { |
314 | 0 | if (usac_data->ec_flag == 0) |
315 | 0 | return -1; |
316 | 0 | else |
317 | 0 | lfac = 48; |
318 | 0 | } |
319 | 791 | } |
320 | | |
321 | 97.2k | ixheaacd_fr_alias_cnx_fix(x_in, n_long / 4, lfac, i_aq, izir, fac_idata + 16, &qshift1, qshift2, |
322 | 97.2k | qshift3, &preshift, ptr_scratch); |
323 | | |
324 | 97.2k | preshift += 4; |
325 | 97.2k | *q_fac = (qshift1 - preshift); |
326 | | |
327 | 97.2k | if (acelp_in != NULL) { |
328 | 24.1M | for (k = 0; k < 2 * lfac; k++) { |
329 | 24.0M | fac_idata[k] = |
330 | 24.0M | ixheaac_mul32_sh(fac_idata[k + 16], gain_fac, (WORD8)(scale)); |
331 | 24.0M | } |
332 | 97.2k | } |
333 | 97.2k | return IA_NO_ERROR; |
334 | 97.2k | } |
335 | | |
336 | | static IA_ERRORCODE ixheaacd_fd_imdct_short(ia_usac_data_struct *usac_data, |
337 | | WORD32 i_ch, WORD32 *fac_data_out, |
338 | | offset_lengths *ixheaacd_drc_offset, |
339 | 91.4k | WORD8 fac_q) { |
340 | 91.4k | FLOAT32 qfac; |
341 | 91.4k | WORD32 overlap_data_buf[2 * N_LONG_LEN_MAX] = {0}; |
342 | 91.4k | WORD32 *window_short, k, *window_short_prev_ptr; |
343 | 91.4k | WORD32 *overlap_data, *fp; |
344 | | |
345 | 91.4k | WORD32 *p_overlap_ibuffer = usac_data->overlap_data_ptr[i_ch]; |
346 | 91.4k | WORD32 *p_in_ibuffer = usac_data->coef_fix[i_ch]; |
347 | 91.4k | FLOAT32 *p_out_buffer = usac_data->time_sample_vector[i_ch]; |
348 | 91.4k | WORD32 *p_out_ibuffer = usac_data->output_data_ptr[i_ch]; |
349 | 91.4k | WORD32 *scratch_mem = usac_data->scratch_buffer; |
350 | 91.4k | WORD32 td_frame_prev = usac_data->td_frame_prev[i_ch]; |
351 | 91.4k | WORD32 fac_apply = usac_data->fac_data_present[i_ch]; |
352 | 91.4k | WORD8 shiftp, input_q, output_q, shift_olap = 14; |
353 | 91.4k | WORD32 max_shift; |
354 | | |
355 | 91.4k | WORD32 window_select = usac_data->window_shape[i_ch]; |
356 | 91.4k | WORD32 window_select_prev = usac_data->window_shape_prev[i_ch]; |
357 | 91.4k | ia_usac_lpd_decoder_handle st = usac_data->str_tddec[i_ch]; |
358 | 91.4k | WORD32 err_code = 0; |
359 | | |
360 | 91.4k | if (usac_data->ec_flag) { |
361 | 0 | td_frame_prev = usac_data->td_frame_prev_ec[i_ch]; |
362 | 91.4k | } else { |
363 | 91.4k | if (ixheaacd_drc_offset->n_short & (ixheaacd_drc_offset->n_short - 1)) { |
364 | 9.02k | if ((ixheaacd_drc_offset->n_short != 48) && (ixheaacd_drc_offset->n_short != 96) && |
365 | 9.02k | (ixheaacd_drc_offset->n_short != 192) && (ixheaacd_drc_offset->n_short != 384) && |
366 | 9.02k | (ixheaacd_drc_offset->n_short != 768)) { |
367 | 0 | return -1; |
368 | 0 | } |
369 | 9.02k | } |
370 | 91.4k | } |
371 | | |
372 | 91.4k | max_shift = ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
373 | 91.4k | ixheaacd_normalize(p_in_ibuffer, max_shift, ixheaacd_drc_offset->n_long); |
374 | 91.4k | shiftp = max_shift + 6; |
375 | 91.4k | input_q = shiftp; |
376 | | |
377 | 91.4k | memcpy(overlap_data_buf, p_overlap_ibuffer, |
378 | 91.4k | sizeof(WORD32) * ixheaacd_drc_offset->n_long); |
379 | 91.4k | overlap_data = overlap_data_buf; |
380 | | |
381 | 91.4k | fp = overlap_data + ixheaacd_drc_offset->n_flat_ls; |
382 | | |
383 | 823k | for (k = 0; k < 8; k++) { |
384 | 731k | shiftp = input_q; |
385 | 731k | ixheaacd_acelp_imdct( |
386 | 731k | p_in_ibuffer + (k * ixheaacd_drc_offset->n_short), |
387 | 731k | 2 * ixheaacd_drc_offset->n_short, &shiftp, scratch_mem); |
388 | 731k | } |
389 | | |
390 | 91.4k | max_shift = |
391 | 91.4k | ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
392 | 91.4k | ixheaacd_normalize(p_in_ibuffer, max_shift - 1, ixheaacd_drc_offset->n_long); |
393 | 91.4k | shiftp += max_shift - 1; |
394 | | |
395 | 91.4k | if ((shiftp - shift_olap) > 31) { |
396 | 31.4k | shiftp = 31 + shift_olap; |
397 | 31.4k | } |
398 | 91.4k | err_code = ixheaacd_calc_window(&window_short, ixheaacd_drc_offset->n_short, |
399 | 91.4k | window_select, usac_data->ec_flag); |
400 | 91.4k | if (err_code == -1) return err_code; |
401 | 91.4k | err_code = ixheaacd_calc_window(&window_short_prev_ptr, ixheaacd_drc_offset->n_trans_ls, |
402 | 91.4k | window_select_prev, usac_data->ec_flag); |
403 | 91.4k | if (err_code == -1) return err_code; |
404 | | |
405 | 91.4k | if (fac_apply) |
406 | 31.9k | ixheaacd_windowing_short1(p_in_ibuffer + ixheaacd_drc_offset->n_short / 2, |
407 | 31.9k | window_short_prev_ptr, fp, ixheaacd_drc_offset, |
408 | 31.9k | shiftp, shift_olap); |
409 | | |
410 | 59.5k | else |
411 | 59.5k | ixheaacd_windowing_short2(p_in_ibuffer + ixheaacd_drc_offset->n_short / 2, |
412 | 59.5k | window_short_prev_ptr, fp, ixheaacd_drc_offset, |
413 | 59.5k | shiftp, shift_olap); |
414 | | |
415 | 91.4k | output_q = ixheaacd_windowing_short3( |
416 | 91.4k | p_in_ibuffer, window_short + ixheaacd_drc_offset->n_short - 1, |
417 | 91.4k | fp + ixheaacd_drc_offset->n_short, ixheaacd_drc_offset->n_short, shiftp, |
418 | 91.4k | shift_olap); |
419 | 91.4k | p_in_ibuffer += ixheaacd_drc_offset->n_short; |
420 | 91.4k | fp += ixheaacd_drc_offset->n_short; |
421 | 91.4k | window_short_prev_ptr = window_short; |
422 | | |
423 | 640k | for (k = 1; k < 7; k++) { |
424 | 548k | output_q = ixheaacd_windowing_short4( |
425 | 548k | p_in_ibuffer, window_short_prev_ptr, fp, |
426 | 548k | window_short_prev_ptr + ixheaacd_drc_offset->n_short - 1, |
427 | 548k | ixheaacd_drc_offset->n_short, 1, shiftp, shift_olap, output_q); |
428 | 548k | p_in_ibuffer += ixheaacd_drc_offset->n_short; |
429 | 548k | fp += ixheaacd_drc_offset->n_short; |
430 | 548k | window_short_prev_ptr = window_short; |
431 | 548k | } |
432 | | |
433 | 91.4k | output_q = ixheaacd_windowing_short4( |
434 | 91.4k | p_in_ibuffer, window_short_prev_ptr, fp, |
435 | 91.4k | window_short_prev_ptr + ixheaacd_drc_offset->n_short - 1, |
436 | 91.4k | ixheaacd_drc_offset->n_short, 0, shiftp, shift_olap, output_q); |
437 | 91.4k | p_in_ibuffer += ixheaacd_drc_offset->n_short; |
438 | 91.4k | fp += ixheaacd_drc_offset->n_short; |
439 | | |
440 | 91.4k | if (fac_apply) { |
441 | 31.9k | ixheaacd_combine_fac(overlap_data + ixheaacd_drc_offset->n_flat_ls + |
442 | 31.9k | ixheaacd_drc_offset->lfac, |
443 | 31.9k | fac_data_out, |
444 | 31.9k | overlap_data + ixheaacd_drc_offset->n_flat_ls + |
445 | 31.9k | ixheaacd_drc_offset->lfac, |
446 | 31.9k | 2 * ixheaacd_drc_offset->lfac, output_q, fac_q); |
447 | 31.9k | } |
448 | 91.4k | memset(overlap_data + 2 * ixheaacd_drc_offset->n_long - |
449 | 91.4k | ixheaacd_drc_offset->n_flat_ls, |
450 | 91.4k | 0, sizeof(WORD32) * ixheaacd_drc_offset->n_flat_ls); |
451 | 91.4k | ixheaacd_scale_down(overlap_data, overlap_data, |
452 | 91.4k | ixheaacd_drc_offset->n_flat_ls, shift_olap, output_q); |
453 | | |
454 | 91.4k | ixheaacd_scale_down(p_overlap_ibuffer, |
455 | 91.4k | overlap_data + ixheaacd_drc_offset->n_long, |
456 | 91.4k | ixheaacd_drc_offset->n_long, output_q, shift_olap); |
457 | 91.4k | ixheaacd_scale_down(p_out_ibuffer, overlap_data, ixheaacd_drc_offset->n_long, |
458 | 91.4k | output_q, 15); |
459 | | |
460 | 91.4k | if (td_frame_prev) { |
461 | 19.2k | qfac = 1.0f / (FLOAT32)(1 << 15); |
462 | | |
463 | 17.6M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
464 | 17.6M | p_out_buffer[k] = ((FLOAT32)p_out_ibuffer[k]) * qfac; |
465 | 17.6M | } |
466 | 19.2k | err_code = ixheaacd_lpd_bpf_fix(usac_data, 1, p_out_buffer, st); |
467 | 19.2k | if (err_code != 0) return err_code; |
468 | | |
469 | 17.6M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
470 | 17.6M | p_out_ibuffer[k] = (WORD32)(p_out_buffer[k] * (1 << 15)); |
471 | 17.6M | } |
472 | 19.2k | } |
473 | | |
474 | 91.4k | return 0; |
475 | 91.4k | } |
476 | | |
477 | | static IA_ERRORCODE ixheaacd_fd_imdct_long(ia_usac_data_struct *usac_data, |
478 | | WORD32 i_ch, WORD32 *fac_idata, |
479 | | offset_lengths *ixheaacd_drc_offset, |
480 | 259k | WORD8 fac_q) { |
481 | 259k | FLOAT32 qfac; |
482 | 259k | WORD32 *window_long_prev = NULL, k, i, *window_short_prev_ptr = NULL; |
483 | | |
484 | 259k | WORD32 *p_in_ibuffer = usac_data->coef_fix[i_ch]; |
485 | 259k | WORD32 *p_overlap_ibuffer = usac_data->overlap_data_ptr[i_ch]; |
486 | 259k | WORD32 *p_out_ibuffer = usac_data->output_data_ptr[i_ch]; |
487 | 259k | FLOAT32 *p_out_buffer = usac_data->time_sample_vector[i_ch]; |
488 | 259k | WORD32 *scratch_mem = usac_data->scratch_buffer; |
489 | 259k | WORD32 n_long = usac_data->ccfl; |
490 | 259k | WORD32 td_frame_prev = usac_data->td_frame_prev[i_ch]; |
491 | 259k | WORD32 fac_apply = usac_data->fac_data_present[i_ch]; |
492 | 259k | WORD8 shiftp, output_q = 0, shift_olap = 14; |
493 | 259k | WORD32 max_shift; |
494 | | |
495 | 259k | WORD32 window_sequence = usac_data->window_sequence[i_ch]; |
496 | 259k | WORD32 window_select_prev = usac_data->window_shape_prev[i_ch]; |
497 | 259k | ia_usac_lpd_decoder_handle st = usac_data->str_tddec[i_ch]; |
498 | | |
499 | 259k | WORD32 err_code = 0; |
500 | 259k | if (usac_data->ec_flag) { |
501 | 0 | td_frame_prev = usac_data->td_frame_prev_ec[i_ch]; |
502 | 259k | } else { |
503 | 259k | if (ixheaacd_drc_offset->n_long & (ixheaacd_drc_offset->n_long - 1)) { |
504 | 22.7k | if ((ixheaacd_drc_offset->n_long != 48) && (ixheaacd_drc_offset->n_long != 96) && |
505 | 22.7k | (ixheaacd_drc_offset->n_long != 192) && (ixheaacd_drc_offset->n_long != 384) && |
506 | 22.7k | (ixheaacd_drc_offset->n_long != 768)) { |
507 | 0 | return -1; |
508 | 0 | } |
509 | 22.7k | } |
510 | 259k | } |
511 | | |
512 | 259k | max_shift = |
513 | 259k | ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
514 | 259k | ixheaacd_normalize(p_in_ibuffer, max_shift, ixheaacd_drc_offset->n_long); |
515 | 259k | shiftp = max_shift + 6; |
516 | | |
517 | 259k | ixheaacd_acelp_imdct(p_in_ibuffer, 2 * ixheaacd_drc_offset->n_long, |
518 | 259k | &shiftp, scratch_mem); |
519 | | |
520 | 259k | max_shift = |
521 | 259k | ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
522 | 259k | ixheaacd_normalize(p_in_ibuffer, max_shift - 1, ixheaacd_drc_offset->n_long); |
523 | 259k | shiftp += max_shift - 1; |
524 | 259k | if ((shiftp - shift_olap) > 31) { |
525 | 220k | shiftp = 31 + shift_olap; |
526 | 220k | } |
527 | | |
528 | 259k | switch (window_sequence) { |
529 | 184k | case ONLY_LONG_SEQUENCE: |
530 | 187k | case LONG_START_SEQUENCE: |
531 | 187k | err_code = ixheaacd_calc_window( |
532 | 187k | &window_long_prev, ixheaacd_drc_offset->n_long, window_select_prev, usac_data->ec_flag); |
533 | 187k | if (err_code == -1) return err_code; |
534 | 187k | output_q = ixheaacd_windowing_long1( |
535 | 187k | p_in_ibuffer + n_long / 2, p_overlap_ibuffer, window_long_prev, |
536 | 187k | window_long_prev + ixheaacd_drc_offset->n_long - 1, p_out_ibuffer, |
537 | 187k | ixheaacd_drc_offset->n_long, shiftp, shift_olap); |
538 | 187k | break; |
539 | | |
540 | 52.9k | case STOP_START_SEQUENCE: |
541 | 71.1k | case LONG_STOP_SEQUENCE: |
542 | 71.1k | err_code = ixheaacd_calc_window(&window_short_prev_ptr, |
543 | 71.1k | ixheaacd_drc_offset->n_trans_ls, |
544 | 71.1k | window_select_prev, usac_data->ec_flag); |
545 | 71.1k | if (err_code == -1) return err_code; |
546 | 71.1k | if (fac_apply) { |
547 | 33.3k | output_q = ixheaacd_windowing_long2( |
548 | 33.3k | p_in_ibuffer + n_long / 2, window_short_prev_ptr, fac_idata, |
549 | 33.3k | p_overlap_ibuffer, p_out_ibuffer, ixheaacd_drc_offset, shiftp, |
550 | 33.3k | shift_olap, fac_q); |
551 | 37.8k | } else { |
552 | 37.8k | output_q = ixheaacd_windowing_long3( |
553 | 37.8k | p_in_ibuffer + n_long / 2, window_short_prev_ptr, p_overlap_ibuffer, |
554 | 37.8k | p_out_ibuffer, |
555 | 37.8k | window_short_prev_ptr + ixheaacd_drc_offset->n_trans_ls - 1, |
556 | 37.8k | ixheaacd_drc_offset, shiftp, shift_olap); |
557 | 37.8k | } |
558 | 71.1k | break; |
559 | 259k | } |
560 | | |
561 | 129M | for (i = 0; i < ixheaacd_drc_offset->n_long / 2; i++) { |
562 | 129M | if (shiftp > shift_olap) { |
563 | 116M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 + i] = |
564 | 116M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shiftp - shift_olap); |
565 | 116M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 - i - 1] = |
566 | 116M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shiftp - shift_olap); |
567 | 116M | } |
568 | 12.7M | else { |
569 | 12.7M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 + i] = |
570 | 12.7M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shift_olap - shiftp); |
571 | 12.7M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 - i - 1] = |
572 | 12.7M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shift_olap - shiftp); |
573 | 12.7M | } |
574 | 129M | } |
575 | | |
576 | 259k | ixheaacd_scale_down_adj(p_out_ibuffer, p_out_ibuffer, |
577 | 259k | ixheaacd_drc_offset->n_long, output_q, 15); |
578 | | |
579 | 259k | if (td_frame_prev) { |
580 | 25.7k | qfac = 1.0f / (FLOAT32)(1 << 15); |
581 | | |
582 | 25.2M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
583 | 25.2M | p_out_buffer[k] = ((FLOAT32)p_out_ibuffer[k]) * qfac; |
584 | 25.2M | } |
585 | 25.7k | err_code = ixheaacd_lpd_bpf_fix(usac_data, 0, p_out_buffer, st); |
586 | 25.7k | if (err_code != 0) return err_code; |
587 | | |
588 | 25.2M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
589 | 25.2M | p_out_ibuffer[k] = (WORD32)(p_out_buffer[k] * (1 << 15)); |
590 | 25.2M | } |
591 | 25.7k | } |
592 | | |
593 | 259k | return 0; |
594 | 259k | } |
595 | | |
596 | 350k | WORD32 ixheaacd_fd_frm_dec(ia_usac_data_struct *usac_data, WORD32 i_ch) { |
597 | 350k | WORD32 fac_idata[2 * FAC_LENGTH + 16]; |
598 | 350k | offset_lengths ixheaacd_drc_offset; |
599 | 350k | WORD8 fac_q = 0; |
600 | 350k | IA_ERRORCODE err = IA_NO_ERROR; |
601 | 350k | WORD32 td_frame_prev, fac_apply, window_sequence; |
602 | 350k | if (usac_data->ec_flag) { |
603 | 0 | usac_data->str_error_concealment[i_ch].pstr_ec_scratch = |
604 | 0 | (ia_ec_scratch_str *)&usac_data->str_error_concealment[i_ch].str_ec_scratch; |
605 | 0 | usac_data->core_mode = 0; |
606 | 0 | ixheaacd_usac_apply_ec(usac_data, &ixheaacd_samp_rate_info[0], i_ch); |
607 | 0 | } |
608 | 350k | if (usac_data->ec_flag) { |
609 | 0 | td_frame_prev = usac_data->td_frame_prev_ec[i_ch]; |
610 | 350k | } else { |
611 | 350k | td_frame_prev = usac_data->td_frame_prev[i_ch]; |
612 | 350k | } |
613 | 350k | fac_apply = usac_data->fac_data_present[i_ch]; |
614 | 350k | window_sequence = usac_data->window_sequence[i_ch]; |
615 | 350k | ixheaacd_drc_offset.n_long = usac_data->ccfl; |
616 | 350k | ixheaacd_drc_offset.n_short = ixheaacd_drc_offset.n_long >> 3; |
617 | | |
618 | 350k | memset(fac_idata, 0, sizeof(fac_idata)); |
619 | | |
620 | 350k | if (td_frame_prev) { |
621 | 44.9k | if (window_sequence == EIGHT_SHORT_SEQUENCE) { |
622 | 19.2k | ixheaacd_drc_offset.lfac = ixheaacd_drc_offset.n_long >> 4; |
623 | 25.7k | } else { |
624 | 25.7k | ixheaacd_drc_offset.lfac = ixheaacd_drc_offset.n_long >> 3; |
625 | 25.7k | } |
626 | 44.9k | ixheaacd_drc_offset.n_flat_ls = |
627 | 44.9k | (ixheaacd_drc_offset.n_long - (ixheaacd_drc_offset.lfac) * 2) >> 1; |
628 | | |
629 | 44.9k | ixheaacd_drc_offset.n_trans_ls = (ixheaacd_drc_offset.lfac) << 1; |
630 | 305k | } else { |
631 | 305k | ixheaacd_drc_offset.lfac = FAC_LENGTH; |
632 | 305k | ixheaacd_drc_offset.n_flat_ls = |
633 | 305k | (ixheaacd_drc_offset.n_long - ixheaacd_drc_offset.n_short) >> 1; |
634 | 305k | ixheaacd_drc_offset.n_trans_ls = ixheaacd_drc_offset.n_short; |
635 | 305k | } |
636 | | |
637 | 350k | if (fac_apply && usac_data->frame_ok == 1) { |
638 | 97.3k | err = ixheaacd_cal_fac_data(usac_data, i_ch, ixheaacd_drc_offset.n_long, |
639 | 97.3k | ixheaacd_drc_offset.lfac, fac_idata, &fac_q); |
640 | 97.3k | if (err) return err; |
641 | 97.3k | } |
642 | | |
643 | 350k | if (window_sequence != EIGHT_SHORT_SEQUENCE) { |
644 | 259k | err = ixheaacd_fd_imdct_long(usac_data, i_ch, fac_idata, |
645 | 259k | &ixheaacd_drc_offset, fac_q); |
646 | 259k | if (err) return err; |
647 | 259k | } else { |
648 | 91.4k | err = ixheaacd_fd_imdct_short(usac_data, i_ch, fac_idata, |
649 | 91.4k | &ixheaacd_drc_offset, fac_q); |
650 | 91.4k | if (err) return err; |
651 | 91.4k | } |
652 | | |
653 | 350k | return err; |
654 | 350k | } |