Coverage Report

Created: 2025-12-14 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_sbr_hbe_dft_trans.c
Line
Count
Source
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2023 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
21
#include <math.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#include "ixheaac_type_def.h"
26
#include "ixheaace_bitbuffer.h"
27
#include "iusace_tns_usac.h"
28
#include "iusace_cnst.h"
29
#include "ixheaace_sbr_def.h"
30
#include "ixheaace_resampler.h"
31
#include "ixheaace_sbr_hbe.h"
32
#include "ixheaace_sbr_hbe_fft.h"
33
#include "ixheaace_error_codes.h"
34
#include "ixheaace_common_rom.h"
35
#include "ixheaac_error_standards.h"
36
#include "ixheaac_constants.h"
37
#include "ixheaac_esbr_rom.h"
38
39
4.19k
static FLOAT32 *ixheaace_map_prot_filter(WORD32 filt_length) {
40
4.19k
  switch (filt_length) {
41
0
    case 4:
42
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0];
43
0
      break;
44
0
    case 8:
45
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[40];
46
0
      break;
47
896
    case 12:
48
896
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[120];
49
0
      break;
50
929
    case 16:
51
929
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[240];
52
0
      break;
53
302
    case 20:
54
302
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[400];
55
0
      break;
56
7
    case 24:
57
7
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[600];
58
0
      break;
59
185
    case 28:
60
185
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[0];
61
0
      break;
62
384
    case 32:
63
384
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[840];
64
0
      break;
65
866
    case 36:
66
866
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[280];
67
0
      break;
68
7
    case 40:
69
7
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1160];
70
0
      break;
71
618
    case 44:
72
618
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1560];
73
0
      break;
74
0
    default:
75
0
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0];
76
4.19k
  }
77
4.19k
}
78
79
/**
80
 * Calculate frequency domain window according to 23003-3:2012, 7.5.3.1 eSBR - Tool description
81
 */
82
static VOID ixheaace_create_dft_hbe_window(FLOAT32 *ptr_win, WORD32 x_over_bin1,
83
9.24k
                                           WORD32 x_over_bin2, WORD32 ts, WORD32 size) {
84
9.24k
  const FLOAT32 *ptr_freq_domain_win = NULL;
85
9.24k
  WORD32 n;
86
9.24k
  if (ts == 12) {
87
4.62k
    ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_12[0];
88
4.62k
  } else {
89
4.62k
    ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_18[0];
90
4.62k
  }
91
2.86M
  for (n = 0; n < (x_over_bin1 - ts / 2); n++) {
92
2.85M
    ptr_win[n] = 0;
93
2.85M
  }
94
95
157k
  for (n = (x_over_bin1 - ts / 2); n <= (x_over_bin1 + ts / 2); n++) {
96
147k
    ptr_win[n] = (FLOAT32)ptr_freq_domain_win[n - (x_over_bin1 - ts / 2)];
97
147k
  }
98
99
1.19M
  for (n = (x_over_bin1 + ts / 2 + 1); n < (x_over_bin2 - ts / 2); n++) {
100
1.18M
    ptr_win[n] = (FLOAT32)1.0f;
101
1.18M
  }
102
103
157k
  for (n = (x_over_bin2 - ts / 2); n <= (x_over_bin2 + ts / 2); n++) {
104
147k
    ptr_win[n] = (FLOAT32)1.0f - ptr_freq_domain_win[n - (x_over_bin2 - ts / 2)];
105
147k
  }
106
107
7.50M
  for (n = (x_over_bin2 + ts / 2 + 1); n < size; n++) {
108
7.49M
    ptr_win[n] = 0.0f;
109
7.49M
  }
110
9.24k
}
111
112
4.19k
static IA_ERRORCODE ixheaace_calc_anal_synth_window(WORD32 fft_size, FLOAT32 *ptr_window) {
113
4.19k
  FLOAT32 sin_pi_2_n = 0.0f;
114
4.19k
  FLOAT32 cos_pi_2_n = 0.0f;
115
4.19k
  FLOAT32 *ptr_sin_pi_n_by_n = NULL;
116
4.19k
  WORD32 hop_stride = 1;
117
4.19k
  WORD32 i, j;
118
4.19k
  WORD32 l_fft_stride = 512;
119
4.19k
  switch (fft_size) {
120
0
    case 64:
121
0
      hop_stride = 16;
122
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
123
0
      sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1];
124
0
      cos_pi_2_n = ptr_sin_pi_n_by_n[512 + (hop_stride >> 1)];
125
0
      l_fft_stride = 512;
126
0
      break;
127
0
    case 128:
128
0
      hop_stride = 8;
129
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
130
0
      sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1];
131
0
      cos_pi_2_n = ptr_sin_pi_n_by_n[512 + (hop_stride >> 1)];
132
0
      l_fft_stride = 512;
133
0
      break;
134
0
    case 256:
135
0
      hop_stride = 4;
136
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
137
0
      sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1];
138
0
      cos_pi_2_n = ptr_sin_pi_n_by_n[512 + (hop_stride >> 1)];
139
0
      l_fft_stride = 512;
140
0
      break;
141
1.31k
    case 512:
142
1.31k
      hop_stride = 2;
143
1.31k
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
144
1.31k
      sin_pi_2_n = ptr_sin_pi_n_by_n[1];
145
1.31k
      cos_pi_2_n = ptr_sin_pi_n_by_n[512 + 1];
146
1.31k
      l_fft_stride = 512;
147
1.31k
      break;
148
0
    case 1024:
149
0
      hop_stride = 1;
150
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
151
0
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[0];
152
0
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[1];
153
0
      l_fft_stride = 512;
154
0
      break;
155
30
    case 192:
156
30
      hop_stride = 4;
157
30
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
158
30
      sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1];
159
30
      cos_pi_2_n = ptr_sin_pi_n_by_n[384 + (hop_stride >> 1)];
160
30
      l_fft_stride = 384;
161
30
      break;
162
873
    case 384:
163
873
      hop_stride = 2;
164
873
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
165
873
      sin_pi_2_n = ptr_sin_pi_n_by_n[1];
166
873
      cos_pi_2_n = ptr_sin_pi_n_by_n[384 + 1];
167
873
      l_fft_stride = 384;
168
873
      break;
169
0
    case 768:
170
0
      hop_stride = 1;
171
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
172
0
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[8];
173
0
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[9];
174
0
      l_fft_stride = 384;
175
0
      break;
176
0
    case 320:
177
0
      hop_stride = 3;
178
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_960[0];
179
0
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[16];
180
0
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[17];
181
0
      l_fft_stride = 480;
182
0
      break;
183
0
    case 960:
184
0
      hop_stride = 1;
185
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_960[0];
186
0
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[2];
187
0
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[3];
188
0
      l_fft_stride = 480;
189
0
      break;
190
185
    case 448:
191
185
      hop_stride = 2;
192
185
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_896[0];
193
185
      sin_pi_2_n = ptr_sin_pi_n_by_n[1];
194
185
      cos_pi_2_n = ptr_sin_pi_n_by_n[448 + 1];
195
185
      l_fft_stride = 448;
196
185
      break;
197
0
    case 896:
198
0
      hop_stride = 1;
199
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_896[0];
200
0
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[4];
201
0
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[5];
202
0
      l_fft_stride = 448;
203
0
      break;
204
866
    case 576:
205
866
      hop_stride = 1;
206
866
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_576[0];
207
866
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[14];
208
866
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[15];
209
866
      l_fft_stride = 288;
210
866
      break;
211
309
    case 640:
212
309
      hop_stride = 1;
213
309
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_640[0];
214
309
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[12];
215
309
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[13];
216
309
      l_fft_stride = 320;
217
309
      break;
218
618
    case 704:
219
618
      hop_stride = 1;
220
618
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_704[0];
221
618
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[10];
222
618
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[11];
223
618
      l_fft_stride = 352;
224
618
      break;
225
0
    case 832:
226
0
      hop_stride = 1;
227
0
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_832[0];
228
0
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[6];
229
0
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[7];
230
0
      l_fft_stride = 416;
231
0
      break;
232
0
    default:
233
0
      return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING;
234
4.19k
  }
235
236
  /*calculate Window*/
237
1.11M
  for (i = 0, j = 0; j < (fft_size >> 1); i += hop_stride, j++) {
238
1.11M
    FLOAT32 cos_val = ptr_sin_pi_n_by_n[i + l_fft_stride];
239
1.11M
    FLOAT32 sin_val = ptr_sin_pi_n_by_n[i];
240
1.11M
    ptr_window[j] = cos_val * sin_pi_2_n + sin_val * cos_pi_2_n;
241
1.11M
  }
242
243
1.11M
  for (; j < fft_size; j++, i += hop_stride) {
244
1.11M
    FLOAT32 cos_val = ptr_sin_pi_n_by_n[i - l_fft_stride];
245
1.11M
    FLOAT32 sin_val = ptr_sin_pi_n_by_n[i];
246
1.11M
    ptr_window[j] = sin_val * cos_pi_2_n - cos_val * sin_pi_2_n;
247
1.11M
  }
248
4.19k
  return IA_NO_ERROR;
249
4.19k
}
250
251
VOID ixheaace_esbr_hbe_data_init(ixheaace_str_esbr_hbe_txposer *pstr_esbr_hbe_txposer,
252
                                 const WORD32 num_aac_samples, WORD32 samp_fac_4_flag,
253
                                 const WORD32 num_out_samples, VOID *ptr_persistent_hbe_mem,
254
2.09k
                                 WORD32 *ptr_total_persistant) {
255
2.09k
  WORD32 used_persistent = 0;
256
257
2.09k
  if (pstr_esbr_hbe_txposer) {
258
2.09k
    memset(pstr_esbr_hbe_txposer, 0, sizeof(ixheaace_str_esbr_hbe_txposer));
259
260
2.09k
    pstr_esbr_hbe_txposer->core_frame_length = num_aac_samples;
261
262
2.09k
    pstr_esbr_hbe_txposer->no_bins = num_out_samples / IXHEAACE_NUM_QMF_SYNTH_CHANNELS;
263
264
2.09k
    pstr_esbr_hbe_txposer->hbe_qmf_in_len = pstr_esbr_hbe_txposer->no_bins;
265
266
2.09k
    pstr_esbr_hbe_txposer->hbe_qmf_out_len = 2 * pstr_esbr_hbe_txposer->hbe_qmf_in_len;
267
268
2.09k
    pstr_esbr_hbe_txposer->ptr_input_buf = (FLOAT32 *)ptr_persistent_hbe_mem;
269
2.09k
    used_persistent += (num_aac_samples + IXHEAACE_NUM_QMF_SYNTH_CHANNELS) *
270
2.09k
                       sizeof(pstr_esbr_hbe_txposer->ptr_input_buf[0]);
271
272
2.09k
    pstr_esbr_hbe_txposer->upsamp_4_flag = samp_fac_4_flag;
273
274
2.09k
    if (pstr_esbr_hbe_txposer) {
275
2.09k
      pstr_esbr_hbe_txposer->fft_size[0] = num_aac_samples;
276
2.09k
      pstr_esbr_hbe_txposer->fft_size[1] = (int)(IXHEAACE_FD_OVERSAMPLING_FAC * num_aac_samples);
277
278
      /*
279
        Worst Case Memory requirements for DFT based HBE.
280
        analysis ptr_win = num_aac_samples * sizeof(float)          = 1024 * sizeof(FLOAT32)
281
        synthesis ptr_win = num_aac_samples * sizeof(float)         = 1024 * sizeof(FLOAT32)
282
        ptr_spectrum = num_aac_samples * sizeof(float) * 1.5        = 1536 * sizeof(FLOAT32)
283
        spectrumTransposed = num_aac_samples * sizeof(float)    = 1536 * sizeof(FLOAT32)
284
        ptr_mag                                                     = 1536 * sizeof(FLOAT32)
285
        ptr_phase                                                   = 1536 * sizeof(FLOAT32)
286
        pstr_esbr_hbe_txposer->inBuf                            = 2048 * sizeof(FLOAT32)
287
        pstr_esbr_hbe_txposer->outBuf                           = 4096 * sizeof(FLOAT32)
288
        fd_win_buf                                                   = 2560 * 3 * sizeof(FLOAT32)
289
        Total ~ (1024 * 2 + 1536 * 4 + 2048 * 1 + 4096 * 1 + 2560 * 3) * sizeof(FLOAT32)
290
        = 22016 * sizeof(FLOAT32)
291
       */
292
293
2.09k
      pstr_esbr_hbe_txposer->ptr_spectrum = &pstr_esbr_hbe_txposer->spectrum_buf[0];
294
2.09k
      pstr_esbr_hbe_txposer->ptr_spectrum_tx = &pstr_esbr_hbe_txposer->spectrum_transposed_buf[0];
295
2.09k
      pstr_esbr_hbe_txposer->ptr_mag = &pstr_esbr_hbe_txposer->mag_buf[0];
296
2.09k
      pstr_esbr_hbe_txposer->ptr_phase = &pstr_esbr_hbe_txposer->phase_buf[0];
297
2.09k
      pstr_esbr_hbe_txposer->ptr_output_buf = &pstr_esbr_hbe_txposer->output_buf[0];
298
2.09k
    }
299
2.09k
  }
300
2.09k
  *ptr_total_persistant = used_persistent;
301
2.09k
}
302
303
2.09k
IA_ERRORCODE ixheaace_dft_hbe_data_reinit(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) {
304
2.09k
  WORD32 sfb;
305
2.09k
  WORD32 patch;
306
2.09k
  WORD32 i;
307
2.09k
  WORD32 temp_start;
308
2.09k
  FLOAT32 fb_ratio;
309
2.09k
  WORD32 stop_patch;
310
2.09k
  WORD32 in_hop_size_divisor = 8;
311
2.09k
  static const WORD32 trans_samp[2] = {12, 18}; /* FD transition samples */
312
2.09k
  WORD32 err = IA_NO_ERROR;
313
314
2.09k
  pstr_hbe_txposer->start_band = pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][0];
315
2.09k
  pstr_hbe_txposer->end_band =
316
2.09k
      pstr_hbe_txposer
317
2.09k
          ->ptr_freq_band_tab[IXHEAACE_LOW][pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW]];
318
2.09k
  pstr_hbe_txposer->esbr_hq = 1;
319
320
2.09k
  pstr_hbe_txposer->synth_size = 4 * ((pstr_hbe_txposer->start_band + 4) / 8 + 1);
321
2.09k
  pstr_hbe_txposer->k_start = ixheaac_start_subband2kL_tbl[pstr_hbe_txposer->start_band];
322
323
2.09k
  fb_ratio = pstr_hbe_txposer->synth_size / 32.0f;
324
325
2.09k
  pstr_hbe_txposer->ana_fft_size[0] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[0]);
326
2.09k
  pstr_hbe_txposer->ana_fft_size[1] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[1]);
327
328
2.09k
  pstr_hbe_txposer->in_hop_size = pstr_hbe_txposer->ana_fft_size[0] / in_hop_size_divisor;
329
330
2.09k
  pstr_hbe_txposer->ptr_syn_win = (FLOAT32 *)&pstr_hbe_txposer->synthesis_window_buf[0];
331
2.09k
  pstr_hbe_txposer->ptr_ana_win = (FLOAT32 *)&pstr_hbe_txposer->analysis_window_buf[0];
332
333
2.09k
  err = ixheaace_calc_anal_synth_window(pstr_hbe_txposer->ana_fft_size[0],
334
2.09k
                                        pstr_hbe_txposer->ptr_ana_win);
335
2.09k
  if (err) {
336
0
    return err;
337
0
  }
338
339
2.09k
  memset(pstr_hbe_txposer->synth_buf, 0, sizeof(pstr_hbe_txposer->synth_buf));
340
341
2.09k
  pstr_hbe_txposer->ptr_syn_win_coeff = ixheaace_map_prot_filter(pstr_hbe_txposer->synth_size);
342
343
2.09k
  temp_start = 2 * ((pstr_hbe_txposer->start_band - 1) / 2); /* Largest start band */
344
2.09k
  pstr_hbe_txposer->analy_size =
345
2.09k
      4 * ((min(64, pstr_hbe_txposer->end_band + 1) - temp_start - 1) / 4 +
346
2.09k
           1); /* Quantize in steps of 4 */
347
2.09k
  pstr_hbe_txposer->a_start = temp_start - max(0, temp_start + pstr_hbe_txposer->analy_size - 64);
348
349
2.09k
  fb_ratio = pstr_hbe_txposer->analy_size / 64.0f;
350
351
2.09k
  pstr_hbe_txposer->syn_fft_size[0] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[0]);
352
2.09k
  pstr_hbe_txposer->syn_fft_size[1] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[1]);
353
354
2.09k
  pstr_hbe_txposer->out_hop_size = 2 * pstr_hbe_txposer->syn_fft_size[0] / in_hop_size_divisor;
355
356
2.09k
  err = ixheaace_calc_anal_synth_window(pstr_hbe_txposer->syn_fft_size[0],
357
2.09k
                                        pstr_hbe_txposer->ptr_syn_win);
358
2.09k
  if (err) {
359
0
    return err;
360
0
  }
361
362
2.09k
  pstr_hbe_txposer->ptr_ana_win_coeff = ixheaace_map_prot_filter(pstr_hbe_txposer->analy_size);
363
364
  /* calculation of x_over_bin array and x_over_qmf array */
365
366
2.09k
  memset(&pstr_hbe_txposer->x_over_qmf[0], 0, sizeof(pstr_hbe_txposer->x_over_qmf));
367
368
10.4k
  for (i = 0; i < IXHEAACE_MAX_STRETCH; i++) {
369
8.38k
    memset(&pstr_hbe_txposer->x_over_bin[i][0], 0,
370
8.38k
           2 * sizeof(pstr_hbe_txposer->x_over_bin[i][0]));
371
8.38k
  }
372
2.09k
  sfb = 0;
373
2.09k
  stop_patch = IXHEAACE_MAX_STRETCH;
374
375
2.09k
  switch (pstr_hbe_txposer->synth_size) {
376
0
    case 4:
377
0
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4;
378
0
      pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2;
379
0
      break;
380
0
    case 8:
381
0
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_8;
382
0
      pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2;
383
0
      break;
384
866
    case 12:
385
866
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_12;
386
866
      pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p3;
387
866
      break;
388
929
    case 16:
389
929
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_16;
390
929
      pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2;
391
929
      break;
392
302
    case 20:
393
302
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20;
394
302
      break;
395
0
    case 28:
396
0
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20;
397
0
      break;
398
0
    default:
399
0
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4;
400
0
      pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2;
401
2.09k
  }
402
403
2.09k
  {
404
2.09k
    WORD32 l, k, L = pstr_hbe_txposer->analy_size;
405
78.7k
    for (k = 0; k < L; k++) {
406
5.82M
      for (l = 0; l < 2 * L; l++) {
407
5.75M
        pstr_hbe_txposer->str_dft_hbe_anal_coeff.real[k][l] =
408
5.75M
            (FLOAT32)cos(PI / (2 * L) *
409
5.75M
                         ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 * pstr_hbe_txposer->a_start));
410
5.75M
        pstr_hbe_txposer->str_dft_hbe_anal_coeff.imag[k][l] =
411
5.75M
            (FLOAT32)sin(PI / (2 * L) *
412
5.75M
                         ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 * pstr_hbe_txposer->a_start));
413
5.75M
      }
414
76.6k
    }
415
2.09k
  }
416
417
6.71k
  for (patch = 1; patch <= stop_patch; patch++) {
418
23.5k
    while (sfb <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW] &&
419
21.4k
           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb] <=
420
21.4k
               patch * pstr_hbe_txposer->start_band)
421
16.8k
      sfb++;
422
6.71k
    if (sfb <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW]) {
423
      /* If the distance is larger than three QMF bands - try aligning to high resolution
424
       * frequency bands instead. */
425
4.62k
      if ((patch * pstr_hbe_txposer->start_band -
426
4.62k
           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1]) <= 3) {
427
4.12k
        pstr_hbe_txposer->x_over_qmf[patch - 1] =
428
4.12k
            pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1];
429
4.12k
        if (patch <= IXHEAACE_MAX_STRETCH) {
430
4.12k
          pstr_hbe_txposer->x_over_bin[patch - 1][0] =
431
4.12k
              (WORD32)(pstr_hbe_txposer->fft_size[0] *
432
4.12k
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1] / 128 +
433
4.12k
                       0.5);
434
4.12k
          pstr_hbe_txposer->x_over_bin[patch - 1][1] =
435
4.12k
              (WORD32)(pstr_hbe_txposer->fft_size[1] *
436
4.12k
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1] / 128 +
437
4.12k
                       0.5);
438
4.12k
        }
439
4.12k
      } else {
440
493
        WORD32 sfb_idx = 0;
441
7.32k
        while (sfb_idx <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_HIGH] &&
442
7.32k
               pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx] <=
443
7.32k
                   patch * pstr_hbe_txposer->start_band)
444
6.83k
          sfb_idx++;
445
493
        pstr_hbe_txposer->x_over_qmf[patch - 1] =
446
493
            pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1];
447
493
        if (patch <= IXHEAACE_MAX_STRETCH) {
448
493
          pstr_hbe_txposer->x_over_bin[patch - 1][0] =
449
493
              (WORD32)(pstr_hbe_txposer->fft_size[0] *
450
493
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1] / 128 +
451
493
                       0.5);
452
493
          pstr_hbe_txposer->x_over_bin[patch - 1][1] =
453
493
              (WORD32)(pstr_hbe_txposer->fft_size[1] *
454
493
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1] / 128 +
455
493
                       0.5);
456
493
        }
457
493
      }
458
4.62k
    } else {
459
2.09k
      pstr_hbe_txposer->x_over_qmf[patch - 1] = pstr_hbe_txposer->end_band;
460
2.09k
      if (patch <= IXHEAACE_MAX_STRETCH) {
461
2.09k
        pstr_hbe_txposer->x_over_bin[patch - 1][0] =
462
2.09k
            (WORD32)(pstr_hbe_txposer->fft_size[0] * pstr_hbe_txposer->end_band / 128 + 0.5);
463
2.09k
        pstr_hbe_txposer->x_over_bin[patch - 1][1] =
464
2.09k
            (WORD32)(pstr_hbe_txposer->fft_size[1] * pstr_hbe_txposer->end_band / 128 + 0.5);
465
2.09k
      }
466
2.09k
      pstr_hbe_txposer->max_stretch = min(patch, IXHEAACE_MAX_STRETCH);
467
2.09k
      break;
468
2.09k
    }
469
6.71k
  }
470
471
  /* calculation of frequency domain windows */
472
6.71k
  for (patch = 0; patch < pstr_hbe_txposer->max_stretch - 1; patch++) {
473
13.8k
    for (i = 0; i < 2; i++) {
474
9.24k
      ixheaace_create_dft_hbe_window(pstr_hbe_txposer->fd_win_buf[patch][i],
475
9.24k
                                     pstr_hbe_txposer->x_over_bin[patch][i],
476
9.24k
                                     pstr_hbe_txposer->x_over_bin[patch + 1][i], trans_samp[i],
477
9.24k
                                     pstr_hbe_txposer->fft_size[i]);
478
9.24k
    }
479
4.62k
  }
480
2.09k
  return err;
481
2.09k
}
482
483
static VOID ixheaace_dft_hbe_apply_win(const FLOAT32 *ptr_x, const FLOAT32 *ptr_y, FLOAT32 *ptr_z,
484
290k
                                       WORD32 n) {
485
290k
  WORD32 i;
486
136M
  for (i = 0; i < n; i++) {
487
136M
    ptr_z[i] = ptr_x[i] * ptr_y[i];
488
136M
  }
489
290k
}
490
491
290k
VOID ixheaace_dft_hbe_fft_memmove(FLOAT32 *ptr_spectrum, WORD32 size) {
492
290k
  WORD32 n = 0;
493
494
68.3M
  while (n < size / 2) {
495
68.0M
    FLOAT32 tmp = ptr_spectrum[n];
496
68.0M
    ptr_spectrum[n] = ptr_spectrum[n + size / 2];
497
68.0M
    ptr_spectrum[n + size / 2] = tmp;
498
68.0M
    n++;
499
68.0M
  }
500
290k
}
501
VOID ixheaace_karth2polar(FLOAT32 *ptr_spectrum, FLOAT32 *ptr_mag, FLOAT32 *ptr_phase,
502
145k
                          WORD32 fft_size) {
503
145k
  WORD32 n;
504
505
32.2M
  for (n = 1; n < fft_size / 2; n++) {
506
32.0M
    ptr_phase[n] = (FLOAT32)atan2(ptr_spectrum[2 * n + 1], ptr_spectrum[2 * n]);
507
32.0M
    ptr_mag[n] = (FLOAT32)sqrt(ptr_spectrum[2 * n] * ptr_spectrum[2 * n] +
508
32.0M
                               ptr_spectrum[2 * n + 1] * ptr_spectrum[2 * n + 1]);
509
32.0M
  }
510
511
145k
  if (ptr_spectrum[0] < 0) {
512
0
    ptr_phase[0] = (FLOAT32)acos(-1);
513
0
    ptr_mag[0] = -ptr_spectrum[0];
514
145k
  } else {
515
145k
    ptr_phase[0] = 0;
516
145k
    ptr_mag[0] = ptr_spectrum[0];
517
145k
  }
518
519
145k
  if (ptr_spectrum[1] < 0) {
520
0
    ptr_phase[fft_size / 2] = (FLOAT32)acos(-1);
521
0
    ptr_mag[fft_size / 2] = -ptr_spectrum[1];
522
145k
  } else {
523
145k
    ptr_phase[fft_size / 2] = 0;
524
145k
    ptr_mag[fft_size / 2] = ptr_spectrum[1];
525
145k
  }
526
145k
}
527
0
VOID ixheaace_hbe_fft_tab(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) {
528
0
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
529
0
  WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag];
530
0
  WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag];
531
532
0
  switch (ana_fft_size) {
533
0
    case 576:
534
0
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576;
535
0
      break;
536
0
    case 384:
537
0
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_384;
538
0
      break;
539
0
    case 512:
540
0
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
541
0
      break;
542
0
    case 768:
543
0
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
544
0
      break;
545
0
    default:
546
0
      break;
547
0
  }
548
549
0
  switch (syn_fft_size) {
550
0
    case 448:
551
0
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_448;
552
0
      break;
553
0
    case 512:
554
0
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
555
0
      break;
556
0
    case 768:
557
0
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
558
0
      break;
559
0
    case 672:
560
0
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_672;
561
0
      break;
562
0
    default:
563
0
      break;
564
0
  }
565
0
}
566
567
26.6k
IA_ERRORCODE ixheaace_hbe_fft_map(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) {
568
26.6k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
569
26.6k
  WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag];
570
26.6k
  WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag];
571
572
26.6k
  switch (ana_fft_size) {
573
2.50k
    case 576:
574
2.50k
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576;
575
2.50k
      pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_fft_288;
576
2.50k
      break;
577
10.2k
    case 384:
578
10.2k
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_384;
579
10.2k
      pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn_gen;
580
10.2k
      break;
581
8.94k
    case 512:
582
8.94k
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
583
8.94k
      pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn;
584
8.94k
      break;
585
0
    case 768:
586
0
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
587
0
      pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn_gen;
588
0
      break;
589
5.01k
    default:
590
5.01k
      return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING;
591
0
      break;
592
26.6k
  }
593
594
21.6k
  switch (syn_fft_size) {
595
9.08k
    case 448:
596
9.08k
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_448;
597
9.08k
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_ifft_224;
598
9.08k
      break;
599
5.33k
    case 512:
600
5.33k
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
601
5.33k
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_cfftn;
602
5.33k
      break;
603
3.73k
    case 576:
604
3.73k
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576;
605
3.73k
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_fft_288;
606
3.73k
      break;
607
0
    case 768:
608
0
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768;
609
0
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_cfftn_gen;
610
0
      break;
611
0
    case 672:
612
0
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_672;
613
0
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_ifft_336;
614
0
      break;
615
3.51k
    default:
616
3.51k
      return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING;
617
0
      break;
618
21.6k
  }
619
620
18.1k
  return IA_NO_ERROR;
621
21.6k
}
622
623
VOID ia_dft_hbe_apply_polar_t2(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer,
624
145k
                               WORD32 pitch_in_bins, WORD out_transform_size) {
625
145k
  WORD32 tr;
626
145k
  WORD32 ti;
627
145k
  WORD32 m_tr = 0;
628
145k
  WORD32 p, i;
629
145k
  FLOAT32 mag_t;
630
145k
  FLOAT32 phase_t;
631
145k
  FLOAT32 m_val;
632
145k
  FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf;
633
145k
  FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase;
634
145k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
635
145k
  WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag];
636
145k
  FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx;
637
145k
  FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag;
638
  /* pitch_in_bins is given with the resolution of a 1536 point FFT */
639
145k
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
640
145k
  p = (WORD32)p_flt;
641
145k
  FLOAT32 q_thr = 4.0f;
642
643
145k
  if (T < 2) {
644
    // To avoid invalid access by fd_win_buf
645
0
    T = 2;
646
0
  }
647
145k
  i = 0;
648
74.6M
  while (i <= out_transform_size) {
649
74.5M
    WORD32 utk = i;
650
651
74.5M
    mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ptr_mag[utk];
652
653
74.5M
    phase_t = T * ptr_phase[utk];
654
655
74.5M
    if (phase_t == 0.0) {
656
74.5M
      ptr_spectrum_tx[2 * i] += mag_t;
657
74.5M
    } else {
658
0
      ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
659
0
      ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
660
0
    }
661
74.5M
    if (p > 0) {
662
65.1M
      m_val = 0;
663
130M
      for (tr = 1; tr < T; tr++) {
664
65.1M
        FLOAT32 temp;
665
65.1M
        ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f);
666
65.1M
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
667
63.8M
        temp = min(ptr_mag[ti], ptr_mag[ti + p]);
668
63.8M
        if (temp > m_val) {
669
0
          m_val = temp;
670
0
          m_tr = tr;
671
0
          utk = ti;
672
0
        }
673
63.8M
      } /* for tr */
674
675
65.1M
      if (m_val > q_thr * ptr_mag[2 * i / T]) {
676
0
        mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ((FLOAT32)sqrt(ptr_mag[utk])) *
677
0
                ((FLOAT32)sqrt(ptr_mag[utk + p]));
678
0
        phase_t = ((FLOAT32)(T - m_tr)) * ptr_phase[utk] + ((FLOAT32)m_tr) * ptr_phase[utk + p];
679
0
        ptr_spectrum_tx[2 * i] += mag_t * ((FLOAT32)cos(phase_t));
680
0
        ptr_spectrum_tx[2 * i + 1] += mag_t * ((FLOAT32)sin(phase_t));
681
0
      }
682
65.1M
    }
683
74.5M
    i++;
684
74.5M
  }
685
145k
}
686
687
VOID ia_dft_hbe_apply_polar_t_3(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer,
688
145k
                                WORD32 pitch_in_bins, WORD out_transform_size) {
689
145k
  WORD32 tr;
690
145k
  WORD32 ti;
691
145k
  WORD32 m_tr = 0;
692
145k
  WORD32 p, i;
693
145k
  FLOAT32 mag_t = 0.0f;
694
145k
  FLOAT32 phase_t;
695
145k
  FLOAT32 m_val;
696
145k
  FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf;
697
145k
  FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase;
698
145k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
699
145k
  WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag];
700
145k
  FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx;
701
145k
  FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag;
702
  /* pitch_in_bins is given with the resolution of a 1536 point FFT */
703
145k
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
704
145k
  p = (WORD32)p_flt;
705
145k
  FLOAT32 q_thr = 4.0f;
706
707
145k
  if (T < 3) {
708
    // To avoid invalid access by fd_win_buf
709
0
    T = 3;
710
0
  }
711
712
145k
  i = 0;
713
74.6M
  while (i <= out_transform_size) {
714
74.5M
    WORD32 utk = 2 * i / T;
715
74.5M
    FLOAT32 ptk = (2.0f * i / T) - utk;
716
74.5M
    FLOAT32 k;
717
718
74.5M
    if (i % 3 == 0) {
719
24.8M
      mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ptr_mag[utk];
720
49.6M
    } else if (i % 3 == 1) {
721
24.8M
      k = (FLOAT32)cbrt(ptr_mag[utk]);
722
24.8M
      mag_t =
723
24.8M
          (*fd_win_buf)[T - 2][oversampling_flag][i] * k * (FLOAT32)pow(ptr_mag[utk + 1], ptk);
724
24.8M
    } else if (i % 3 == 2) {
725
24.8M
      k = (FLOAT32)cbrt(ptr_mag[utk + 1]);
726
24.8M
      mag_t =
727
24.8M
          (*fd_win_buf)[T - 2][oversampling_flag][i] * (FLOAT32)pow(ptr_mag[utk], 1.0 - ptk) * k;
728
24.8M
    }
729
730
74.5M
    phase_t = T * ((1 - ptk) * ptr_phase[utk] + ptk * ptr_phase[utk + 1]);
731
732
74.5M
    ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
733
74.5M
    ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
734
735
74.5M
    if (p > 0) {
736
65.1M
      m_val = 0;
737
195M
      for (tr = 1; tr < T; tr++) {
738
130M
        FLOAT32 temp;
739
130M
        ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f);
740
130M
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
741
128M
        temp = min(ptr_mag[ti], ptr_mag[ti + p]);
742
128M
        if (temp > m_val) {
743
0
          m_val = temp;
744
0
          m_tr = tr;
745
0
          utk = ti;
746
0
        }
747
128M
      } /* for tr */
748
749
65.1M
      if (m_val > q_thr * ptr_mag[2 * i / T]) {
750
0
        FLOAT32 r = (FLOAT32)m_tr / T;
751
0
        switch (m_tr) {
752
0
          case 1:
753
0
            k = (FLOAT32)(cbrt((FLOAT32)ptr_mag[utk + p]));
754
0
            mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] *
755
0
                    (FLOAT32)pow(ptr_mag[utk], 1.0 - r) * k;
756
0
            phase_t = (T - m_tr) * ptr_phase[utk] + ptr_phase[utk + p];
757
0
            break;
758
759
0
          case 2:
760
0
            k = (FLOAT32)(cbrt((FLOAT32)ptr_mag[utk]));
761
0
            mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * k *
762
0
                    (FLOAT32)pow(ptr_mag[utk + p], r);
763
0
            phase_t = ptr_phase[utk] + m_tr * ptr_phase[utk + p];
764
0
            break;
765
0
        }
766
767
0
        ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
768
0
        ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
769
0
      }
770
65.1M
    }
771
74.5M
    i++;
772
74.5M
  }
773
145k
}
774
775
VOID ia_dft_hbe_apply_polar_t(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer,
776
0
                              WORD32 pitch_in_bins, WORD out_transform_size) {
777
0
  WORD32 tr;
778
0
  WORD32 ti;
779
0
  WORD32 m_tr = 0;
780
0
  WORD32 p, i;
781
0
  FLOAT32 mag_t;
782
0
  FLOAT32 phase_t;
783
0
  FLOAT32 m_val;
784
0
  FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf;
785
0
  FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase;
786
0
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
787
0
  WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag];
788
0
  FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx;
789
0
  FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag;
790
  /* pitch_in_bins is given with the resolution of a 1536 point FFT */
791
0
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
792
0
  p = (WORD32)p_flt;
793
0
  FLOAT32 q_thr = 4.0f;
794
795
0
  if (T < 2) {
796
    // To avoid invalid access by fd_win_buf
797
0
    T = 2;
798
0
  }
799
0
  for (i = 0; i <= out_transform_size; i++) {
800
0
    WORD32 utk = 2 * i / T;
801
0
    FLOAT32 ptk = (2.0f * i / T) - utk;
802
803
0
    mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * (FLOAT32)pow(ptr_mag[utk], 1.0f - ptk) *
804
0
            (FLOAT32)pow(ptr_mag[utk + 1], ptk);
805
806
0
    phase_t = T * ((1 - ptk) * ptr_phase[utk] + ptk * ptr_phase[utk + 1]);
807
808
0
    ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
809
0
    ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
810
811
0
    if (p > 0) {
812
0
      m_val = 0;
813
0
      for (tr = 1; tr < T; tr++) {
814
0
        FLOAT32 temp;
815
0
        ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f);
816
0
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
817
0
        temp = min(ptr_mag[ti], ptr_mag[ti + p]);
818
0
        if (temp > m_val) {
819
0
          m_val = temp;
820
0
          m_tr = tr;
821
0
          utk = ti;
822
0
        }
823
0
      } /* for tr */
824
825
0
      if (m_val > q_thr * ptr_mag[2 * i / T]) {
826
0
        FLOAT32 r = (FLOAT32)m_tr / T;
827
0
        mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * (FLOAT32)pow(ptr_mag[utk], 1.0 - r) *
828
0
                (FLOAT32)pow(ptr_mag[utk + p], r);
829
0
        phase_t = (T - m_tr) * ptr_phase[utk] + m_tr * ptr_phase[utk + p];
830
0
        ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
831
0
        ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
832
0
      }
833
0
    }
834
0
  }
835
0
}
836
837
IA_ERRORCODE ixheaace_dft_hbe_apply(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer,
838
                                    FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64],
839
                                    WORD32 num_columns, FLOAT32 pv_qmf_buf_real[][64],
840
                                    FLOAT32 pv_qmf_buf_imag[][64], WORD32 pitch_in_bins,
841
26.6k
                                    FLOAT32 *ptr_dft_hbe_scratch_buf) {
842
26.6k
  WORD32 in_offset = 0;
843
26.6k
  WORD32 out_offset = 0;
844
26.6k
  WORD32 in_hop_size = pstr_hbe_txposer->in_hop_size;
845
26.6k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
846
26.6k
  WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag];
847
848
26.6k
  WORD32 out_hop_size = pstr_hbe_txposer->out_hop_size;
849
26.6k
  WORD32 num_in_samples = num_columns * pstr_hbe_txposer->synth_size;
850
26.6k
  WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag];
851
26.6k
  WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag];
852
853
26.6k
  WORD32 ana_pad_size = (ana_fft_size - pstr_hbe_txposer->ana_fft_size[0]) / 2;
854
26.6k
  WORD32 syn_pad_size = (syn_fft_size - pstr_hbe_txposer->syn_fft_size[0]) / 2;
855
856
26.6k
  FLOAT32 *ptr_input_buf = pstr_hbe_txposer->ptr_input_buf;
857
26.6k
  FLOAT32 *ptr_output_buf = pstr_hbe_txposer->ptr_output_buf;
858
26.6k
  FLOAT32 *ptr_spectrum = pstr_hbe_txposer->ptr_spectrum;
859
26.6k
  FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx;
860
26.6k
  FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag;
861
26.6k
  FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase;
862
26.6k
  WORD32 i, T;
863
26.6k
  FLOAT32 *ptr_cos_fft;
864
26.6k
  FLOAT32 *ptr_cos_ifft;
865
866
26.6k
  WORD32 ana_fft_offset = pstr_hbe_txposer->k_start * fft_size / 32;
867
26.6k
  WORD32 syn_fft_offset = pstr_hbe_txposer->a_start * fft_size / 64;
868
  /* pitch_in_bins is given with the resolution of a 1536 point FFT */
869
26.6k
  WORD32 err_code = IA_NO_ERROR;
870
871
26.6k
  memcpy(pstr_hbe_txposer->ptr_input_buf,
872
26.6k
         pstr_hbe_txposer->ptr_input_buf + pstr_hbe_txposer->ana_fft_size[0],
873
26.6k
         pstr_hbe_txposer->ana_fft_size[0] * sizeof(pstr_hbe_txposer->ptr_input_buf[0]));
874
875
26.6k
  err_code = ixheaace_real_synth_filt(pstr_hbe_txposer, num_columns, qmf_buf_real, qmf_buf_imag);
876
26.6k
  if (err_code) {
877
0
    return err_code;
878
0
  }
879
880
26.6k
  memcpy(ptr_output_buf, ptr_output_buf + 2 * pstr_hbe_txposer->syn_fft_size[0],
881
26.6k
         2 * pstr_hbe_txposer->syn_fft_size[0] * sizeof(ptr_output_buf[0]));
882
883
26.6k
  memset(ptr_output_buf + 2 * pstr_hbe_txposer->syn_fft_size[0], 0,
884
26.6k
         2 * pstr_hbe_txposer->syn_fft_size[0] * sizeof(ptr_output_buf[0]));
885
886
26.6k
  err_code = ixheaace_hbe_fft_map(pstr_hbe_txposer);
887
26.6k
  if (err_code) {
888
8.52k
    return err_code;
889
8.52k
  }
890
891
163k
  while (in_offset < num_in_samples) {
892
145k
    memset(ptr_spectrum, 0, fft_size * sizeof(ptr_spectrum[0]));
893
145k
    memset(ptr_spectrum_tx, 0, ((fft_size + 2) * sizeof(ptr_spectrum_tx[0])));
894
895
145k
    memset(ptr_mag, 0, (fft_size / 2 + 2) * sizeof(ptr_mag[0]));
896
145k
    memset(ptr_phase, 0, (fft_size / 2 + 2) * sizeof(ptr_phase[0]));
897
145k
    ixheaace_dft_hbe_apply_win(ptr_input_buf + in_offset, pstr_hbe_txposer->ptr_ana_win,
898
145k
                               ptr_spectrum + ana_pad_size + ana_fft_offset,
899
145k
                               pstr_hbe_txposer->ana_fft_size[0]);
900
145k
    ixheaace_dft_hbe_fft_memmove(ptr_spectrum + ana_fft_offset, ana_fft_size);
901
145k
    {
902
145k
      WORD32 len = ana_fft_size;
903
145k
      ptr_cos_fft = pstr_hbe_txposer->ptr_ana_cos_sin_tab;
904
145k
      FLOAT32 *ptr_fft_data = ptr_spectrum + ana_fft_offset;
905
145k
      FLOAT32 tmp1, tmp2, tmp3, tmp4;
906
145k
      (*(pstr_hbe_txposer->ixheaace_hbe_anal_fft))(ptr_fft_data, ptr_dft_hbe_scratch_buf, len / 2,
907
145k
                                                   -1);
908
145k
      tmp1 = ptr_fft_data[0] + ptr_fft_data[1];
909
145k
      ptr_fft_data[1] = ptr_fft_data[0] - ptr_fft_data[1];
910
145k
      ptr_fft_data[0] = tmp1;
911
912
145k
      i = 1;
913
16.2M
      while (i <= (len / 4 + (len % 4) / 2)) {
914
16.1M
        tmp1 = ptr_fft_data[2 * i] - ptr_fft_data[len - 2 * i];
915
16.1M
        tmp2 = ptr_fft_data[2 * i + 1] + ptr_fft_data[len - 2 * i + 1];
916
917
16.1M
        tmp3 = (*(ptr_cos_fft)) * tmp1 - (*(ptr_cos_fft + 1)) * tmp2;
918
16.1M
        tmp4 = (*(ptr_cos_fft + 1)) * tmp1 + (*(ptr_cos_fft)) * tmp2;
919
920
16.1M
        ptr_cos_fft = ptr_cos_fft + 2;
921
922
16.1M
        tmp1 = ptr_fft_data[2 * i] + ptr_fft_data[len - 2 * i];
923
16.1M
        tmp2 = ptr_fft_data[2 * i + 1] - ptr_fft_data[len - 2 * i + 1];
924
925
16.1M
        ptr_fft_data[2 * i + 0] = 0.5f * (tmp1 - tmp3);
926
16.1M
        ptr_fft_data[2 * i + 1] = 0.5f * (tmp2 - tmp4);
927
16.1M
        ptr_fft_data[len - 2 * i + 0] = 0.5f * (tmp1 + tmp3);
928
16.1M
        ptr_fft_data[len - 2 * i + 1] = -0.5f * (tmp2 + tmp4);
929
16.1M
        ++i;
930
16.1M
      }
931
145k
    }
932
145k
    ixheaace_karth2polar(ptr_spectrum + ana_fft_offset, ptr_mag + ana_fft_offset / 2,
933
145k
                         ptr_phase + ana_fft_offset / 2, ana_fft_size);
934
935
435k
    for (T = 2; T <= pstr_hbe_txposer->max_stretch; T++) {
936
      /* max_stretch cannot be greater than 4. So, T can be 2 to 4*/
937
938
290k
      WORD32 out_transform_size;
939
940
      /* 0<i<fft_size/2 */
941
290k
      out_transform_size = (fft_size / 2);
942
290k
      switch (T) {
943
145k
        case 2:
944
145k
          ia_dft_hbe_apply_polar_t2(T, pstr_hbe_txposer, pitch_in_bins, out_transform_size);
945
145k
          break;
946
145k
        case 3:
947
145k
          ia_dft_hbe_apply_polar_t_3(T, pstr_hbe_txposer, pitch_in_bins, out_transform_size);
948
145k
          break;
949
0
        default:
950
0
          ia_dft_hbe_apply_polar_t(T, pstr_hbe_txposer, pitch_in_bins, out_transform_size);
951
290k
      }
952
290k
    } /* for T */
953
954
145k
    ptr_spectrum_tx[syn_fft_offset + 1] =
955
145k
        ptr_spectrum_tx[syn_fft_offset + syn_fft_size]; /* Move Nyquist bin to bin 1 for RFFTN */
956
957
145k
    {
958
145k
      WORD32 len = syn_fft_size;
959
145k
      ptr_cos_ifft = pstr_hbe_txposer->ptr_syn_cos_sin_tab;
960
145k
      FLOAT32 *ptr_fft_data = ptr_spectrum_tx + syn_fft_offset;
961
145k
      FLOAT32 tmp1, tmp2, tmp3, tmp4;
962
963
145k
      FLOAT32 scale = 1.0f / len;
964
145k
      tmp1 = ptr_fft_data[0] + ptr_fft_data[1];
965
145k
      ptr_fft_data[1] = scale * (ptr_fft_data[0] - ptr_fft_data[1]);
966
145k
      ptr_fft_data[0] = scale * tmp1;
967
968
18.0M
      for (i = 1; i <= (len / 4 + (len % 4) / 2); ++i) {
969
17.9M
        tmp1 = ptr_fft_data[2 * i] - ptr_fft_data[len - 2 * i];
970
17.9M
        tmp2 = ptr_fft_data[2 * i + 1] + ptr_fft_data[len - 2 * i + 1];
971
972
17.9M
        tmp3 = (*(ptr_cos_ifft)) * tmp1 + (*(ptr_cos_ifft + 1)) * tmp2;
973
17.9M
        tmp4 = -(*(ptr_cos_ifft + 1)) * tmp1 + (*(ptr_cos_ifft)) * tmp2;
974
975
17.9M
        ptr_cos_ifft = ptr_cos_ifft + 2;
976
977
17.9M
        tmp1 = ptr_fft_data[2 * i] + ptr_fft_data[len - 2 * i];
978
17.9M
        tmp2 = ptr_fft_data[2 * i + 1] - ptr_fft_data[len - 2 * i + 1];
979
980
17.9M
        ptr_fft_data[2 * i] = scale * (tmp1 - tmp3);
981
17.9M
        ptr_fft_data[2 * i + 1] = scale * (tmp2 - tmp4);
982
17.9M
        ptr_fft_data[len - 2 * i] = scale * (tmp1 + tmp3);
983
17.9M
        ptr_fft_data[len - 2 * i + 1] = -scale * (tmp2 + tmp4);
984
17.9M
      }
985
986
145k
      (*(pstr_hbe_txposer->ixheaace_hbe_synth_ifft))(ptr_fft_data, ptr_dft_hbe_scratch_buf,
987
145k
                                                     len / 2, 1);
988
145k
    }
989
990
145k
    ixheaace_dft_hbe_fft_memmove(ptr_spectrum_tx + syn_fft_offset, syn_fft_size);
991
145k
    ixheaace_dft_hbe_apply_win(
992
145k
        ptr_spectrum_tx + syn_pad_size + syn_fft_offset, pstr_hbe_txposer->ptr_syn_win,
993
145k
        ptr_spectrum_tx + syn_pad_size + syn_fft_offset, pstr_hbe_txposer->syn_fft_size[0]);
994
995
71.7M
    for (i = 0; i < pstr_hbe_txposer->syn_fft_size[0]; i++) {
996
71.6M
      ptr_output_buf[out_offset + i] += ptr_spectrum_tx[syn_pad_size + syn_fft_offset + i];
997
71.6M
    }
998
999
145k
    in_offset += in_hop_size;
1000
145k
    out_offset += out_hop_size;
1001
1002
145k
  } /* while(in_offset<num_in_samples) */
1003
1004
18.1k
  ixheaace_dft_hbe_cplx_anal_filt(pstr_hbe_txposer, pv_qmf_buf_real, pv_qmf_buf_imag);
1005
1006
18.1k
  return err_code;
1007
18.1k
}