Coverage Report

Created: 2025-07-12 06:52

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