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