/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 | 26.4M | #define ABS(A) ((A) < 0 ? (-A) : (A)) |
81 | | |
82 | 741k | static WORD32 ixheaacd_calc_max_spectralline(WORD32 *p_in_ibuffer, WORD32 n) { |
83 | 741k | WORD32 k, shiftp, itemp = 0; |
84 | 743M | for (k = 0; k < n; k++) { |
85 | 742M | if (ixheaac_abs32_sat(p_in_ibuffer[k]) > itemp) |
86 | 2.35M | itemp = ixheaac_abs32_sat(p_in_ibuffer[k]); |
87 | 742M | } |
88 | | |
89 | 741k | shiftp = ixheaac_norm32(itemp); |
90 | | |
91 | 741k | return (shiftp); |
92 | 741k | } |
93 | | |
94 | 741k | static void ixheaacd_normalize(WORD32 *buff, WORD32 shift, WORD len) { |
95 | 741k | WORD32 i; |
96 | | |
97 | 743M | for (i = 0; i < len; i++) { |
98 | 742M | buff[i] = buff[i] << shift; |
99 | 742M | } |
100 | 741k | } |
101 | | |
102 | 93.8k | static FLOAT32 ixheaacd_pow10(WORD32 input) { |
103 | 93.8k | FLOAT32 output = 1; |
104 | 199k | while (input > 0) { |
105 | 105k | output *= 10; |
106 | 105k | input--; |
107 | 105k | } |
108 | 93.8k | return (output); |
109 | 93.8k | } |
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 | 1.10M | const WORD32 *sin_ptr) { |
114 | 1.10M | WORD32 i; |
115 | 1.10M | WORD32 *ptr_y; |
116 | | |
117 | 1.10M | ptr_y = &ptr_x[2 * nlength - 1]; |
118 | | |
119 | 186M | for (i = 0; i < nlength; i++) { |
120 | 185M | *r_ptr++ = ((ixheaac_mult32(ixheaac_negate32_sat(*ptr_x), (*cos_ptr)) - |
121 | 185M | ixheaac_mult32((*ptr_y), (*sin_ptr)))); |
122 | 185M | *i_ptr++ = ((ixheaac_mult32((*ptr_y), (*cos_ptr++)) - |
123 | 185M | ixheaac_mult32((*ptr_x), (*sin_ptr++)))); |
124 | 185M | ptr_x += 2; |
125 | 185M | ptr_y -= 2; |
126 | 185M | } |
127 | 1.10M | } |
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 | 1.10M | ) { |
134 | 1.10M | WORD32 i; |
135 | 1.10M | WORD32 *yptr; |
136 | | |
137 | 1.10M | yptr = &xptr[2 * nlength - 1]; |
138 | | |
139 | 186M | for (i = 0; i < nlength; i++) { |
140 | 185M | *xptr = (-(ixheaac_mult32((r_ptr[i]), (*cos_ptr)) - |
141 | 185M | ixheaac_mult32((i_ptr[i]), (*sin_ptr)))); |
142 | 185M | *yptr = (-(ixheaac_mult32((i_ptr[i]), (*cos_ptr++)) + |
143 | 185M | ixheaac_mult32((r_ptr[i]), (*sin_ptr++)))); |
144 | 185M | xptr += 2; |
145 | 185M | yptr -= 2; |
146 | 185M | } |
147 | 1.10M | } |
148 | | |
149 | | static VOID ixheaacd_fft_based_imdct(WORD32 *data, WORD32 npoints, WORD32 *preshift, |
150 | 1.10M | WORD32 *tmp_data) { |
151 | 1.10M | WORD32 *data_r; |
152 | 1.10M | WORD32 *data_i; |
153 | 1.10M | WORD32 nlength = npoints >> 1; |
154 | 1.10M | const WORD32 *cos_ptr; |
155 | 1.10M | const WORD32 *sin_ptr; |
156 | | |
157 | 1.10M | data_r = tmp_data; |
158 | 1.10M | data_i = tmp_data + 512; |
159 | | |
160 | 1.10M | if (nlength == 512) { |
161 | 239k | cos_ptr = ixheaacd_pre_post_twid_cos_512; |
162 | 239k | sin_ptr = ixheaacd_pre_post_twid_sin_512; |
163 | 869k | } else if (nlength == 384) { |
164 | 26.2k | cos_ptr = ixheaacd_pre_post_twid_cos_384; |
165 | 26.2k | sin_ptr = ixheaacd_pre_post_twid_sin_384; |
166 | 843k | } else if (nlength == 64) { |
167 | 791k | cos_ptr = ixheaacd_pre_post_twid_cos_64; |
168 | 791k | sin_ptr = ixheaacd_pre_post_twid_sin_64; |
169 | 791k | } else if (nlength == 48) { |
170 | 51.9k | cos_ptr = ixheaacd_pre_post_twid_cos_48; |
171 | 51.9k | sin_ptr = ixheaacd_pre_post_twid_sin_48; |
172 | 51.9k | } 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 | 1.10M | (*ixheaacd_calc_pre_twid)(data, data_r, data_i, nlength, cos_ptr, sin_ptr); |
178 | 1.10M | ixheaacd_complex_fft(data_r, data_i, nlength, 1, preshift); |
179 | | |
180 | 1.10M | (*ixheaacd_calc_post_twid)(data, data_r, data_i, nlength, cos_ptr, sin_ptr); |
181 | 1.10M | return; |
182 | 1.10M | } |
183 | | |
184 | | #define N_LONG_LEN_MAX 1024 |
185 | | |
186 | | VOID ixheaacd_acelp_imdct(WORD32 *imdct_in, WORD32 npoints, WORD8 *qshift, |
187 | 1.10M | WORD32 *tmp_data) { |
188 | 1.10M | WORD32 preshift = 0; |
189 | 1.10M | WORD32 i; |
190 | 1.10M | WORD32 k = (npoints / 2); |
191 | | |
192 | 9.50M | while (((k & 1) == 0) & (k != 1)) { |
193 | 8.39M | k = k >> 1; |
194 | 8.39M | preshift++; |
195 | 8.39M | } |
196 | | |
197 | 1.10M | if ((k != 1)) { |
198 | 25.2M | for (i = 0; i < (npoints / 2); i++) { |
199 | 25.1M | imdct_in[i] = (imdct_in[i] / 3) << 1; |
200 | 25.1M | } |
201 | 78.2k | preshift++; |
202 | 78.2k | } |
203 | | |
204 | 1.10M | ixheaacd_fft_based_imdct(imdct_in, npoints / 2, &preshift, tmp_data); |
205 | 1.10M | preshift += 2; |
206 | 1.10M | *qshift -= preshift; |
207 | 1.10M | return; |
208 | 1.10M | } |
209 | | |
210 | | IA_ERRORCODE ixheaacd_cal_fac_data(ia_usac_data_struct *usac_data, WORD32 i_ch, |
211 | | WORD32 n_long, WORD32 lfac, |
212 | 93.8k | WORD32 *fac_idata, WORD8 *q_fac) { |
213 | 93.8k | WORD32 gain_fac, scale, k, *i_aq, itemp = 0, *izir; |
214 | 93.8k | WORD32 int_aq[ORDER + 1] = {0}; |
215 | 93.8k | WORD32 intzir[2 * LEN_FRAME] = {0}; |
216 | 93.8k | WORD32 x_in[FAC_LENGTH] = {0}; |
217 | 93.8k | FLOAT32 gain, ztemp, ftemp, pow10, rem10; |
218 | 93.8k | FLOAT32 qfac1; |
219 | 93.8k | WORD8 qshift1 = 0; |
220 | 93.8k | WORD8 qshift2 = 0; |
221 | 93.8k | WORD8 qshift3 = 0; |
222 | 93.8k | WORD32 preshift = 0; |
223 | | |
224 | 93.8k | FLOAT32 *last_lpc = usac_data->lpc_prev[i_ch]; |
225 | 93.8k | FLOAT32 *acelp_in = usac_data->acelp_in[i_ch]; |
226 | 93.8k | WORD32 *fac_data = usac_data->fac_data[i_ch]; |
227 | 93.8k | WORD32 *ptr_scratch = &usac_data->scratch_buffer[0]; |
228 | | |
229 | 93.8k | WORD32 quo = fac_data[0] / 28; |
230 | 93.8k | WORD32 rem = fac_data[0] % 28; |
231 | 93.8k | pow10 = ixheaacd_pow10(quo); |
232 | 93.8k | rem10 = (FLOAT32)ixheaacd_power_10_table[rem]; |
233 | | |
234 | 93.8k | gain = pow10 * rem10; |
235 | 93.8k | scale = (WORD32)(ixheaac_norm32((WORD32)((ABS(gain) + 1)))); |
236 | 93.8k | gain_fac = (WORD32)(gain * (FLOAT32)((WORD64)1 << scale)); |
237 | 93.8k | scale += 4; |
238 | 93.8k | qfac1 = 1.0f / (gain); |
239 | | |
240 | 93.8k | if (acelp_in != NULL) { |
241 | 93.8k | izir = intzir; |
242 | 93.8k | ftemp = 0.0; |
243 | 24.0M | for (k = 0; k < n_long / 4; k++) { |
244 | 23.9M | ztemp = acelp_in[k] * (qfac1); |
245 | 23.9M | if (ABS(ztemp) > ftemp) ftemp = ABS(ztemp); |
246 | 23.9M | } |
247 | | |
248 | 93.8k | itemp = (WORD32)(ftemp); |
249 | 93.8k | qshift3 = ixheaac_norm32(itemp); |
250 | | |
251 | 24.0M | for (k = 0; k < n_long / 4; k++) { |
252 | 23.9M | izir[k] = |
253 | 23.9M | (WORD32)((acelp_in[k] * (qfac1)) * (FLOAT32)((WORD64)1 << qshift3)); |
254 | 23.9M | } |
255 | 93.8k | } else |
256 | 0 | izir = NULL; |
257 | | |
258 | 93.8k | if (last_lpc != NULL) { |
259 | 93.8k | ftemp = 0.0; |
260 | 93.8k | i_aq = int_aq; |
261 | 1.68M | for (k = 0; k < ORDER + 1; k++) { |
262 | 1.59M | if (ABS(last_lpc[k]) > ftemp) ftemp = ABS(last_lpc[k]); |
263 | 1.59M | } |
264 | | |
265 | 93.8k | itemp = (WORD32)(ftemp); |
266 | 93.8k | qshift2 = ixheaac_norm32(itemp); |
267 | | |
268 | 1.68M | for (k = 0; k < ORDER + 1; k++) { |
269 | 1.59M | i_aq[k] = (WORD32)(last_lpc[k] * (FLOAT32)((WORD64)1 << qshift2)); |
270 | 1.59M | } |
271 | 93.8k | } else |
272 | 0 | i_aq = NULL; |
273 | | |
274 | 11.7M | for (k = 0; k < lfac; k++) { |
275 | 11.6M | if (ixheaac_abs32_sat(fac_data[k + 1]) > itemp) |
276 | 151k | itemp = ixheaac_abs32_sat(fac_data[k + 1]); |
277 | 11.6M | } |
278 | | |
279 | 93.8k | qshift1 = ixheaac_norm32(itemp); |
280 | | |
281 | 11.7M | for (k = 0; k < lfac; k++) { |
282 | 11.6M | fac_data[k + 1] = |
283 | 11.6M | (WORD32)(fac_data[k + 1] * (FLOAT32)((WORD64)1 << qshift1)); |
284 | 11.6M | } |
285 | | |
286 | 5.92M | for (k = 0; k < lfac / 2; k++) { |
287 | 5.83M | x_in[k] = fac_data[2 * k + 1]; |
288 | 5.83M | x_in[lfac / 2 + k] = fac_data[lfac - 2 * k]; |
289 | 5.83M | } |
290 | | |
291 | 93.8k | 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 | 93.8k | if ((n_long / 8) < lfac) { |
299 | 89 | if (usac_data->ec_flag == 0) |
300 | 89 | return -1; |
301 | 0 | else |
302 | 0 | lfac = (n_long / 8); |
303 | 89 | } |
304 | | |
305 | 93.7k | 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 | 93.7k | if (lfac & (lfac - 1)) { |
313 | 784 | 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 | 784 | } |
320 | | |
321 | 93.7k | ixheaacd_fr_alias_cnx_fix(x_in, n_long / 4, lfac, i_aq, izir, fac_idata + 16, &qshift1, qshift2, |
322 | 93.7k | qshift3, &preshift, ptr_scratch); |
323 | | |
324 | 93.7k | preshift += 4; |
325 | 93.7k | *q_fac = (qshift1 - preshift); |
326 | | |
327 | 93.7k | if (acelp_in != NULL) { |
328 | 23.4M | for (k = 0; k < 2 * lfac; k++) { |
329 | 23.3M | fac_idata[k] = |
330 | 23.3M | ixheaac_mul32_sh(fac_idata[k + 16], gain_fac, (WORD8)(scale)); |
331 | 23.3M | } |
332 | 93.7k | } |
333 | 93.7k | return IA_NO_ERROR; |
334 | 93.7k | } |
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 | 105k | WORD8 fac_q) { |
340 | 105k | FLOAT32 qfac; |
341 | 105k | WORD32 overlap_data_buf[2 * N_LONG_LEN_MAX] = {0}; |
342 | 105k | WORD32 *window_short, k, *window_short_prev_ptr; |
343 | 105k | WORD32 *overlap_data, *fp; |
344 | | |
345 | 105k | WORD32 *p_overlap_ibuffer = usac_data->overlap_data_ptr[i_ch]; |
346 | 105k | WORD32 *p_in_ibuffer = usac_data->coef_fix[i_ch]; |
347 | 105k | FLOAT32 *p_out_buffer = usac_data->time_sample_vector[i_ch]; |
348 | 105k | WORD32 *p_out_ibuffer = usac_data->output_data_ptr[i_ch]; |
349 | 105k | WORD32 *scratch_mem = usac_data->scratch_buffer; |
350 | 105k | WORD32 td_frame_prev = usac_data->td_frame_prev[i_ch]; |
351 | 105k | WORD32 fac_apply = usac_data->fac_data_present[i_ch]; |
352 | 105k | WORD8 shiftp, input_q, output_q, shift_olap = 14; |
353 | 105k | WORD32 max_shift; |
354 | | |
355 | 105k | WORD32 window_select = usac_data->window_shape[i_ch]; |
356 | 105k | WORD32 window_select_prev = usac_data->window_shape_prev[i_ch]; |
357 | 105k | ia_usac_lpd_decoder_handle st = usac_data->str_tddec[i_ch]; |
358 | 105k | WORD32 err_code = 0; |
359 | | |
360 | 105k | if (usac_data->ec_flag) { |
361 | 0 | td_frame_prev = usac_data->td_frame_prev_ec[i_ch]; |
362 | 105k | } else { |
363 | 105k | if (ixheaacd_drc_offset->n_short & (ixheaacd_drc_offset->n_short - 1)) { |
364 | 6.49k | if ((ixheaacd_drc_offset->n_short != 48) && (ixheaacd_drc_offset->n_short != 96) && |
365 | 6.49k | (ixheaacd_drc_offset->n_short != 192) && (ixheaacd_drc_offset->n_short != 384) && |
366 | 6.49k | (ixheaacd_drc_offset->n_short != 768)) { |
367 | 0 | return -1; |
368 | 0 | } |
369 | 6.49k | } |
370 | 105k | } |
371 | | |
372 | 105k | max_shift = ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
373 | 105k | ixheaacd_normalize(p_in_ibuffer, max_shift, ixheaacd_drc_offset->n_long); |
374 | 105k | shiftp = max_shift + 6; |
375 | 105k | input_q = shiftp; |
376 | | |
377 | 105k | memcpy(overlap_data_buf, p_overlap_ibuffer, |
378 | 105k | sizeof(WORD32) * ixheaacd_drc_offset->n_long); |
379 | 105k | overlap_data = overlap_data_buf; |
380 | | |
381 | 105k | fp = overlap_data + ixheaacd_drc_offset->n_flat_ls; |
382 | | |
383 | 948k | for (k = 0; k < 8; k++) { |
384 | 843k | shiftp = input_q; |
385 | 843k | ixheaacd_acelp_imdct( |
386 | 843k | p_in_ibuffer + (k * ixheaacd_drc_offset->n_short), |
387 | 843k | 2 * ixheaacd_drc_offset->n_short, &shiftp, scratch_mem); |
388 | 843k | } |
389 | | |
390 | 105k | max_shift = |
391 | 105k | ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
392 | 105k | ixheaacd_normalize(p_in_ibuffer, max_shift - 1, ixheaacd_drc_offset->n_long); |
393 | 105k | shiftp += max_shift - 1; |
394 | | |
395 | 105k | if ((shiftp - shift_olap) > 31) { |
396 | 43.8k | shiftp = 31 + shift_olap; |
397 | 43.8k | } |
398 | 105k | err_code = ixheaacd_calc_window(&window_short, ixheaacd_drc_offset->n_short, |
399 | 105k | window_select, usac_data->ec_flag); |
400 | 105k | if (err_code == -1) return err_code; |
401 | 105k | err_code = ixheaacd_calc_window(&window_short_prev_ptr, ixheaacd_drc_offset->n_trans_ls, |
402 | 105k | window_select_prev, usac_data->ec_flag); |
403 | 105k | if (err_code == -1) return err_code; |
404 | | |
405 | 105k | if (fac_apply) |
406 | 31.7k | ixheaacd_windowing_short1(p_in_ibuffer + ixheaacd_drc_offset->n_short / 2, |
407 | 31.7k | window_short_prev_ptr, fp, ixheaacd_drc_offset, |
408 | 31.7k | shiftp, shift_olap); |
409 | | |
410 | 73.6k | else |
411 | 73.6k | ixheaacd_windowing_short2(p_in_ibuffer + ixheaacd_drc_offset->n_short / 2, |
412 | 73.6k | window_short_prev_ptr, fp, ixheaacd_drc_offset, |
413 | 73.6k | shiftp, shift_olap); |
414 | | |
415 | 105k | output_q = ixheaacd_windowing_short3( |
416 | 105k | p_in_ibuffer, window_short + ixheaacd_drc_offset->n_short - 1, |
417 | 105k | fp + ixheaacd_drc_offset->n_short, ixheaacd_drc_offset->n_short, shiftp, |
418 | 105k | shift_olap); |
419 | 105k | p_in_ibuffer += ixheaacd_drc_offset->n_short; |
420 | 105k | fp += ixheaacd_drc_offset->n_short; |
421 | 105k | window_short_prev_ptr = window_short; |
422 | | |
423 | 737k | for (k = 1; k < 7; k++) { |
424 | 632k | output_q = ixheaacd_windowing_short4( |
425 | 632k | p_in_ibuffer, window_short_prev_ptr, fp, |
426 | 632k | window_short_prev_ptr + ixheaacd_drc_offset->n_short - 1, |
427 | 632k | ixheaacd_drc_offset->n_short, 1, shiftp, shift_olap, output_q); |
428 | 632k | p_in_ibuffer += ixheaacd_drc_offset->n_short; |
429 | 632k | fp += ixheaacd_drc_offset->n_short; |
430 | 632k | window_short_prev_ptr = window_short; |
431 | 632k | } |
432 | | |
433 | 105k | output_q = ixheaacd_windowing_short4( |
434 | 105k | p_in_ibuffer, window_short_prev_ptr, fp, |
435 | 105k | window_short_prev_ptr + ixheaacd_drc_offset->n_short - 1, |
436 | 105k | ixheaacd_drc_offset->n_short, 0, shiftp, shift_olap, output_q); |
437 | 105k | p_in_ibuffer += ixheaacd_drc_offset->n_short; |
438 | 105k | fp += ixheaacd_drc_offset->n_short; |
439 | | |
440 | 105k | if (fac_apply) { |
441 | 31.7k | ixheaacd_combine_fac(overlap_data + ixheaacd_drc_offset->n_flat_ls + |
442 | 31.7k | ixheaacd_drc_offset->lfac, |
443 | 31.7k | fac_data_out, |
444 | 31.7k | overlap_data + ixheaacd_drc_offset->n_flat_ls + |
445 | 31.7k | ixheaacd_drc_offset->lfac, |
446 | 31.7k | 2 * ixheaacd_drc_offset->lfac, output_q, fac_q); |
447 | 31.7k | } |
448 | 105k | memset(overlap_data + 2 * ixheaacd_drc_offset->n_long - |
449 | 105k | ixheaacd_drc_offset->n_flat_ls, |
450 | 105k | 0, sizeof(WORD32) * ixheaacd_drc_offset->n_flat_ls); |
451 | 105k | ixheaacd_scale_down(overlap_data, overlap_data, |
452 | 105k | ixheaacd_drc_offset->n_flat_ls, shift_olap, output_q); |
453 | | |
454 | 105k | ixheaacd_scale_down(p_overlap_ibuffer, |
455 | 105k | overlap_data + ixheaacd_drc_offset->n_long, |
456 | 105k | ixheaacd_drc_offset->n_long, output_q, shift_olap); |
457 | 105k | ixheaacd_scale_down(p_out_ibuffer, overlap_data, ixheaacd_drc_offset->n_long, |
458 | 105k | output_q, 15); |
459 | | |
460 | 105k | if (td_frame_prev) { |
461 | 14.9k | qfac = 1.0f / (FLOAT32)(1 << 15); |
462 | | |
463 | 13.9M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
464 | 13.9M | p_out_buffer[k] = ((FLOAT32)p_out_ibuffer[k]) * qfac; |
465 | 13.9M | } |
466 | 14.9k | err_code = ixheaacd_lpd_bpf_fix(usac_data, 1, p_out_buffer, st); |
467 | 14.9k | if (err_code != 0) return err_code; |
468 | | |
469 | 13.9M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
470 | 13.9M | p_out_ibuffer[k] = (WORD32)(p_out_buffer[k] * (1 << 15)); |
471 | 13.9M | } |
472 | 14.9k | } |
473 | | |
474 | 105k | return 0; |
475 | 105k | } |
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 | 265k | WORD8 fac_q) { |
481 | 265k | FLOAT32 qfac; |
482 | 265k | WORD32 *window_long_prev = NULL, k, i, *window_short_prev_ptr = NULL; |
483 | | |
484 | 265k | WORD32 *p_in_ibuffer = usac_data->coef_fix[i_ch]; |
485 | 265k | WORD32 *p_overlap_ibuffer = usac_data->overlap_data_ptr[i_ch]; |
486 | 265k | WORD32 *p_out_ibuffer = usac_data->output_data_ptr[i_ch]; |
487 | 265k | FLOAT32 *p_out_buffer = usac_data->time_sample_vector[i_ch]; |
488 | 265k | WORD32 *scratch_mem = usac_data->scratch_buffer; |
489 | 265k | WORD32 n_long = usac_data->ccfl; |
490 | 265k | WORD32 td_frame_prev = usac_data->td_frame_prev[i_ch]; |
491 | 265k | WORD32 fac_apply = usac_data->fac_data_present[i_ch]; |
492 | 265k | WORD8 shiftp, output_q = 0, shift_olap = 14; |
493 | 265k | WORD32 max_shift; |
494 | | |
495 | 265k | WORD32 window_sequence = usac_data->window_sequence[i_ch]; |
496 | 265k | WORD32 window_select_prev = usac_data->window_shape_prev[i_ch]; |
497 | 265k | ia_usac_lpd_decoder_handle st = usac_data->str_tddec[i_ch]; |
498 | | |
499 | 265k | WORD32 err_code = 0; |
500 | 265k | if (usac_data->ec_flag) { |
501 | 0 | td_frame_prev = usac_data->td_frame_prev_ec[i_ch]; |
502 | 265k | } else { |
503 | 265k | if (ixheaacd_drc_offset->n_long & (ixheaacd_drc_offset->n_long - 1)) { |
504 | 26.2k | if ((ixheaacd_drc_offset->n_long != 48) && (ixheaacd_drc_offset->n_long != 96) && |
505 | 26.2k | (ixheaacd_drc_offset->n_long != 192) && (ixheaacd_drc_offset->n_long != 384) && |
506 | 26.2k | (ixheaacd_drc_offset->n_long != 768)) { |
507 | 0 | return -1; |
508 | 0 | } |
509 | 26.2k | } |
510 | 265k | } |
511 | | |
512 | 265k | max_shift = |
513 | 265k | ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
514 | 265k | ixheaacd_normalize(p_in_ibuffer, max_shift, ixheaacd_drc_offset->n_long); |
515 | 265k | shiftp = max_shift + 6; |
516 | | |
517 | 265k | ixheaacd_acelp_imdct(p_in_ibuffer, 2 * ixheaacd_drc_offset->n_long, |
518 | 265k | &shiftp, scratch_mem); |
519 | | |
520 | 265k | max_shift = |
521 | 265k | ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long); |
522 | 265k | ixheaacd_normalize(p_in_ibuffer, max_shift - 1, ixheaacd_drc_offset->n_long); |
523 | 265k | shiftp += max_shift - 1; |
524 | 265k | if ((shiftp - shift_olap) > 31) { |
525 | 229k | shiftp = 31 + shift_olap; |
526 | 229k | } |
527 | | |
528 | 265k | switch (window_sequence) { |
529 | 198k | case ONLY_LONG_SEQUENCE: |
530 | 202k | case LONG_START_SEQUENCE: |
531 | 202k | err_code = ixheaacd_calc_window( |
532 | 202k | &window_long_prev, ixheaacd_drc_offset->n_long, window_select_prev, usac_data->ec_flag); |
533 | 202k | if (err_code == -1) return err_code; |
534 | 202k | output_q = ixheaacd_windowing_long1( |
535 | 202k | p_in_ibuffer + n_long / 2, p_overlap_ibuffer, window_long_prev, |
536 | 202k | window_long_prev + ixheaacd_drc_offset->n_long - 1, p_out_ibuffer, |
537 | 202k | ixheaacd_drc_offset->n_long, shiftp, shift_olap); |
538 | 202k | break; |
539 | | |
540 | 42.5k | case STOP_START_SEQUENCE: |
541 | 63.3k | case LONG_STOP_SEQUENCE: |
542 | 63.3k | err_code = ixheaacd_calc_window(&window_short_prev_ptr, |
543 | 63.3k | ixheaacd_drc_offset->n_trans_ls, |
544 | 63.3k | window_select_prev, usac_data->ec_flag); |
545 | 63.3k | if (err_code == -1) return err_code; |
546 | 63.3k | if (fac_apply) { |
547 | 31.0k | output_q = ixheaacd_windowing_long2( |
548 | 31.0k | p_in_ibuffer + n_long / 2, window_short_prev_ptr, fac_idata, |
549 | 31.0k | p_overlap_ibuffer, p_out_ibuffer, ixheaacd_drc_offset, shiftp, |
550 | 31.0k | shift_olap, fac_q); |
551 | 32.2k | } else { |
552 | 32.2k | output_q = ixheaacd_windowing_long3( |
553 | 32.2k | p_in_ibuffer + n_long / 2, window_short_prev_ptr, p_overlap_ibuffer, |
554 | 32.2k | p_out_ibuffer, |
555 | 32.2k | window_short_prev_ptr + ixheaacd_drc_offset->n_trans_ls - 1, |
556 | 32.2k | ixheaacd_drc_offset, shiftp, shift_olap); |
557 | 32.2k | } |
558 | 63.3k | break; |
559 | 265k | } |
560 | | |
561 | 132M | for (i = 0; i < ixheaacd_drc_offset->n_long / 2; i++) { |
562 | 132M | if (shiftp > shift_olap) { |
563 | 119M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 + i] = |
564 | 119M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shiftp - shift_olap); |
565 | 119M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 - i - 1] = |
566 | 119M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shiftp - shift_olap); |
567 | 119M | } |
568 | 13.3M | else { |
569 | 13.3M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 + i] = |
570 | 13.3M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shift_olap - shiftp); |
571 | 13.3M | p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 - i - 1] = |
572 | 13.3M | ixheaac_negate32_sat(p_in_ibuffer[i]) >> (shift_olap - shiftp); |
573 | 13.3M | } |
574 | 132M | } |
575 | | |
576 | 265k | ixheaacd_scale_down_adj(p_out_ibuffer, p_out_ibuffer, |
577 | 265k | ixheaacd_drc_offset->n_long, output_q, 15); |
578 | | |
579 | 265k | if (td_frame_prev) { |
580 | 23.8k | qfac = 1.0f / (FLOAT32)(1 << 15); |
581 | | |
582 | 23.3M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
583 | 23.3M | p_out_buffer[k] = ((FLOAT32)p_out_ibuffer[k]) * qfac; |
584 | 23.3M | } |
585 | 23.8k | err_code = ixheaacd_lpd_bpf_fix(usac_data, 0, p_out_buffer, st); |
586 | 23.8k | if (err_code != 0) return err_code; |
587 | | |
588 | 23.3M | for (k = 0; k < ixheaacd_drc_offset->n_long; k++) { |
589 | 23.3M | p_out_ibuffer[k] = (WORD32)(p_out_buffer[k] * (1 << 15)); |
590 | 23.3M | } |
591 | 23.7k | } |
592 | | |
593 | 265k | return 0; |
594 | 265k | } |
595 | | |
596 | 370k | WORD32 ixheaacd_fd_frm_dec(ia_usac_data_struct *usac_data, WORD32 i_ch) { |
597 | 370k | WORD32 fac_idata[2 * FAC_LENGTH + 16]; |
598 | 370k | offset_lengths ixheaacd_drc_offset; |
599 | 370k | WORD8 fac_q = 0; |
600 | 370k | IA_ERRORCODE err = IA_NO_ERROR; |
601 | 370k | WORD32 td_frame_prev, fac_apply, window_sequence; |
602 | 370k | 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 | 370k | if (usac_data->ec_flag) { |
609 | 0 | td_frame_prev = usac_data->td_frame_prev_ec[i_ch]; |
610 | 370k | } else { |
611 | 370k | td_frame_prev = usac_data->td_frame_prev[i_ch]; |
612 | 370k | } |
613 | 370k | fac_apply = usac_data->fac_data_present[i_ch]; |
614 | 370k | window_sequence = usac_data->window_sequence[i_ch]; |
615 | 370k | ixheaacd_drc_offset.n_long = usac_data->ccfl; |
616 | 370k | ixheaacd_drc_offset.n_short = ixheaacd_drc_offset.n_long >> 3; |
617 | | |
618 | 370k | memset(fac_idata, 0, sizeof(fac_idata)); |
619 | | |
620 | 370k | if (td_frame_prev) { |
621 | 38.7k | if (window_sequence == EIGHT_SHORT_SEQUENCE) { |
622 | 14.9k | ixheaacd_drc_offset.lfac = ixheaacd_drc_offset.n_long >> 4; |
623 | 23.8k | } else { |
624 | 23.8k | ixheaacd_drc_offset.lfac = ixheaacd_drc_offset.n_long >> 3; |
625 | 23.8k | } |
626 | 38.7k | ixheaacd_drc_offset.n_flat_ls = |
627 | 38.7k | (ixheaacd_drc_offset.n_long - (ixheaacd_drc_offset.lfac) * 2) >> 1; |
628 | | |
629 | 38.7k | ixheaacd_drc_offset.n_trans_ls = (ixheaacd_drc_offset.lfac) << 1; |
630 | 332k | } else { |
631 | 332k | ixheaacd_drc_offset.lfac = FAC_LENGTH; |
632 | 332k | ixheaacd_drc_offset.n_flat_ls = |
633 | 332k | (ixheaacd_drc_offset.n_long - ixheaacd_drc_offset.n_short) >> 1; |
634 | 332k | ixheaacd_drc_offset.n_trans_ls = ixheaacd_drc_offset.n_short; |
635 | 332k | } |
636 | | |
637 | 370k | if (fac_apply && usac_data->frame_ok == 1) { |
638 | 93.8k | err = ixheaacd_cal_fac_data(usac_data, i_ch, ixheaacd_drc_offset.n_long, |
639 | 93.8k | ixheaacd_drc_offset.lfac, fac_idata, &fac_q); |
640 | 93.8k | if (err) return err; |
641 | 93.8k | } |
642 | | |
643 | 370k | if (window_sequence != EIGHT_SHORT_SEQUENCE) { |
644 | 265k | err = ixheaacd_fd_imdct_long(usac_data, i_ch, fac_idata, |
645 | 265k | &ixheaacd_drc_offset, fac_q); |
646 | 265k | if (err) return err; |
647 | 265k | } else { |
648 | 105k | err = ixheaacd_fd_imdct_short(usac_data, i_ch, fac_idata, |
649 | 105k | &ixheaacd_drc_offset, fac_q); |
650 | 105k | if (err) return err; |
651 | 105k | } |
652 | | |
653 | 370k | return err; |
654 | 370k | } |