Coverage Report

Created: 2025-07-11 06:38

/src/libxaac/decoder/ixheaacd_hbe_dft_trans.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 <stdlib.h>
22
#include <string.h>
23
24
#include "ixheaac_type_def.h"
25
26
#include "ixheaacd_bitbuffer.h"
27
28
#include "ixheaacd_interface.h"
29
30
#include "ixheaacd_tns_usac.h"
31
#include "ixheaacd_cnst.h"
32
33
#include "ixheaacd_acelp_info.h"
34
35
#include "ixheaacd_sbrdecsettings.h"
36
#include "ixheaacd_info.h"
37
#include "ixheaacd_sbr_common.h"
38
#include "ixheaacd_drc_data_struct.h"
39
#include "ixheaacd_drc_dec.h"
40
#include "ixheaacd_sbrdecoder.h"
41
#include "ixheaacd_mps_polyphase.h"
42
#include "ixheaac_sbr_const.h"
43
44
#include "ixheaacd_env_extr_part.h"
45
#include "ixheaacd_sbr_rom.h"
46
#include "ixheaacd_common_rom.h"
47
#include "ixheaacd_hybrid.h"
48
#include "ixheaacd_sbr_scale.h"
49
#include "ixheaacd_ps_dec.h"
50
#include "ixheaacd_freq_sca.h"
51
#include "ixheaacd_lpp_tran.h"
52
#include "ixheaacd_bitbuffer.h"
53
#include "ixheaacd_env_extr.h"
54
#include "ixheaacd_qmf_dec.h"
55
#include "ixheaacd_env_calc.h"
56
#include "ixheaacd_pvc_dec.h"
57
58
#include "ixheaacd_sbr_dec.h"
59
#include "ixheaac_error_standards.h"
60
#include "ixheaacd_sbrqmftrans.h"
61
#include "ixheaacd_qmf_poly.h"
62
63
#include "ixheaac_constants.h"
64
#include "ixheaac_basic_ops32.h"
65
#include "ixheaac_basic_op.h"
66
67
#include "ixheaac_esbr_rom.h"
68
69
0
static FLOAT32 *ixheaacd_map_prot_filter(WORD32 filt_length) {
70
0
  switch (filt_length) {
71
0
    case 4:
72
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0];
73
0
      break;
74
0
    case 8:
75
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[40];
76
0
      break;
77
0
    case 12:
78
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[120];
79
0
      break;
80
0
    case 16:
81
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[240];
82
0
      break;
83
0
    case 20:
84
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[400];
85
0
      break;
86
0
    case 24:
87
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[600];
88
0
      break;
89
0
    case 28:
90
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[0];
91
0
      break;
92
0
    case 32:
93
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[840];
94
0
      break;
95
0
    case 36:
96
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[280];
97
0
      break;
98
0
    case 40:
99
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1160];
100
0
      break;
101
0
    case 44:
102
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1560];
103
0
      break;
104
0
    default:
105
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0];
106
0
  }
107
0
}
108
109
static VOID ixheaacd_create_dft_hbe_window(FLOAT32 *win, WORD32 x_over_bin1,
110
                                           WORD32 x_over_bin2,
111
0
                                           WORD32 ts, WORD32 size) {
112
0
  const FLOAT32 *ptr_freq_domain_win = NULL;
113
0
  WORD32 n;
114
0
  if (ts == 12) {
115
0
    ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_12[0];
116
0
  } else {
117
0
    ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_18[0];
118
0
  }
119
0
  for (n = 0; n < (x_over_bin1 - ts / 2); n++) {
120
0
    win[n] = 0;
121
0
  }
122
123
0
  for (n = (x_over_bin1 - ts / 2); n <= (x_over_bin1 + ts / 2); n++) {
124
0
    win[n] = (FLOAT32)ptr_freq_domain_win[n - (x_over_bin1 - ts / 2)];
125
0
  }
126
127
0
  for (n = (x_over_bin1 + ts / 2 + 1); n < (x_over_bin2 - ts / 2); n++) {
128
0
    win[n] = (FLOAT32)1.0f;
129
0
  }
130
131
0
  for (n = (x_over_bin2 - ts / 2); n <= (x_over_bin2 + ts / 2); n++) {
132
0
    win[n] = (FLOAT32)1.0f - ptr_freq_domain_win[n - (x_over_bin2 - ts / 2)];
133
0
  }
134
135
0
  for (n = (x_over_bin2 + ts / 2 + 1); n < size; n++) {
136
0
    win[n] = 0.0f;
137
0
  }
138
0
}
139
140
0
static WORD32 ixheaacd_calc_anal_synth_window(WORD32 fft_size, FLOAT32 *ptr_window) {
141
0
  FLOAT32 sin_pi_2_N = 0.0f;
142
0
  FLOAT32 cos_pi_2_N = 0.0f;
143
0
  FLOAT32 *ptr_sin_pi_n_by_N = NULL;
144
0
  WORD32 hop_stride = 1;
145
0
  WORD32 i, j;
146
0
  WORD32 l_fft_stride = 512;
147
0
  switch (fft_size) {
148
0
    case 64:
149
0
      hop_stride = 16;
150
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
151
0
      sin_pi_2_N = ptr_sin_pi_n_by_N[hop_stride >> 1];
152
0
      cos_pi_2_N = ptr_sin_pi_n_by_N[512 + (hop_stride >> 1)];
153
0
      l_fft_stride = 512;
154
0
      break;
155
0
    case 128:
156
0
      hop_stride = 8;
157
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
158
0
      sin_pi_2_N = ptr_sin_pi_n_by_N[hop_stride >> 1];
159
0
      cos_pi_2_N = ptr_sin_pi_n_by_N[512 + (hop_stride >> 1)];
160
0
      l_fft_stride = 512;
161
0
      break;
162
0
    case 256:
163
0
      hop_stride = 4;
164
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
165
0
      sin_pi_2_N = ptr_sin_pi_n_by_N[hop_stride >> 1];
166
0
      cos_pi_2_N = ptr_sin_pi_n_by_N[512 + (hop_stride >> 1)];
167
0
      l_fft_stride = 512;
168
0
      break;
169
0
    case 512:
170
0
      hop_stride = 2;
171
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
172
0
      sin_pi_2_N = ptr_sin_pi_n_by_N[1];
173
0
      cos_pi_2_N = ptr_sin_pi_n_by_N[512 + 1];
174
0
      l_fft_stride = 512;
175
0
      break;
176
0
    case 1024:
177
0
      hop_stride = 1;
178
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
179
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[0];
180
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[1];
181
0
      l_fft_stride = 512;
182
0
      break;
183
0
    case 192:
184
0
      hop_stride = 4;
185
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
186
0
      sin_pi_2_N = ptr_sin_pi_n_by_N[hop_stride >> 1];
187
0
      cos_pi_2_N = ptr_sin_pi_n_by_N[384 + (hop_stride >> 1)];
188
0
      l_fft_stride = 384;
189
0
      break;
190
0
    case 384:
191
0
      hop_stride = 2;
192
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
193
0
      sin_pi_2_N = ptr_sin_pi_n_by_N[1];
194
0
      cos_pi_2_N = ptr_sin_pi_n_by_N[384 + 1];
195
0
      l_fft_stride = 384;
196
0
      break;
197
0
    case 768:
198
0
      hop_stride = 1;
199
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
200
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[8];
201
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[9];
202
0
      l_fft_stride = 384;
203
0
      break;
204
0
    case 320:
205
0
      hop_stride = 3;
206
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_960[0];
207
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[16];
208
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[17];
209
0
      l_fft_stride = 480;
210
0
      break;
211
0
    case 960:
212
0
      hop_stride = 1;
213
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_960[0];
214
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[2];
215
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[3];
216
0
      l_fft_stride = 480;
217
0
      break;
218
0
    case 448:
219
0
      hop_stride = 2;
220
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_896[0];
221
0
      sin_pi_2_N = ptr_sin_pi_n_by_N[1];
222
0
      cos_pi_2_N = ptr_sin_pi_n_by_N[448 + 1];
223
0
      l_fft_stride = 448;
224
0
      break;
225
0
    case 896:
226
0
      hop_stride = 1;
227
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_896[0];
228
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[4];
229
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[5];
230
0
      l_fft_stride = 448;
231
0
      break;
232
0
    case 576:
233
0
      hop_stride = 1;
234
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_576[0];
235
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[14];
236
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[15];
237
0
      l_fft_stride = 288;
238
0
      break;
239
0
    case 640:
240
0
      hop_stride = 1;
241
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_640[0];
242
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[12];
243
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[13];
244
0
      l_fft_stride = 320;
245
0
      break;
246
0
    case 704:
247
0
      hop_stride = 1;
248
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_704[0];
249
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[10];
250
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[11];
251
0
      l_fft_stride = 352;
252
0
      break;
253
0
    case 832:
254
0
      hop_stride = 1;
255
0
      ptr_sin_pi_n_by_N = (FLOAT32 *)&ixheaac_sine_pi_n_by_832[0];
256
0
      sin_pi_2_N = ixheaac_sine_pi_by_2_N[6];
257
0
      cos_pi_2_N = ixheaac_sine_pi_by_2_N[7];
258
0
      l_fft_stride = 416;
259
0
      break;
260
0
    default:
261
0
      return -1;
262
0
  }
263
264
0
  for (i = 0, j = 0; j < (fft_size >> 1); i += hop_stride, j++) {
265
0
    FLOAT32 cos_val = ptr_sin_pi_n_by_N[i + l_fft_stride];
266
0
    FLOAT32 sin_val = ptr_sin_pi_n_by_N[i];
267
0
    ptr_window[j] = cos_val * sin_pi_2_N + sin_val * cos_pi_2_N;
268
0
  }
269
270
0
  for (; j < fft_size; j++, i += hop_stride) {
271
0
    FLOAT32 cos_val = ptr_sin_pi_n_by_N[i - l_fft_stride];
272
0
    FLOAT32 sin_val = ptr_sin_pi_n_by_N[i];
273
0
    ptr_window[j] = sin_val * cos_pi_2_N - cos_val * sin_pi_2_N;
274
0
  }
275
0
  return 0;
276
0
}
277
278
WORD32 ixheaacd_dft_hbe_data_reinit(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer,
279
0
                                    WORD16 *p_freq_band_tab[2], WORD16 *p_num_sfb) {
280
0
  WORD32 sfb;
281
0
  WORD32 patch;
282
0
  WORD32 i;
283
0
  WORD32 temp_start;
284
0
  FLOAT32 fb_ratio;
285
0
  WORD32 stop_patch;
286
0
  WORD32 in_hop_size_divisor = 8;
287
0
  static const WORD32 trans_samp[2] = {12, 18};
288
0
  WORD32 err = 0;
289
290
0
  ptr_hbe_txposer->start_band = p_freq_band_tab[LOW][0];
291
0
  ptr_hbe_txposer->end_band = p_freq_band_tab[LOW][p_num_sfb[LOW]];
292
0
  ptr_hbe_txposer->esbr_hq = 1;
293
294
0
  ptr_hbe_txposer->synth_size = 4 * ((ptr_hbe_txposer->start_band + 4) / 8 + 1);
295
0
  ptr_hbe_txposer->k_start = ixheaac_start_subband2kL_tbl[ptr_hbe_txposer->start_band];
296
297
0
  fb_ratio = ptr_hbe_txposer->synth_size / 32.0f;
298
299
0
  ptr_hbe_txposer->ana_fft_size[0] = (WORD32)(fb_ratio * ptr_hbe_txposer->fft_size[0]);
300
0
  ptr_hbe_txposer->ana_fft_size[1] = (WORD32)(fb_ratio * ptr_hbe_txposer->fft_size[1]);
301
302
0
  ptr_hbe_txposer->in_hop_size = ptr_hbe_txposer->ana_fft_size[0] / in_hop_size_divisor;
303
304
0
  ptr_hbe_txposer->synth_window = (FLOAT32 *)&ptr_hbe_txposer->synthesis_window_buf[0];
305
0
  ptr_hbe_txposer->anal_window = (FLOAT32 *)&ptr_hbe_txposer->analysis_window_buf[0];
306
307
0
  err = ixheaacd_calc_anal_synth_window(ptr_hbe_txposer->ana_fft_size[0],
308
0
                                        ptr_hbe_txposer->anal_window);
309
0
  if (err) {
310
0
    return err;
311
0
  }
312
313
0
  memset(ptr_hbe_txposer->synth_buf, 0, 1280 * sizeof(ptr_hbe_txposer->synth_buf[0]));
314
315
0
  ptr_hbe_txposer->synth_wind_coeff = ixheaacd_map_prot_filter(ptr_hbe_txposer->synth_size);
316
317
0
  temp_start = 2 * ((ptr_hbe_txposer->start_band - 1) / 2);
318
0
  ptr_hbe_txposer->analy_size =
319
0
      4 * ((min(64, ptr_hbe_txposer->end_band + 1) - temp_start - 1) / 4 +
320
0
           1);
321
0
  ptr_hbe_txposer->a_start = temp_start - max(0, temp_start + ptr_hbe_txposer->analy_size - 64);
322
323
0
  fb_ratio = ptr_hbe_txposer->analy_size / 64.0f;
324
325
0
  ptr_hbe_txposer->syn_fft_size[0] = (WORD32)(fb_ratio * ptr_hbe_txposer->fft_size[0]);
326
0
  ptr_hbe_txposer->syn_fft_size[1] = (WORD32)(fb_ratio * ptr_hbe_txposer->fft_size[1]);
327
328
0
  ptr_hbe_txposer->out_hop_size = 2 * ptr_hbe_txposer->syn_fft_size[0] / in_hop_size_divisor;
329
330
0
  err = ixheaacd_calc_anal_synth_window(ptr_hbe_txposer->syn_fft_size[0],
331
0
                                        ptr_hbe_txposer->synth_window);
332
0
  if (err) {
333
0
    return err;
334
0
  }
335
336
0
  ptr_hbe_txposer->analy_wind_coeff = ixheaacd_map_prot_filter(ptr_hbe_txposer->analy_size);
337
338
0
  memset(&ptr_hbe_txposer->x_over_qmf[0], 0, sizeof(ptr_hbe_txposer->x_over_qmf));
339
0
  for (i = 0; i < MAX_STRETCH; i++) {
340
0
    memset(&ptr_hbe_txposer->x_over_bin[i][0], 0,
341
0
           2 * sizeof(ptr_hbe_txposer->x_over_bin[i][0]));
342
0
  }
343
0
  sfb = 0;
344
0
  stop_patch = MAX_STRETCH;
345
346
0
  switch (ptr_hbe_txposer->synth_size) {
347
0
    case 4:
348
0
      ptr_hbe_txposer->synth_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4;
349
0
      ptr_hbe_txposer->ixheaacd_real_synth_fft = &ixheaac_real_synth_fft_p2;
350
0
      break;
351
0
    case 8:
352
0
      ptr_hbe_txposer->synth_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_8;
353
0
      ptr_hbe_txposer->ixheaacd_real_synth_fft = &ixheaac_real_synth_fft_p2;
354
0
      break;
355
0
    case 12:
356
0
      ptr_hbe_txposer->synth_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_12;
357
0
      ptr_hbe_txposer->ixheaacd_real_synth_fft = &ixheaac_real_synth_fft_p3;
358
0
      break;
359
0
    case 16:
360
0
      ptr_hbe_txposer->synth_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_16;
361
0
      ptr_hbe_txposer->ixheaacd_real_synth_fft = &ixheaac_real_synth_fft_p2;
362
0
      break;
363
0
    case 20:
364
0
      ptr_hbe_txposer->synth_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20;
365
0
      break;
366
0
    case 28:
367
0
      ptr_hbe_txposer->synth_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20;
368
0
      break;
369
0
    default:
370
0
      ptr_hbe_txposer->synth_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4;
371
0
      ptr_hbe_txposer->ixheaacd_real_synth_fft = &ixheaac_real_synth_fft_p2;
372
0
  }
373
374
0
  {
375
0
    WORD32 l, k, L = ptr_hbe_txposer->analy_size;
376
0
    for (k = 0; k < L; k++) {
377
0
      for (l = 0; l < 2 * L; l++) {
378
0
        ptr_hbe_txposer->str_dft_hbe_anal_coeff.real[k][l] =
379
0
            (FLOAT32)cos(PI / (2 * L) *
380
0
                         ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 *
381
0
                          ptr_hbe_txposer->a_start));
382
0
        ptr_hbe_txposer->str_dft_hbe_anal_coeff.imag[k][l] =
383
0
            (FLOAT32)sin(PI / (2 * L) *
384
0
                         ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 *
385
0
                          ptr_hbe_txposer->a_start));
386
0
      }
387
0
    }
388
0
  }
389
390
0
  for (patch = 1; patch <= stop_patch; patch++) {
391
0
    while (sfb <= p_num_sfb[LOW] &&
392
0
           p_freq_band_tab[LOW][sfb] <= patch * ptr_hbe_txposer->start_band)
393
0
      sfb++;
394
0
    if (sfb <= p_num_sfb[LOW]) {
395
0
      if ((patch * ptr_hbe_txposer->start_band - p_freq_band_tab[LOW][sfb - 1]) <= 3) {
396
0
        ptr_hbe_txposer->x_over_qmf[patch - 1] = p_freq_band_tab[LOW][sfb - 1];
397
0
        if (patch <= MAX_STRETCH) {
398
0
          ptr_hbe_txposer->x_over_bin[patch - 1][0] = (WORD32)(
399
0
              ptr_hbe_txposer->fft_size[0] * p_freq_band_tab[LOW][sfb - 1] / 128 + 0.5);
400
0
          ptr_hbe_txposer->x_over_bin[patch - 1][1] = (WORD32)(
401
0
              ptr_hbe_txposer->fft_size[1] * p_freq_band_tab[LOW][sfb - 1] / 128 + 0.5);
402
0
        }
403
0
      } else {
404
0
        WORD32 sfb = 0;
405
0
        while (sfb <= p_num_sfb[HIGH] &&
406
0
               p_freq_band_tab[HIGH][sfb] <= patch * ptr_hbe_txposer->start_band)
407
0
          sfb++;
408
0
        ptr_hbe_txposer->x_over_qmf[patch - 1] = p_freq_band_tab[HIGH][sfb - 1];
409
0
        if (patch <= MAX_STRETCH) {
410
0
          ptr_hbe_txposer->x_over_bin[patch - 1][0] = (WORD32)(
411
0
              ptr_hbe_txposer->fft_size[0] * p_freq_band_tab[HIGH][sfb - 1] / 128 + 0.5);
412
0
          ptr_hbe_txposer->x_over_bin[patch - 1][1] = (WORD32)(
413
0
              ptr_hbe_txposer->fft_size[1] * p_freq_band_tab[HIGH][sfb - 1] / 128 + 0.5);
414
0
        }
415
0
      }
416
0
    } else {
417
0
      ptr_hbe_txposer->x_over_qmf[patch - 1] = ptr_hbe_txposer->end_band;
418
0
      if (patch <= MAX_STRETCH) {
419
0
        ptr_hbe_txposer->x_over_bin[patch - 1][0] =
420
0
            (WORD32)(ptr_hbe_txposer->fft_size[0] * ptr_hbe_txposer->end_band / 128 + 0.5);
421
0
        ptr_hbe_txposer->x_over_bin[patch - 1][1] =
422
0
            (WORD32)(ptr_hbe_txposer->fft_size[1] * ptr_hbe_txposer->end_band / 128 + 0.5);
423
0
      }
424
0
      ptr_hbe_txposer->max_stretch = min(patch, MAX_STRETCH);
425
0
      break;
426
0
    }
427
0
  }
428
429
0
  for (patch = 0; patch < ptr_hbe_txposer->max_stretch - 1; patch++) {
430
0
    for (i = 0; i < 2; i++) {
431
0
      ixheaacd_create_dft_hbe_window(ptr_hbe_txposer->fd_win_buf[patch][i],
432
0
                                     ptr_hbe_txposer->x_over_bin[patch][i],
433
0
                                     ptr_hbe_txposer->x_over_bin[patch + 1][i], trans_samp[i],
434
0
                                     ptr_hbe_txposer->fft_size[i]);
435
0
    }
436
0
  }
437
0
  return 0;
438
0
}
439
440
static VOID ixheaacd_dft_hbe_apply_win(const FLOAT32 *inp1, const FLOAT32 *inp2, FLOAT32 *out,
441
0
                                       WORD32 n) {
442
0
  WORD32 i;
443
0
  for (i = 0; i < n; i++) {
444
0
    out[i] = inp1[i] * inp2[i];
445
0
  }
446
0
}
447
448
0
VOID ixheaacd_dft_hbe_fft_memmove(FLOAT32 *ptr_spectrum, WORD32 size) {
449
0
  WORD32 n;
450
451
0
  for (n = 0; n < size / 2; n++) {
452
0
    FLOAT32 tmp = ptr_spectrum[n];
453
0
    ptr_spectrum[n] = ptr_spectrum[n + size / 2];
454
0
    ptr_spectrum[n + size / 2] = tmp;
455
0
  }
456
0
}
457
458
0
VOID ixheaacd_karth2polar(FLOAT32 *spectrum, FLOAT32 *mag, FLOAT32 *phase, WORD32 fft_size) {
459
0
  WORD32 n;
460
461
0
  for (n = 1; n < fft_size / 2; n++) {
462
0
    phase[n] = (FLOAT32)atan2(spectrum[2 * n + 1], spectrum[2 * n]);
463
0
    mag[n] = (FLOAT32)sqrt(spectrum[2 * n] * spectrum[2 * n] +
464
0
                           spectrum[2 * n + 1] * spectrum[2 * n + 1]);
465
0
  }
466
467
0
  if (spectrum[0] < 0) {
468
0
    phase[0] = (FLOAT32)acos(-1);
469
0
    mag[0] = -spectrum[0];
470
0
  } else {
471
0
    phase[0] = 0;
472
0
    mag[0] = spectrum[0];
473
0
  }
474
475
0
  if (spectrum[1] < 0) {
476
0
    phase[fft_size / 2] = (FLOAT32)acos(-1);
477
0
    mag[fft_size / 2] = -spectrum[1];
478
0
  } else {
479
0
    phase[fft_size / 2] = 0;
480
0
    mag[fft_size / 2] = spectrum[1];
481
0
  }
482
0
}
483
484
0
VOID ixheaacd_hbe_fft_table(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer) {
485
0
  WORD32 oversampling_flag = ptr_hbe_txposer->oversampling_flag;
486
0
  WORD32 ana_fft_size = ptr_hbe_txposer->ana_fft_size[oversampling_flag];
487
0
  WORD32 syn_fft_size = ptr_hbe_txposer->syn_fft_size[oversampling_flag];
488
489
0
  switch (ana_fft_size) {
490
0
    case 576:
491
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576;
492
0
      break;
493
0
    case 384:
494
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_384;
495
0
      break;
496
0
    case 512:
497
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
498
0
      break;
499
0
    case 768:
500
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
501
0
      break;
502
0
    default:
503
0
      break;
504
0
  }
505
506
0
  switch (syn_fft_size) {
507
0
    case 448:
508
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_448;
509
0
      break;
510
0
    case 512:
511
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
512
0
      break;
513
0
    case 768:
514
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
515
0
      break;
516
0
    case 672:
517
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_672;
518
0
      break;
519
0
    default:
520
0
      break;
521
0
  }
522
0
}
523
524
0
IA_ERRORCODE ixheaacd_hbe_fft_map(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer) {
525
0
  WORD32 oversampling_flag = ptr_hbe_txposer->oversampling_flag;
526
0
  WORD32 ana_fft_size = ptr_hbe_txposer->ana_fft_size[oversampling_flag];
527
0
  WORD32 syn_fft_size = ptr_hbe_txposer->syn_fft_size[oversampling_flag];
528
529
0
  switch (ana_fft_size) {
530
0
    case 576:
531
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576;
532
0
      ptr_hbe_txposer->ixheaacd_hbe_anal_fft = &ixheaacd_hbe_apply_fft_288;
533
0
      break;
534
0
    case 384:
535
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_384;
536
0
      ptr_hbe_txposer->ixheaacd_hbe_anal_fft = &ixheaacd_hbe_apply_cfftn_gen;
537
0
      break;
538
0
    case 512:
539
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
540
0
      ptr_hbe_txposer->ixheaacd_hbe_anal_fft = &ixheaacd_hbe_apply_cfftn;
541
0
      break;
542
0
    case 768:
543
0
      ptr_hbe_txposer->ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
544
0
      ptr_hbe_txposer->ixheaacd_hbe_anal_fft = &ixheaacd_hbe_apply_cfftn_gen;
545
0
      break;
546
0
    default:
547
0
      return IA_FATAL_ERROR;
548
0
      break;
549
0
  }
550
551
0
  switch (syn_fft_size) {
552
0
    case 448:
553
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_448;
554
0
      ptr_hbe_txposer->ixheaacd_hbe_synth_ifft = &ixheaacd_hbe_apply_ifft_224;
555
0
      break;
556
0
    case 512:
557
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
558
0
      ptr_hbe_txposer->ixheaacd_hbe_synth_ifft = &ixheaacd_hbe_apply_cfftn;
559
0
      break;
560
0
    case 768:
561
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
562
0
      ptr_hbe_txposer->ixheaacd_hbe_synth_ifft = &ixheaacd_hbe_apply_cfftn_gen;
563
0
      break;
564
0
    case 672:
565
0
      ptr_hbe_txposer->syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_672;
566
0
      ptr_hbe_txposer->ixheaacd_hbe_synth_ifft = &ixheaacd_hbe_apply_ifft_336;
567
0
      break;
568
0
    default:
569
0
      return IA_FATAL_ERROR;
570
0
      break;
571
0
  }
572
573
0
  return IA_NO_ERROR;
574
0
}
575
576
VOID ixheaacd_dft_hbe_apply_polar_t2(
577
    WORD32 trans_fac, ia_esbr_hbe_txposer_struct *ptr_hbe_txposer,
578
0
    WORD32 pitch_in_bins, WORD out_transform_size) {
579
0
  WORD32 tr;
580
0
  WORD32 ti;
581
0
  WORD32 m_tr;
582
0
  WORD32 p, i;
583
0
  FLOAT32 mag_t;
584
0
  FLOAT32 phase_t;
585
0
  FLOAT32 m_val;
586
0
  FLOAT32(*fd_win_buf)[3][3][1536] = &ptr_hbe_txposer->fd_win_buf;
587
0
  FLOAT32 *phase = ptr_hbe_txposer->phase;
588
0
  WORD32 oversampling_flag = ptr_hbe_txposer->oversampling_flag;
589
0
  WORD32 fft_size = ptr_hbe_txposer->fft_size[oversampling_flag];
590
0
  FLOAT32 *ptr_spectrum_tx = ptr_hbe_txposer->ptr_spectrum_tx;
591
0
  FLOAT32 *mag = ptr_hbe_txposer->mag;
592
0
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
593
0
  p = (WORD32)p_flt;
594
0
  FLOAT32 q_thr = 4.0f;
595
0
  m_tr = 0;
596
597
0
  for (i = 0; i <= out_transform_size; i++) {
598
0
    WORD32 utk = i;
599
600
0
    mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] * mag[utk];
601
602
0
    phase_t = trans_fac * phase[utk];
603
604
0
    if (phase_t == 0.0) {
605
0
      ptr_spectrum_tx[2 * i] += mag_t;
606
0
    } else {
607
0
      ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
608
0
      ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
609
0
    }
610
0
    if (p > 0) {
611
0
      m_val = 0;
612
0
      for (tr = 1; tr < trans_fac; tr++) {
613
0
        FLOAT32 temp;
614
0
        ti = (WORD32)((2.0f * i - tr * p_flt) / trans_fac + 0.5f);
615
0
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
616
0
        temp = min(mag[ti], mag[ti + p]);
617
0
        if (temp > m_val) {
618
0
          m_val = temp;
619
0
          m_tr = tr;
620
0
          utk = ti;
621
0
        }
622
0
      }
623
624
0
      if (m_val > q_thr * mag[2 * i / trans_fac]) {
625
0
        mag_t = (FLOAT32)((*fd_win_buf)[trans_fac - 2][oversampling_flag][i] *
626
0
                         sqrt(mag[utk]) * sqrt(mag[utk + p]));
627
0
        phase_t = (trans_fac - m_tr) * phase[utk] + m_tr * phase[utk + p];
628
0
        ptr_spectrum_tx[2 * i] += (FLOAT32)(mag_t * cos(phase_t));
629
0
        ptr_spectrum_tx[2 * i + 1] += (FLOAT32)(mag_t * sin(phase_t));
630
0
      }
631
0
    }
632
0
  }
633
0
}
634
635
VOID ixheaacd_dft_hbe_apply_polar_t3(
636
    WORD32 trans_fac, ia_esbr_hbe_txposer_struct *ptr_hbe_txposer,
637
0
    WORD32 pitch_in_bins, WORD out_transform_size) {
638
0
  WORD32 tr;
639
0
  WORD32 ti;
640
0
  WORD32 m_tr = 0;
641
0
  WORD32 p, i;
642
0
  FLOAT32 mag_t = 0;
643
0
  FLOAT32 phase_t;
644
0
  FLOAT32 m_val;
645
0
  FLOAT32(*fd_win_buf)[3][3][1536] = &ptr_hbe_txposer->fd_win_buf;
646
0
  FLOAT32 *phase = ptr_hbe_txposer->phase;
647
0
  WORD32 oversampling_flag = ptr_hbe_txposer->oversampling_flag;
648
0
  WORD32 fft_size = ptr_hbe_txposer->fft_size[oversampling_flag];
649
0
  FLOAT32 *ptr_spectrum_tx = ptr_hbe_txposer->ptr_spectrum_tx;
650
0
  FLOAT32 *mag = ptr_hbe_txposer->mag;
651
0
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
652
0
  p = (WORD32)p_flt;
653
0
  FLOAT32 q_thr = 4.0f;
654
655
0
  for (i = 0; i <= out_transform_size; i++) {
656
0
    WORD32 utk = 2 * i / trans_fac;
657
0
    FLOAT32 ptk = (2.0f * i / trans_fac) - utk;
658
0
    FLOAT32 k;
659
660
0
    if (i % 3 == 0) {
661
0
      mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] * mag[utk];
662
0
    } else if (i % 3 == 1) {
663
0
      k = (FLOAT32)cbrt(mag[utk]);
664
0
      mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] * k *
665
0
             (FLOAT32)pow(mag[utk + 1], ptk);
666
0
    } else if (i % 3 == 2) {
667
0
      k = (FLOAT32)cbrt(mag[utk + 1]);
668
0
      mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] *
669
0
             (FLOAT32)pow(mag[utk], 1.0 - ptk) * k;
670
0
    }
671
672
0
    phase_t = trans_fac * ((1 - ptk) * phase[utk] + ptk * phase[utk + 1]);
673
674
0
    ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
675
0
    ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
676
677
0
    if (p > 0) {
678
0
      m_val = 0;
679
0
      for (tr = 1; tr < trans_fac; tr++) {
680
0
        FLOAT32 temp;
681
0
        ti = (WORD32)((2.0f * i - tr * p_flt) / trans_fac + 0.5f);
682
0
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
683
0
        temp = min(mag[ti], mag[ti + p]);
684
0
        if (temp > m_val) {
685
0
          m_val = temp;
686
0
          m_tr = tr;
687
0
          utk = ti;
688
0
        }
689
0
      }
690
691
0
      if (m_val > q_thr * mag[2 * i / trans_fac]) {
692
0
        FLOAT32 r = (FLOAT32)m_tr / trans_fac;
693
0
        if (m_tr == 1) {
694
0
          k = (FLOAT32)(cbrt((FLOAT32)mag[utk + p]));
695
0
          mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] *
696
0
                 (FLOAT32)pow(mag[utk], 1.0 - r) * k;
697
0
          phase_t = (trans_fac - m_tr) * phase[utk] + phase[utk + p];
698
0
        } else if (m_tr == 2) {
699
0
          k = (FLOAT32)(cbrt((FLOAT32)mag[utk]));
700
0
          mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] * k *
701
0
                 (FLOAT32)pow(mag[utk + p], r);
702
0
          phase_t = phase[utk] + m_tr * phase[utk + p];
703
0
        }
704
705
0
        ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
706
0
        ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
707
0
      }
708
0
    }
709
0
  }
710
0
}
711
712
VOID ixheaacd_dft_hbe_apply_polar_t(
713
    WORD32 trans_fac, ia_esbr_hbe_txposer_struct *ptr_hbe_txposer,
714
0
    WORD32 pitch_in_bins, WORD out_transform_size) {
715
0
  WORD32 tr;
716
0
  WORD32 ti;
717
0
  WORD32 m_tr;
718
0
  WORD32 p, i;
719
0
  FLOAT32 mag_t;
720
0
  FLOAT32 phase_t;
721
0
  FLOAT32 m_val;
722
0
  FLOAT32(*fd_win_buf)[3][3][1536] = &ptr_hbe_txposer->fd_win_buf;
723
0
  FLOAT32 *phase = ptr_hbe_txposer->phase;
724
0
  WORD32 oversampling_flag = ptr_hbe_txposer->oversampling_flag;
725
0
  WORD32 fft_size = ptr_hbe_txposer->fft_size[oversampling_flag];
726
0
  FLOAT32 *ptr_spectrum_tx = ptr_hbe_txposer->ptr_spectrum_tx;
727
0
  FLOAT32 *mag = ptr_hbe_txposer->mag;
728
0
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
729
0
  p = (WORD32)p_flt;
730
0
  FLOAT32 q_thr = 4.0f;
731
0
  m_tr = 0;
732
733
0
  for (i = 0; i <= out_transform_size; i++) {
734
0
    WORD32 utk = 2 * i / trans_fac;
735
0
    FLOAT32 ptk = (2.0f * i / trans_fac) - utk;
736
737
0
    mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] *
738
0
            (FLOAT32)pow(mag[utk], 1.0f - ptk) * (FLOAT32)pow(mag[utk + 1], ptk);
739
740
0
    phase_t = trans_fac * ((1 - ptk) * phase[utk] + ptk * phase[utk + 1]);
741
742
0
    ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
743
0
    ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
744
745
0
    if (p > 0) {
746
0
      m_val = 0;
747
0
      for (tr = 1; tr < trans_fac; tr++) {
748
0
        FLOAT32 temp;
749
0
        ti = (WORD32)((2.0f * i - tr * p_flt) / trans_fac + 0.5f);
750
0
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
751
0
        temp = min(mag[ti], mag[ti + p]);
752
0
        if (temp > m_val) {
753
0
          m_val = temp;
754
0
          m_tr = tr;
755
0
          utk = ti;
756
0
        }
757
0
      }
758
759
0
      if (m_val > q_thr * mag[2 * i / trans_fac]) {
760
0
        FLOAT32 r = (FLOAT32)m_tr / trans_fac;
761
0
        mag_t = (*fd_win_buf)[trans_fac - 2][oversampling_flag][i] *
762
0
                (FLOAT32)pow(mag[utk], 1.0 - r) * (FLOAT32)pow(mag[utk + p], r);
763
0
        phase_t = (trans_fac - m_tr) * phase[utk] + m_tr * phase[utk + p];
764
0
        ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
765
0
        ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
766
0
      }
767
0
    }
768
0
  }
769
0
}
770
771
WORD32 ixheaacd_dft_hbe_apply(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer,
772
                              FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64],
773
                              WORD32 num_columns, FLOAT32 pv_qmf_buf_real[][64],
774
                              FLOAT32 pv_qmf_buf_imag[][64], WORD32 pitch_in_bins,
775
0
                              FLOAT32 *dft_hbe_scratch_buf) {
776
0
  WORD32 in_offset = 0;
777
0
  WORD32 out_offset = 0;
778
0
  WORD32 in_hop_size = ptr_hbe_txposer->in_hop_size;
779
0
  WORD32 oversampling_flag = ptr_hbe_txposer->oversampling_flag;
780
0
  WORD32 fft_size = ptr_hbe_txposer->fft_size[oversampling_flag];
781
782
0
  WORD32 out_hop_size = ptr_hbe_txposer->out_hop_size;
783
0
  WORD32 num_in_samples = num_columns * ptr_hbe_txposer->synth_size;
784
0
  WORD32 ana_fft_size = ptr_hbe_txposer->ana_fft_size[oversampling_flag];
785
0
  WORD32 syn_fft_size = ptr_hbe_txposer->syn_fft_size[oversampling_flag];
786
787
0
  WORD32 ana_pad_size = (ana_fft_size - ptr_hbe_txposer->ana_fft_size[0]) / 2;
788
0
  WORD32 syn_pad_size = (syn_fft_size - ptr_hbe_txposer->syn_fft_size[0]) / 2;
789
790
0
  FLOAT32 *ptr_input_buf = ptr_hbe_txposer->ptr_input_buf;
791
0
  FLOAT32 *ptr_output_buf = ptr_hbe_txposer->ptr_output_buf;
792
0
  FLOAT32 *ptr_spectrum = ptr_hbe_txposer->ptr_spectrum;
793
0
  FLOAT32 *ptr_spectrum_tx = ptr_hbe_txposer->ptr_spectrum_tx;
794
0
  FLOAT32 *mag = ptr_hbe_txposer->mag;
795
0
  FLOAT32 *phase = ptr_hbe_txposer->phase;
796
0
  WORD32 i, trans_fac;
797
798
0
  FLOAT32 *ptr_cos_fft;
799
0
  FLOAT32 *ptr_cos_ifft;
800
801
0
  WORD32 ana_fft_offset = ptr_hbe_txposer->k_start * fft_size / 32;
802
0
  WORD32 syn_fft_offset = ptr_hbe_txposer->a_start * fft_size / 64;
803
804
0
  WORD32 err_code = IA_NO_ERROR;
805
806
0
  memcpy(ptr_hbe_txposer->ptr_input_buf,
807
0
         ptr_hbe_txposer->ptr_input_buf + ptr_hbe_txposer->ana_fft_size[0],
808
0
         ptr_hbe_txposer->ana_fft_size[0] * sizeof(ptr_hbe_txposer->ptr_input_buf[0]));
809
810
0
  ixheaacd_real_synth_filt(ptr_hbe_txposer, num_columns, qmf_buf_real, qmf_buf_imag);
811
0
  memcpy(ptr_output_buf, ptr_output_buf + 2 * ptr_hbe_txposer->syn_fft_size[0],
812
0
         2 * ptr_hbe_txposer->syn_fft_size[0] * sizeof(*ptr_output_buf));
813
814
0
  memset(ptr_output_buf + 2 * ptr_hbe_txposer->syn_fft_size[0], 0,
815
0
         2 * ptr_hbe_txposer->syn_fft_size[0] * sizeof(*ptr_output_buf));
816
817
0
  err_code = ixheaacd_hbe_fft_map(ptr_hbe_txposer);
818
0
  if (err_code) return err_code;
819
0
  while (in_offset < num_in_samples) {
820
0
    memset(ptr_spectrum, 0, fft_size * sizeof(FLOAT32));
821
0
    memset(ptr_spectrum_tx, 0, ((fft_size + 2) * sizeof(FLOAT32)));
822
823
0
    memset(mag, 0, (fft_size / 2 + 2) * sizeof(FLOAT32));
824
0
    memset(phase, 0, (fft_size / 2 + 2) * sizeof(FLOAT32));
825
0
    ixheaacd_dft_hbe_apply_win(ptr_input_buf + in_offset, ptr_hbe_txposer->anal_window,
826
0
                               ptr_spectrum + ana_pad_size + ana_fft_offset,
827
0
                               ptr_hbe_txposer->ana_fft_size[0]);
828
0
    ixheaacd_dft_hbe_fft_memmove(ptr_spectrum + ana_fft_offset, ana_fft_size);
829
0
    {
830
0
      WORD32 len = ana_fft_size;
831
0
      ptr_cos_fft = ptr_hbe_txposer->ana_cos_sin_tab;
832
0
      FLOAT32 *ptr_fft_data = ptr_spectrum + ana_fft_offset;
833
0
      FLOAT32 tmp1, tmp2, tmp3, tmp4;
834
835
0
      (*(ptr_hbe_txposer->ixheaacd_hbe_anal_fft))(ptr_fft_data, dft_hbe_scratch_buf,
836
0
                                                  len / 2, -1);
837
838
0
      tmp1 = ptr_fft_data[0] + ptr_fft_data[1];
839
0
      ptr_fft_data[1] = ptr_fft_data[0] - ptr_fft_data[1];
840
0
      ptr_fft_data[0] = tmp1;
841
842
0
      for (i = 1; i <= (len / 4 + (len % 4) / 2); ++i) {
843
0
        tmp1 = ptr_fft_data[2 * i] - ptr_fft_data[len - 2 * i];
844
0
        tmp2 = ptr_fft_data[2 * i + 1] + ptr_fft_data[len - 2 * i + 1];
845
846
0
        tmp3 = (*(ptr_cos_fft)) * tmp1 -
847
0
               (*(ptr_cos_fft + 1)) * tmp2;
848
0
        tmp4 = (*(ptr_cos_fft + 1)) * tmp1 +
849
0
               (*(ptr_cos_fft)) * tmp2;
850
851
0
        ptr_cos_fft = ptr_cos_fft + 2;
852
853
0
        tmp1 = ptr_fft_data[2 * i] + ptr_fft_data[len - 2 * i];
854
0
        tmp2 = ptr_fft_data[2 * i + 1] - ptr_fft_data[len - 2 * i + 1];
855
856
0
        ptr_fft_data[2 * i + 0] = 0.5f * (tmp1 - tmp3);
857
0
        ptr_fft_data[2 * i + 1] = 0.5f * (tmp2 - tmp4);
858
0
        ptr_fft_data[len - 2 * i + 0] = 0.5f * (tmp1 + tmp3);
859
0
        ptr_fft_data[len - 2 * i + 1] = -0.5f * (tmp2 + tmp4);
860
0
      }
861
0
    }
862
0
    ixheaacd_karth2polar(ptr_spectrum + ana_fft_offset, mag + ana_fft_offset / 2,
863
0
                         phase + ana_fft_offset / 2, ana_fft_size);
864
865
0
    for (trans_fac = 2; trans_fac <= ptr_hbe_txposer->max_stretch; trans_fac++) {
866
0
      WORD32 out_transform_size;
867
868
0
      out_transform_size = (fft_size / 2);
869
870
0
      switch (trans_fac) {
871
0
        case 2:
872
0
          ixheaacd_dft_hbe_apply_polar_t2(trans_fac, ptr_hbe_txposer,
873
0
                                          pitch_in_bins, out_transform_size);
874
0
          break;
875
0
        case 3:
876
0
          ixheaacd_dft_hbe_apply_polar_t3(trans_fac, ptr_hbe_txposer,
877
0
                                          pitch_in_bins, out_transform_size);
878
0
          break;
879
0
        default:
880
0
          ixheaacd_dft_hbe_apply_polar_t(trans_fac, ptr_hbe_txposer,
881
0
                                         pitch_in_bins, out_transform_size);
882
0
      }
883
0
    }
884
885
0
    ptr_spectrum_tx[syn_fft_offset + 1] = ptr_spectrum_tx[syn_fft_offset +
886
0
                                                          syn_fft_size];
887
888
0
    {
889
0
      WORD32 len = syn_fft_size;
890
0
      ptr_cos_ifft = ptr_hbe_txposer->syn_cos_sin_tab;
891
0
      FLOAT32 *ptr_fft_data = ptr_spectrum_tx + syn_fft_offset;
892
0
      FLOAT32 tmp1, tmp2, tmp3, tmp4;
893
894
0
      FLOAT32 scale = 1.0f / len;
895
0
      tmp1 = ptr_fft_data[0] + ptr_fft_data[1];
896
0
      ptr_fft_data[1] = scale * (ptr_fft_data[0] - ptr_fft_data[1]);
897
0
      ptr_fft_data[0] = scale * tmp1;
898
899
0
      for (i = 1; i <= (len / 4 + (len % 4) / 2); ++i) {
900
0
        tmp1 = ptr_fft_data[2 * i] - ptr_fft_data[len - 2 * i];
901
0
        tmp2 = ptr_fft_data[2 * i + 1] + ptr_fft_data[len - 2 * i + 1];
902
903
0
        tmp3 = (*(ptr_cos_ifft)) * tmp1 +
904
0
               (*(ptr_cos_ifft + 1)) * tmp2;
905
0
        tmp4 = -(*(ptr_cos_ifft + 1)) * tmp1 +
906
0
               (*(ptr_cos_ifft)) * tmp2;
907
908
0
        ptr_cos_ifft = ptr_cos_ifft + 2;
909
910
0
        tmp1 = ptr_fft_data[2 * i] + ptr_fft_data[len - 2 * i];
911
0
        tmp2 = ptr_fft_data[2 * i + 1] - ptr_fft_data[len - 2 * i + 1];
912
913
0
        ptr_fft_data[2 * i] = scale * (tmp1 - tmp3);
914
0
        ptr_fft_data[2 * i + 1] = scale * (tmp2 - tmp4);
915
0
        ptr_fft_data[len - 2 * i] = scale * (tmp1 + tmp3);
916
0
        ptr_fft_data[len - 2 * i + 1] = -scale * (tmp2 + tmp4);
917
0
      }
918
919
0
      (*(ptr_hbe_txposer->ixheaacd_hbe_synth_ifft))(ptr_fft_data, dft_hbe_scratch_buf,
920
0
                                                    len / 2, 1);
921
0
    }
922
923
0
    ixheaacd_dft_hbe_fft_memmove(ptr_spectrum_tx + syn_fft_offset, syn_fft_size);
924
0
    ixheaacd_dft_hbe_apply_win(
925
0
        ptr_spectrum_tx + syn_pad_size + syn_fft_offset, ptr_hbe_txposer->synth_window,
926
0
        ptr_spectrum_tx + syn_pad_size + syn_fft_offset, ptr_hbe_txposer->syn_fft_size[0]);
927
928
0
    for (i = 0; i < ptr_hbe_txposer->syn_fft_size[0]; i++) {
929
0
      ptr_output_buf[out_offset + i] += ptr_spectrum_tx[syn_pad_size + syn_fft_offset + i];
930
0
    }
931
932
0
    in_offset += in_hop_size;
933
0
    out_offset += out_hop_size;
934
935
0
  }
936
937
0
  err_code = ixheaacd_dft_hbe_cplx_anal_filt(ptr_hbe_txposer, pv_qmf_buf_real,
938
0
                                             pv_qmf_buf_imag);
939
940
0
  return err_code;
941
0
}