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 "ixheaacd_type_def.h"
26 #include "ixheaacd_interface.h"
27
28 #include "ixheaacd_bitbuffer.h"
29 #include "ixheaacd_interface.h"
30
31 #include "ixheaacd_tns_usac.h"
32 #include "ixheaacd_cnst.h"
33 #include "ixheaacd_acelp_info.h"
34
35 #include "ixheaacd_td_mdct.h"
36
37 #include "ixheaacd_sbrdecsettings.h"
38 #include "ixheaacd_info.h"
39 #include "ixheaacd_sbr_common.h"
40 #include "ixheaacd_drc_data_struct.h"
41 #include "ixheaacd_drc_dec.h"
42 #include "ixheaacd_sbrdecoder.h"
43 #include "ixheaacd_mps_polyphase.h"
44 #include "ixheaacd_sbr_const.h"
45 #include "ixheaacd_main.h"
46 #include "ixheaacd_arith_dec.h"
47 #include "ixheaacd_windows.h"
48
49 #include "ixheaacd_vec_baisc_ops.h"
50 #include "ixheaacd_constants.h"
51 #include "ixheaacd_function_selector.h"
52 #include "ixheaacd_basic_ops32.h"
53 #include "ixheaacd_basic_ops40.h"
54
55 #include "ixheaacd_func_def.h"
56
57 #include "ixheaacd_windows.h"
58
59 extern const WORD32 ixheaacd_pre_post_twid_cos_512[512];
60 extern const WORD32 ixheaacd_pre_post_twid_sin_512[512];
61 extern const WORD32 ixheaacd_pre_post_twid_cos_384[384];
62 extern const WORD32 ixheaacd_pre_post_twid_sin_384[384];
63 extern const WORD32 ixheaacd_pre_post_twid_cos_64[64];
64 extern const WORD32 ixheaacd_pre_post_twid_sin_64[64];
65 extern const WORD32 ixheaacd_pre_post_twid_cos_48[48];
66 extern const WORD32 ixheaacd_pre_post_twid_sin_48[48];
67 extern const FLOAT64 ixheaacd_power_10_table[28];
68
69 #define ABS(A) ((A) < 0 ? (-A) : (A))
70
ixheaacd_calc_max_spectralline(WORD32 * p_in_ibuffer,WORD32 n)71 static WORD32 ixheaacd_calc_max_spectralline(WORD32 *p_in_ibuffer, WORD32 n) {
72 WORD32 k, shiftp, itemp = 0;
73 for (k = 0; k < n; k++) {
74 if (ixheaacd_abs32_sat(p_in_ibuffer[k]) > itemp)
75 itemp = ixheaacd_abs32_sat(p_in_ibuffer[k]);
76 }
77
78 shiftp = ixheaacd_norm32(itemp);
79
80 return (shiftp);
81 }
82
ixheaacd_normalize(WORD32 * buff,WORD32 shift,WORD len)83 static void ixheaacd_normalize(WORD32 *buff, WORD32 shift, WORD len) {
84 WORD32 i;
85
86 for (i = 0; i < len; i++) {
87 buff[i] = buff[i] << shift;
88 }
89 }
90
ixheaacd_pow10(WORD32 input)91 static FLOAT32 ixheaacd_pow10(WORD32 input) {
92 FLOAT32 output = 1;
93 while (input > 0) {
94 output *= 10;
95 input--;
96 }
97 return (output);
98 }
99
ixheaacd_calc_pre_twid_dec(WORD32 * ptr_x,WORD32 * r_ptr,WORD32 * i_ptr,WORD32 nlength,const WORD32 * cos_ptr,const WORD32 * sin_ptr)100 void ixheaacd_calc_pre_twid_dec(WORD32 *ptr_x, WORD32 *r_ptr, WORD32 *i_ptr,
101 WORD32 nlength, const WORD32 *cos_ptr,
102 const WORD32 *sin_ptr) {
103 WORD32 i;
104 WORD32 *ptr_y;
105
106 ptr_y = &ptr_x[2 * nlength - 1];
107
108 for (i = 0; i < nlength; i++) {
109 *r_ptr++ = ((ixheaacd_mult32(ixheaacd_negate32_sat(*ptr_x), (*cos_ptr)) -
110 ixheaacd_mult32((*ptr_y), (*sin_ptr))));
111 *i_ptr++ = ((ixheaacd_mult32((*ptr_y), (*cos_ptr++)) -
112 ixheaacd_mult32((*ptr_x), (*sin_ptr++))));
113 ptr_x += 2;
114 ptr_y -= 2;
115 }
116 }
117
ixheaacd_calc_post_twid_dec(WORD32 * xptr,WORD32 * r_ptr,WORD32 * i_ptr,WORD32 nlength,const WORD32 * cos_ptr,const WORD32 * sin_ptr)118 void ixheaacd_calc_post_twid_dec(WORD32 *xptr, WORD32 *r_ptr, WORD32 *i_ptr,
119 WORD32 nlength, const WORD32 *cos_ptr,
120 const WORD32 *sin_ptr
121
122 ) {
123 WORD32 i;
124 WORD32 *yptr;
125
126 yptr = &xptr[2 * nlength - 1];
127
128 for (i = 0; i < nlength; i++) {
129 *xptr = (-(ixheaacd_mult32((r_ptr[i]), (*cos_ptr)) -
130 ixheaacd_mult32((i_ptr[i]), (*sin_ptr))));
131 *yptr = (-(ixheaacd_mult32((i_ptr[i]), (*cos_ptr++)) +
132 ixheaacd_mult32((r_ptr[i]), (*sin_ptr++))));
133 xptr += 2;
134 yptr -= 2;
135 }
136 }
137
ixheaacd_fft_based_imdct(WORD32 * data,WORD32 npoints,WORD32 * preshift,WORD32 * tmp_data)138 static WORD32 ixheaacd_fft_based_imdct(WORD32 *data, WORD32 npoints,
139 WORD32 *preshift, WORD32 *tmp_data) {
140 WORD32 *data_r;
141 WORD32 *data_i;
142 WORD32 nlength = npoints >> 1;
143 WORD32 err = 0;
144 const WORD32 *cos_ptr;
145 const WORD32 *sin_ptr;
146
147 data_r = tmp_data;
148 data_i = tmp_data + 512;
149
150 if (nlength == 512) {
151 cos_ptr = ixheaacd_pre_post_twid_cos_512;
152 sin_ptr = ixheaacd_pre_post_twid_sin_512;
153 } else if (nlength == 384) {
154 cos_ptr = ixheaacd_pre_post_twid_cos_384;
155 sin_ptr = ixheaacd_pre_post_twid_sin_384;
156 } else if (nlength == 64) {
157 cos_ptr = ixheaacd_pre_post_twid_cos_64;
158 sin_ptr = ixheaacd_pre_post_twid_sin_64;
159 } else if (nlength == 48) {
160 cos_ptr = ixheaacd_pre_post_twid_cos_48;
161 sin_ptr = ixheaacd_pre_post_twid_sin_48;
162 } else {
163 cos_ptr = ixheaacd_pre_post_twid_cos_48;
164 sin_ptr = ixheaacd_pre_post_twid_sin_48;
165 }
166
167 (*ixheaacd_calc_pre_twid)(data, data_r, data_i, nlength, cos_ptr, sin_ptr);
168 err = ixheaacd_complex_fft(data_r, data_i, nlength, 1, preshift);
169 if (err) return err;
170 (*ixheaacd_calc_post_twid)(data, data_r, data_i, nlength, cos_ptr, sin_ptr);
171 return err;
172 }
173
174 #define N_LONG_LEN_MAX 1024
175
ixheaacd_acelp_imdct(WORD32 * imdct_in,WORD32 npoints,WORD8 * qshift,WORD32 * tmp_data)176 WORD32 ixheaacd_acelp_imdct(WORD32 *imdct_in, WORD32 npoints, WORD8 *qshift,
177 WORD32 *tmp_data) {
178 WORD32 preshift = 0;
179 WORD32 i;
180 WORD32 k = (npoints / 2);
181 WORD32 err = 0;
182
183 while (((k & 1) == 0) & (k != 1)) {
184 k = k >> 1;
185 preshift++;
186 }
187
188 if ((k != 1)) {
189 for (i = 0; i < (npoints / 2); i++) {
190 imdct_in[i] = (imdct_in[i] / 3) << 1;
191 }
192 preshift++;
193 }
194
195 err = ixheaacd_fft_based_imdct(imdct_in, npoints / 2, &preshift, tmp_data);
196 if (err) return err;
197 preshift += 2;
198 *qshift -= preshift;
199 return err;
200 }
201
ixheaacd_cal_fac_data(ia_usac_data_struct * usac_data,WORD32 i_ch,WORD32 n_long,WORD32 lfac,WORD32 * fac_idata,WORD8 * q_fac)202 IA_ERRORCODE ixheaacd_cal_fac_data(ia_usac_data_struct *usac_data, WORD32 i_ch,
203 WORD32 n_long, WORD32 lfac,
204 WORD32 *fac_idata, WORD8 *q_fac) {
205 WORD32 gain_fac, scale, k, *i_aq, itemp = 0, *izir;
206 WORD32 int_aq[ORDER + 1] = {0};
207 WORD32 intzir[2 * LEN_FRAME] = {0};
208 WORD32 x_in[FAC_LENGTH] = {0};
209 FLOAT32 gain, ztemp, ftemp, pow10, rem10;
210 FLOAT32 qfac1;
211 WORD8 qshift1 = 0;
212 WORD8 qshift2 = 0;
213 WORD8 qshift3 = 0;
214 WORD32 preshift = 0;
215 IA_ERRORCODE err = IA_NO_ERROR;
216
217 FLOAT32 *last_lpc = usac_data->lpc_prev[i_ch];
218 FLOAT32 *acelp_in = usac_data->acelp_in[i_ch];
219 WORD32 *fac_data = usac_data->fac_data[i_ch];
220 WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
221
222 WORD32 quo = fac_data[0] / 28;
223 WORD32 rem = fac_data[0] % 28;
224 pow10 = ixheaacd_pow10(quo);
225 rem10 = (FLOAT32)ixheaacd_power_10_table[rem];
226
227 gain = pow10 * rem10;
228 scale = (WORD32)(ixheaacd_norm32((WORD32)((ABS(gain) + 1))));
229 gain_fac = (WORD32)(gain * (FLOAT32)((WORD64)1 << scale));
230 scale += 4;
231 qfac1 = 1.0f / (gain);
232
233 if (acelp_in != NULL) {
234 izir = intzir;
235 ftemp = 0.0;
236 for (k = 0; k < n_long / 4; k++) {
237 ztemp = acelp_in[k] * (qfac1);
238 if (ABS(ztemp) > ftemp) ftemp = ABS(ztemp);
239 }
240
241 itemp = (WORD32)(ftemp);
242 qshift3 = ixheaacd_norm32(itemp);
243
244 for (k = 0; k < n_long / 4; k++) {
245 izir[k] =
246 (WORD32)((acelp_in[k] * (qfac1)) * (FLOAT32)((WORD64)1 << qshift3));
247 }
248 } else
249 izir = NULL;
250
251 if (last_lpc != NULL) {
252 ftemp = 0.0;
253 i_aq = int_aq;
254 for (k = 0; k < ORDER + 1; k++) {
255 if (ABS(last_lpc[k]) > ftemp) ftemp = ABS(last_lpc[k]);
256 }
257
258 itemp = (WORD32)(ftemp);
259 qshift2 = ixheaacd_norm32(itemp);
260
261 for (k = 0; k < ORDER + 1; k++) {
262 i_aq[k] = (WORD32)(last_lpc[k] * (FLOAT32)((WORD64)1 << qshift2));
263 }
264 } else
265 i_aq = NULL;
266
267 for (k = 0; k < lfac; k++) {
268 if (ixheaacd_abs32_sat(fac_data[k + 1]) > itemp)
269 itemp = ixheaacd_abs32_sat(fac_data[k + 1]);
270 }
271
272 qshift1 = ixheaacd_norm32(itemp);
273
274 for (k = 0; k < lfac; k++) {
275 fac_data[k + 1] =
276 (WORD32)(fac_data[k + 1] * (FLOAT32)((WORD64)1 << qshift1));
277 }
278
279 for (k = 0; k < lfac / 2; k++) {
280 x_in[k] = fac_data[2 * k + 1];
281 x_in[lfac / 2 + k] = fac_data[lfac - 2 * k];
282 }
283
284 err = ixheaacd_fr_alias_cnx_fix(x_in, n_long / 4, lfac, i_aq, izir,
285 fac_idata + 16, &qshift1, qshift2, qshift3,
286 &preshift, ptr_scratch);
287 if (err) return err;
288 preshift += 4;
289 *q_fac = (qshift1 - preshift);
290
291 if (acelp_in != NULL) {
292 for (k = 0; k < 2 * lfac; k++) {
293 fac_idata[k] =
294 ixheaacd_mul32_sh(fac_idata[k + 16], gain_fac, (WORD8)(scale));
295 }
296 }
297 return IA_NO_ERROR;
298 }
299
ixheaacd_fd_imdct_short(ia_usac_data_struct * usac_data,WORD32 i_ch,WORD32 * fac_data_out,offset_lengths * ixheaacd_drc_offset,WORD8 fac_q)300 static IA_ERRORCODE ixheaacd_fd_imdct_short(ia_usac_data_struct *usac_data,
301 WORD32 i_ch, WORD32 *fac_data_out,
302 offset_lengths *ixheaacd_drc_offset,
303 WORD8 fac_q) {
304 FLOAT32 qfac;
305 WORD32 overlap_data_buf[2 * N_LONG_LEN_MAX] = {0};
306 WORD32 *window_short, k, *window_short_prev_ptr;
307 WORD32 *overlap_data, *fp;
308
309 WORD32 *p_overlap_ibuffer = usac_data->overlap_data_ptr[i_ch];
310 WORD32 *p_in_ibuffer = usac_data->coef_fix[i_ch];
311 FLOAT32 *p_out_buffer = usac_data->time_sample_vector[i_ch];
312 WORD32 *p_out_ibuffer = usac_data->output_data_ptr[i_ch];
313 WORD32 *scratch_mem = usac_data->scratch_buffer;
314 WORD32 td_frame_prev = usac_data->td_frame_prev[i_ch];
315 WORD32 fac_apply = usac_data->fac_data_present[i_ch];
316 WORD8 shiftp, input_q, output_q, shift_olap = 14;
317 WORD32 max_shift;
318
319 WORD32 window_select = usac_data->window_shape[i_ch];
320 WORD32 window_select_prev = usac_data->window_shape_prev[i_ch];
321 ia_usac_lpd_decoder_handle st = usac_data->str_tddec[i_ch];
322 WORD32 err_code = 0;
323
324 max_shift =
325 ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long);
326 ixheaacd_normalize(p_in_ibuffer, max_shift, ixheaacd_drc_offset->n_long);
327 shiftp = max_shift + 6;
328 input_q = shiftp;
329
330 memcpy(overlap_data_buf, p_overlap_ibuffer,
331 sizeof(WORD32) * ixheaacd_drc_offset->n_long);
332 overlap_data = overlap_data_buf;
333
334 fp = overlap_data + ixheaacd_drc_offset->n_flat_ls;
335
336 for (k = 0; k < 8; k++) {
337 shiftp = input_q;
338 err_code = ixheaacd_acelp_imdct(
339 p_in_ibuffer + (k * ixheaacd_drc_offset->n_short),
340 2 * ixheaacd_drc_offset->n_short, &shiftp, scratch_mem);
341 if (err_code) return err_code;
342 }
343
344 max_shift =
345 ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long);
346 ixheaacd_normalize(p_in_ibuffer, max_shift - 1, ixheaacd_drc_offset->n_long);
347 shiftp += max_shift - 1;
348
349 err_code = ixheaacd_calc_window(&window_short, ixheaacd_drc_offset->n_short,
350 window_select);
351 if (err_code == -1) return err_code;
352 err_code =
353 ixheaacd_calc_window(&window_short_prev_ptr,
354 ixheaacd_drc_offset->n_trans_ls, window_select_prev);
355 if (err_code == -1) return err_code;
356
357 if (fac_apply)
358 ixheaacd_windowing_short1(p_in_ibuffer + ixheaacd_drc_offset->n_short / 2,
359 window_short_prev_ptr, fp, ixheaacd_drc_offset,
360 shiftp, shift_olap);
361
362 else
363 ixheaacd_windowing_short2(p_in_ibuffer + ixheaacd_drc_offset->n_short / 2,
364 window_short_prev_ptr, fp, ixheaacd_drc_offset,
365 shiftp, shift_olap);
366
367 output_q = ixheaacd_windowing_short3(
368 p_in_ibuffer, window_short + ixheaacd_drc_offset->n_short - 1,
369 fp + ixheaacd_drc_offset->n_short, ixheaacd_drc_offset->n_short, shiftp,
370 shift_olap);
371 p_in_ibuffer += ixheaacd_drc_offset->n_short;
372 fp += ixheaacd_drc_offset->n_short;
373 window_short_prev_ptr = window_short;
374
375 for (k = 1; k < 7; k++) {
376 output_q = ixheaacd_windowing_short4(
377 p_in_ibuffer, window_short_prev_ptr, fp,
378 window_short_prev_ptr + ixheaacd_drc_offset->n_short - 1,
379 ixheaacd_drc_offset->n_short, 1, shiftp, shift_olap, output_q);
380 p_in_ibuffer += ixheaacd_drc_offset->n_short;
381 fp += ixheaacd_drc_offset->n_short;
382 window_short_prev_ptr = window_short;
383 }
384
385 output_q = ixheaacd_windowing_short4(
386 p_in_ibuffer, window_short_prev_ptr, fp,
387 window_short_prev_ptr + ixheaacd_drc_offset->n_short - 1,
388 ixheaacd_drc_offset->n_short, 0, shiftp, shift_olap, output_q);
389 p_in_ibuffer += ixheaacd_drc_offset->n_short;
390 fp += ixheaacd_drc_offset->n_short;
391
392 if (fac_apply) {
393 ixheaacd_combine_fac(overlap_data + ixheaacd_drc_offset->n_flat_ls +
394 ixheaacd_drc_offset->lfac,
395 fac_data_out,
396 overlap_data + ixheaacd_drc_offset->n_flat_ls +
397 ixheaacd_drc_offset->lfac,
398 2 * ixheaacd_drc_offset->lfac, output_q, fac_q);
399 }
400 memset(overlap_data + 2 * ixheaacd_drc_offset->n_long -
401 ixheaacd_drc_offset->n_flat_ls,
402 0, sizeof(WORD32) * ixheaacd_drc_offset->n_flat_ls);
403 ixheaacd_scale_down(overlap_data, overlap_data,
404 ixheaacd_drc_offset->n_flat_ls, shift_olap, output_q);
405
406 ixheaacd_scale_down(p_overlap_ibuffer,
407 overlap_data + ixheaacd_drc_offset->n_long,
408 ixheaacd_drc_offset->n_long, output_q, shift_olap);
409 ixheaacd_scale_down(p_out_ibuffer, overlap_data, ixheaacd_drc_offset->n_long,
410 output_q, 15);
411
412 if (td_frame_prev) {
413 qfac = 1.0f / (FLOAT32)(1 << 15);
414
415 for (k = 0; k < ixheaacd_drc_offset->n_long; k++) {
416 p_out_buffer[k] = ((FLOAT32)p_out_ibuffer[k]) * qfac;
417 }
418 err_code = ixheaacd_lpd_bpf_fix(usac_data, 1, p_out_buffer, st);
419 if (err_code != 0) return err_code;
420
421 for (k = 0; k < ixheaacd_drc_offset->n_long; k++) {
422 p_out_ibuffer[k] = (WORD32)(p_out_buffer[k] * (1 << 15));
423 }
424 }
425
426 return 0;
427 }
428
ixheaacd_fd_imdct_long(ia_usac_data_struct * usac_data,WORD32 i_ch,WORD32 * fac_idata,offset_lengths * ixheaacd_drc_offset,WORD8 fac_q)429 static IA_ERRORCODE ixheaacd_fd_imdct_long(ia_usac_data_struct *usac_data,
430 WORD32 i_ch, WORD32 *fac_idata,
431 offset_lengths *ixheaacd_drc_offset,
432 WORD8 fac_q) {
433 FLOAT32 qfac;
434 WORD32 *window_long_prev, k, i, *window_short_prev_ptr;
435
436 WORD32 *p_in_ibuffer = usac_data->coef_fix[i_ch];
437 WORD32 *p_overlap_ibuffer = usac_data->overlap_data_ptr[i_ch];
438 WORD32 *p_out_ibuffer = usac_data->output_data_ptr[i_ch];
439 FLOAT32 *p_out_buffer = usac_data->time_sample_vector[i_ch];
440 WORD32 *scratch_mem = usac_data->scratch_buffer;
441 WORD32 n_long = usac_data->ccfl;
442 WORD32 td_frame_prev = usac_data->td_frame_prev[i_ch];
443 WORD32 fac_apply = usac_data->fac_data_present[i_ch];
444 WORD8 shiftp, output_q = 0, shift_olap = 14;
445 WORD32 max_shift;
446
447 WORD32 window_sequence = usac_data->window_sequence[i_ch];
448 WORD32 window_select_prev = usac_data->window_shape_prev[i_ch];
449 ia_usac_lpd_decoder_handle st = usac_data->str_tddec[i_ch];
450
451 WORD32 err_code = 0;
452
453 max_shift =
454 ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long);
455 ixheaacd_normalize(p_in_ibuffer, max_shift, ixheaacd_drc_offset->n_long);
456 shiftp = max_shift + 6;
457
458 err_code = ixheaacd_acelp_imdct(p_in_ibuffer, 2 * ixheaacd_drc_offset->n_long,
459 &shiftp, scratch_mem);
460 if (err_code) return err_code;
461
462 max_shift =
463 ixheaacd_calc_max_spectralline(p_in_ibuffer, ixheaacd_drc_offset->n_long);
464 ixheaacd_normalize(p_in_ibuffer, max_shift - 1, ixheaacd_drc_offset->n_long);
465 shiftp += max_shift - 1;
466
467 switch (window_sequence) {
468 case ONLY_LONG_SEQUENCE:
469 case LONG_START_SEQUENCE:
470 err_code = ixheaacd_calc_window(
471 &window_long_prev, ixheaacd_drc_offset->n_long, window_select_prev);
472 if (err_code == -1) return err_code;
473 output_q = ixheaacd_windowing_long1(
474 p_in_ibuffer + n_long / 2, p_overlap_ibuffer, window_long_prev,
475 window_long_prev + ixheaacd_drc_offset->n_long - 1, p_out_ibuffer,
476 ixheaacd_drc_offset->n_long, shiftp, shift_olap);
477 break;
478
479 case STOP_START_SEQUENCE:
480 case LONG_STOP_SEQUENCE:
481 err_code = ixheaacd_calc_window(&window_short_prev_ptr,
482 ixheaacd_drc_offset->n_trans_ls,
483 window_select_prev);
484 if (err_code == -1) return err_code;
485 if (fac_apply) {
486 output_q = ixheaacd_windowing_long2(
487 p_in_ibuffer + n_long / 2, window_short_prev_ptr, fac_idata,
488 p_overlap_ibuffer, p_out_ibuffer, ixheaacd_drc_offset, shiftp,
489 shift_olap, fac_q);
490 } else {
491 output_q = ixheaacd_windowing_long3(
492 p_in_ibuffer + n_long / 2, window_short_prev_ptr, p_overlap_ibuffer,
493 p_out_ibuffer,
494 window_short_prev_ptr + ixheaacd_drc_offset->n_trans_ls - 1,
495 ixheaacd_drc_offset, shiftp, shift_olap);
496 }
497 break;
498 }
499
500 for (i = 0; i < ixheaacd_drc_offset->n_long / 2; i++) {
501 p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 + i] =
502 ixheaacd_negate32_sat(p_in_ibuffer[i]) >> (shiftp - shift_olap);
503 p_overlap_ibuffer[ixheaacd_drc_offset->n_long / 2 - i - 1] =
504 ixheaacd_negate32_sat(p_in_ibuffer[i]) >> (shiftp - shift_olap);
505 }
506
507 ixheaacd_scale_down_adj(p_out_ibuffer, p_out_ibuffer,
508 ixheaacd_drc_offset->n_long, output_q, 15);
509
510 if (td_frame_prev) {
511 qfac = 1.0f / (FLOAT32)(1 << 15);
512
513 for (k = 0; k < ixheaacd_drc_offset->n_long; k++) {
514 p_out_buffer[k] = ((FLOAT32)p_out_ibuffer[k]) * qfac;
515 }
516 err_code = ixheaacd_lpd_bpf_fix(usac_data, 0, p_out_buffer, st);
517 if (err_code != 0) return err_code;
518
519 for (k = 0; k < ixheaacd_drc_offset->n_long; k++) {
520 p_out_ibuffer[k] = (WORD32)(p_out_buffer[k] * (1 << 15));
521 }
522 }
523
524 return 0;
525 }
526
ixheaacd_fd_frm_dec(ia_usac_data_struct * usac_data,WORD32 i_ch)527 WORD32 ixheaacd_fd_frm_dec(ia_usac_data_struct *usac_data, WORD32 i_ch) {
528 WORD32 fac_idata[2 * FAC_LENGTH + 16];
529 offset_lengths ixheaacd_drc_offset;
530 WORD8 fac_q = 0;
531 WORD32 td_frame_prev = usac_data->td_frame_prev[i_ch];
532 WORD32 fac_apply = usac_data->fac_data_present[i_ch];
533 WORD32 window_sequence = usac_data->window_sequence[i_ch];
534 IA_ERRORCODE err = IA_NO_ERROR;
535 ixheaacd_drc_offset.n_long = usac_data->ccfl;
536 ixheaacd_drc_offset.n_short = ixheaacd_drc_offset.n_long >> 3;
537
538 memset(fac_idata, 0, sizeof(fac_idata));
539
540 if (td_frame_prev) {
541 if (window_sequence == EIGHT_SHORT_SEQUENCE) {
542 ixheaacd_drc_offset.lfac = ixheaacd_drc_offset.n_long >> 4;
543 } else {
544 ixheaacd_drc_offset.lfac = ixheaacd_drc_offset.n_long >> 3;
545 }
546 ixheaacd_drc_offset.n_flat_ls =
547 (ixheaacd_drc_offset.n_long - (ixheaacd_drc_offset.lfac) * 2) >> 1;
548
549 ixheaacd_drc_offset.n_trans_ls = (ixheaacd_drc_offset.lfac) << 1;
550 } else {
551 ixheaacd_drc_offset.lfac = FAC_LENGTH;
552 ixheaacd_drc_offset.n_flat_ls =
553 (ixheaacd_drc_offset.n_long - ixheaacd_drc_offset.n_short) >> 1;
554 ixheaacd_drc_offset.n_trans_ls = ixheaacd_drc_offset.n_short;
555 }
556
557 if (fac_apply) {
558 err = ixheaacd_cal_fac_data(usac_data, i_ch, ixheaacd_drc_offset.n_long,
559 ixheaacd_drc_offset.lfac, fac_idata, &fac_q);
560 if (err) return err;
561 }
562
563 if (window_sequence != EIGHT_SHORT_SEQUENCE) {
564 err = ixheaacd_fd_imdct_long(usac_data, i_ch, fac_idata,
565 &ixheaacd_drc_offset, fac_q);
566 if (err) return err;
567 } else {
568 err = ixheaacd_fd_imdct_short(usac_data, i_ch, fac_idata,
569 &ixheaacd_drc_offset, fac_q);
570 if (err) return err;
571 }
572
573 return err;
574 }
575