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