Coverage Report

Created: 2026-09-28 07:18

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
3.95k
static FLOAT32 *ixheaace_map_prot_filter(WORD32 filt_length) {
40
3.95k
  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
885
    case 12:
48
885
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[120];
49
0
      break;
50
797
    case 16:
51
797
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[240];
52
0
      break;
53
361
    case 20:
54
361
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[400];
55
0
      break;
56
6
    case 24:
57
6
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[600];
58
0
      break;
59
149
    case 28:
60
149
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[0];
61
0
      break;
62
386
    case 32:
63
386
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[840];
64
0
      break;
65
797
    case 36:
66
797
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[280];
67
0
      break;
68
5
    case 40:
69
5
      return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1160];
70
0
      break;
71
568
    case 44:
72
568
      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
3.95k
  }
77
3.95k
}
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
8.66k
                                           WORD32 x_over_bin2, WORD32 ts, WORD32 size) {
84
8.66k
  const FLOAT32 *ptr_freq_domain_win = NULL;
85
8.66k
  WORD32 n;
86
8.66k
  if (ts == 12) {
87
4.33k
    ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_12[0];
88
4.33k
  } else {
89
4.33k
    ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_18[0];
90
4.33k
  }
91
2.69M
  for (n = 0; n < (x_over_bin1 - ts / 2); n++) {
92
2.68M
    ptr_win[n] = 0;
93
2.68M
  }
94
95
147k
  for (n = (x_over_bin1 - ts / 2); n <= (x_over_bin1 + ts / 2); n++) {
96
138k
    ptr_win[n] = (FLOAT32)ptr_freq_domain_win[n - (x_over_bin1 - ts / 2)];
97
138k
  }
98
99
1.11M
  for (n = (x_over_bin1 + ts / 2 + 1); n < (x_over_bin2 - ts / 2); n++) {
100
1.10M
    ptr_win[n] = (FLOAT32)1.0f;
101
1.10M
  }
102
103
147k
  for (n = (x_over_bin2 - ts / 2); n <= (x_over_bin2 + ts / 2); n++) {
104
138k
    ptr_win[n] = (FLOAT32)1.0f - ptr_freq_domain_win[n - (x_over_bin2 - ts / 2)];
105
138k
  }
106
107
7.03M
  for (n = (x_over_bin2 + ts / 2 + 1); n < size; n++) {
108
7.02M
    ptr_win[n] = 0.0f;
109
7.02M
  }
110
8.66k
}
111
112
3.95k
static IA_ERRORCODE ixheaace_calc_anal_synth_window(WORD32 fft_size, FLOAT32 *ptr_window) {
113
3.95k
  FLOAT32 sin_pi_2_n = 0.0f;
114
3.95k
  FLOAT32 cos_pi_2_n = 0.0f;
115
3.95k
  FLOAT32 *ptr_sin_pi_n_by_n = NULL;
116
3.95k
  WORD32 hop_stride = 1;
117
3.95k
  WORD32 i, j;
118
3.95k
  WORD32 l_fft_stride = 512;
119
3.95k
  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.18k
    case 512:
142
1.18k
      hop_stride = 2;
143
1.18k
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0];
144
1.18k
      sin_pi_2_n = ptr_sin_pi_n_by_n[1];
145
1.18k
      cos_pi_2_n = ptr_sin_pi_n_by_n[512 + 1];
146
1.18k
      l_fft_stride = 512;
147
1.18k
      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
66
    case 192:
156
66
      hop_stride = 4;
157
66
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
158
66
      sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1];
159
66
      cos_pi_2_n = ptr_sin_pi_n_by_n[384 + (hop_stride >> 1)];
160
66
      l_fft_stride = 384;
161
66
      break;
162
825
    case 384:
163
825
      hop_stride = 2;
164
825
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0];
165
825
      sin_pi_2_n = ptr_sin_pi_n_by_n[1];
166
825
      cos_pi_2_n = ptr_sin_pi_n_by_n[384 + 1];
167
825
      l_fft_stride = 384;
168
825
      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
149
    case 448:
191
149
      hop_stride = 2;
192
149
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_896[0];
193
149
      sin_pi_2_n = ptr_sin_pi_n_by_n[1];
194
149
      cos_pi_2_n = ptr_sin_pi_n_by_n[448 + 1];
195
149
      l_fft_stride = 448;
196
149
      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
797
    case 576:
205
797
      hop_stride = 1;
206
797
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_576[0];
207
797
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[14];
208
797
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[15];
209
797
      l_fft_stride = 288;
210
797
      break;
211
366
    case 640:
212
366
      hop_stride = 1;
213
366
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_640[0];
214
366
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[12];
215
366
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[13];
216
366
      l_fft_stride = 320;
217
366
      break;
218
568
    case 704:
219
568
      hop_stride = 1;
220
568
      ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_704[0];
221
568
      sin_pi_2_n = ixheaac_sine_pi_by_2_N[10];
222
568
      cos_pi_2_n = ixheaac_sine_pi_by_2_N[11];
223
568
      l_fft_stride = 352;
224
568
      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
3.95k
  }
235
236
  /*calculate Window*/
237
1.05M
  for (i = 0, j = 0; j < (fft_size >> 1); i += hop_stride, j++) {
238
1.04M
    FLOAT32 cos_val = ptr_sin_pi_n_by_n[i + l_fft_stride];
239
1.04M
    FLOAT32 sin_val = ptr_sin_pi_n_by_n[i];
240
1.04M
    ptr_window[j] = cos_val * sin_pi_2_n + sin_val * cos_pi_2_n;
241
1.04M
  }
242
243
1.05M
  for (; j < fft_size; j++, i += hop_stride) {
244
1.04M
    FLOAT32 cos_val = ptr_sin_pi_n_by_n[i - l_fft_stride];
245
1.04M
    FLOAT32 sin_val = ptr_sin_pi_n_by_n[i];
246
1.04M
    ptr_window[j] = sin_val * cos_pi_2_n - cos_val * sin_pi_2_n;
247
1.04M
  }
248
3.95k
  return IA_NO_ERROR;
249
3.95k
}
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
1.97k
                                 WORD32 *ptr_total_persistant) {
255
1.97k
  WORD32 used_persistent = 0;
256
257
1.97k
  if (pstr_esbr_hbe_txposer) {
258
1.97k
    memset(pstr_esbr_hbe_txposer, 0, sizeof(ixheaace_str_esbr_hbe_txposer));
259
260
1.97k
    pstr_esbr_hbe_txposer->core_frame_length = num_aac_samples;
261
262
1.97k
    pstr_esbr_hbe_txposer->no_bins = num_out_samples / IXHEAACE_NUM_QMF_SYNTH_CHANNELS;
263
264
1.97k
    pstr_esbr_hbe_txposer->hbe_qmf_in_len = pstr_esbr_hbe_txposer->no_bins;
265
266
1.97k
    pstr_esbr_hbe_txposer->hbe_qmf_out_len = 2 * pstr_esbr_hbe_txposer->hbe_qmf_in_len;
267
268
1.97k
    pstr_esbr_hbe_txposer->ptr_input_buf = (FLOAT32 *)ptr_persistent_hbe_mem;
269
1.97k
    used_persistent += (num_aac_samples + IXHEAACE_NUM_QMF_SYNTH_CHANNELS) *
270
1.97k
                       sizeof(pstr_esbr_hbe_txposer->ptr_input_buf[0]);
271
272
1.97k
    pstr_esbr_hbe_txposer->upsamp_4_flag = samp_fac_4_flag;
273
274
1.97k
    if (pstr_esbr_hbe_txposer) {
275
1.97k
      pstr_esbr_hbe_txposer->fft_size[0] = num_aac_samples;
276
1.97k
      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
1.97k
      pstr_esbr_hbe_txposer->ptr_spectrum = &pstr_esbr_hbe_txposer->spectrum_buf[0];
294
1.97k
      pstr_esbr_hbe_txposer->ptr_spectrum_tx = &pstr_esbr_hbe_txposer->spectrum_transposed_buf[0];
295
1.97k
      pstr_esbr_hbe_txposer->ptr_mag = &pstr_esbr_hbe_txposer->mag_buf[0];
296
1.97k
      pstr_esbr_hbe_txposer->ptr_phase = &pstr_esbr_hbe_txposer->phase_buf[0];
297
1.97k
      pstr_esbr_hbe_txposer->ptr_output_buf = &pstr_esbr_hbe_txposer->output_buf[0];
298
1.97k
    }
299
1.97k
  }
300
1.97k
  *ptr_total_persistant = used_persistent;
301
1.97k
}
302
303
1.97k
IA_ERRORCODE ixheaace_dft_hbe_data_reinit(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) {
304
1.97k
  WORD32 sfb;
305
1.97k
  WORD32 patch;
306
1.97k
  WORD32 i;
307
1.97k
  WORD32 temp_start;
308
1.97k
  FLOAT32 fb_ratio;
309
1.97k
  WORD32 stop_patch;
310
1.97k
  WORD32 in_hop_size_divisor = 8;
311
1.97k
  static const WORD32 trans_samp[2] = {12, 18}; /* FD transition samples */
312
1.97k
  WORD32 err = IA_NO_ERROR;
313
314
1.97k
  pstr_hbe_txposer->start_band = pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][0];
315
1.97k
  pstr_hbe_txposer->end_band =
316
1.97k
      pstr_hbe_txposer
317
1.97k
          ->ptr_freq_band_tab[IXHEAACE_LOW][pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW]];
318
1.97k
  pstr_hbe_txposer->esbr_hq = 1;
319
320
1.97k
  pstr_hbe_txposer->synth_size = 4 * ((pstr_hbe_txposer->start_band + 4) / 8 + 1);
321
1.97k
  pstr_hbe_txposer->k_start = ixheaac_start_subband2kL_tbl[pstr_hbe_txposer->start_band];
322
323
1.97k
  fb_ratio = pstr_hbe_txposer->synth_size / 32.0f;
324
325
1.97k
  pstr_hbe_txposer->ana_fft_size[0] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[0]);
326
1.97k
  pstr_hbe_txposer->ana_fft_size[1] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[1]);
327
328
1.97k
  pstr_hbe_txposer->in_hop_size = pstr_hbe_txposer->ana_fft_size[0] / in_hop_size_divisor;
329
330
1.97k
  pstr_hbe_txposer->ptr_syn_win = (FLOAT32 *)&pstr_hbe_txposer->synthesis_window_buf[0];
331
1.97k
  pstr_hbe_txposer->ptr_ana_win = (FLOAT32 *)&pstr_hbe_txposer->analysis_window_buf[0];
332
333
1.97k
  err = ixheaace_calc_anal_synth_window(pstr_hbe_txposer->ana_fft_size[0],
334
1.97k
                                        pstr_hbe_txposer->ptr_ana_win);
335
1.97k
  if (err) {
336
0
    return err;
337
0
  }
338
339
1.97k
  memset(pstr_hbe_txposer->synth_buf, 0, sizeof(pstr_hbe_txposer->synth_buf));
340
341
1.97k
  pstr_hbe_txposer->ptr_syn_win_coeff = ixheaace_map_prot_filter(pstr_hbe_txposer->synth_size);
342
343
1.97k
  temp_start = 2 * ((pstr_hbe_txposer->start_band - 1) / 2); /* Largest start band */
344
1.97k
  pstr_hbe_txposer->analy_size =
345
1.97k
      4 * ((min(64, pstr_hbe_txposer->end_band + 1) - temp_start - 1) / 4 +
346
1.97k
           1); /* Quantize in steps of 4 */
347
1.97k
  pstr_hbe_txposer->a_start = temp_start - max(0, temp_start + pstr_hbe_txposer->analy_size - 64);
348
349
1.97k
  fb_ratio = pstr_hbe_txposer->analy_size / 64.0f;
350
351
1.97k
  pstr_hbe_txposer->syn_fft_size[0] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[0]);
352
1.97k
  pstr_hbe_txposer->syn_fft_size[1] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[1]);
353
354
1.97k
  pstr_hbe_txposer->out_hop_size = 2 * pstr_hbe_txposer->syn_fft_size[0] / in_hop_size_divisor;
355
356
1.97k
  err = ixheaace_calc_anal_synth_window(pstr_hbe_txposer->syn_fft_size[0],
357
1.97k
                                        pstr_hbe_txposer->ptr_syn_win);
358
1.97k
  if (err) {
359
0
    return err;
360
0
  }
361
362
1.97k
  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
1.97k
  memset(&pstr_hbe_txposer->x_over_qmf[0], 0, sizeof(pstr_hbe_txposer->x_over_qmf));
367
368
9.88k
  for (i = 0; i < IXHEAACE_MAX_STRETCH; i++) {
369
7.90k
    memset(&pstr_hbe_txposer->x_over_bin[i][0], 0,
370
7.90k
           2 * sizeof(pstr_hbe_txposer->x_over_bin[i][0]));
371
7.90k
  }
372
1.97k
  sfb = 0;
373
1.97k
  stop_patch = IXHEAACE_MAX_STRETCH;
374
375
1.97k
  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
819
    case 12:
385
819
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_12;
386
819
      pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p3;
387
819
      break;
388
797
    case 16:
389
797
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_16;
390
797
      pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2;
391
797
      break;
392
361
    case 20:
393
361
      pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20;
394
361
      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
1.97k
  }
402
403
1.97k
  {
404
1.97k
    WORD32 l, k, L = pstr_hbe_txposer->analy_size;
405
73.3k
    for (k = 0; k < L; k++) {
406
5.40M
      for (l = 0; l < 2 * L; l++) {
407
5.33M
        pstr_hbe_txposer->str_dft_hbe_anal_coeff.real[k][l] =
408
5.33M
            (FLOAT32)cos(PI / (2 * L) *
409
5.33M
                         ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 * pstr_hbe_txposer->a_start));
410
5.33M
        pstr_hbe_txposer->str_dft_hbe_anal_coeff.imag[k][l] =
411
5.33M
            (FLOAT32)sin(PI / (2 * L) *
412
5.33M
                         ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 * pstr_hbe_txposer->a_start));
413
5.33M
      }
414
71.3k
    }
415
1.97k
  }
416
417
6.30k
  for (patch = 1; patch <= stop_patch; patch++) {
418
22.1k
    while (sfb <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW] &&
419
20.1k
           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb] <=
420
20.1k
               patch * pstr_hbe_txposer->start_band)
421
15.8k
      sfb++;
422
6.30k
    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.33k
      if ((patch * pstr_hbe_txposer->start_band -
426
4.33k
           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1]) <= 3) {
427
3.81k
        pstr_hbe_txposer->x_over_qmf[patch - 1] =
428
3.81k
            pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1];
429
3.81k
        if (patch <= IXHEAACE_MAX_STRETCH) {
430
3.81k
          pstr_hbe_txposer->x_over_bin[patch - 1][0] =
431
3.81k
              (WORD32)(pstr_hbe_txposer->fft_size[0] *
432
3.81k
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1] / 128 +
433
3.81k
                       0.5);
434
3.81k
          pstr_hbe_txposer->x_over_bin[patch - 1][1] =
435
3.81k
              (WORD32)(pstr_hbe_txposer->fft_size[1] *
436
3.81k
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1] / 128 +
437
3.81k
                       0.5);
438
3.81k
        }
439
3.81k
      } else {
440
516
        WORD32 sfb_idx = 0;
441
7.66k
        while (sfb_idx <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_HIGH] &&
442
7.66k
               pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx] <=
443
7.66k
                   patch * pstr_hbe_txposer->start_band)
444
7.15k
          sfb_idx++;
445
516
        pstr_hbe_txposer->x_over_qmf[patch - 1] =
446
516
            pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1];
447
516
        if (patch <= IXHEAACE_MAX_STRETCH) {
448
516
          pstr_hbe_txposer->x_over_bin[patch - 1][0] =
449
516
              (WORD32)(pstr_hbe_txposer->fft_size[0] *
450
516
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1] / 128 +
451
516
                       0.5);
452
516
          pstr_hbe_txposer->x_over_bin[patch - 1][1] =
453
516
              (WORD32)(pstr_hbe_txposer->fft_size[1] *
454
516
                           pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1] / 128 +
455
516
                       0.5);
456
516
        }
457
516
      }
458
4.33k
    } else {
459
1.97k
      pstr_hbe_txposer->x_over_qmf[patch - 1] = pstr_hbe_txposer->end_band;
460
1.97k
      if (patch <= IXHEAACE_MAX_STRETCH) {
461
1.97k
        pstr_hbe_txposer->x_over_bin[patch - 1][0] =
462
1.97k
            (WORD32)(pstr_hbe_txposer->fft_size[0] * pstr_hbe_txposer->end_band / 128 + 0.5);
463
1.97k
        pstr_hbe_txposer->x_over_bin[patch - 1][1] =
464
1.97k
            (WORD32)(pstr_hbe_txposer->fft_size[1] * pstr_hbe_txposer->end_band / 128 + 0.5);
465
1.97k
      }
466
1.97k
      pstr_hbe_txposer->max_stretch = min(patch, IXHEAACE_MAX_STRETCH);
467
1.97k
      break;
468
1.97k
    }
469
6.30k
  }
470
471
  /* calculation of frequency domain windows */
472
6.30k
  for (patch = 0; patch < pstr_hbe_txposer->max_stretch - 1; patch++) {
473
12.9k
    for (i = 0; i < 2; i++) {
474
8.66k
      ixheaace_create_dft_hbe_window(pstr_hbe_txposer->fd_win_buf[patch][i],
475
8.66k
                                     pstr_hbe_txposer->x_over_bin[patch][i],
476
8.66k
                                     pstr_hbe_txposer->x_over_bin[patch + 1][i], trans_samp[i],
477
8.66k
                                     pstr_hbe_txposer->fft_size[i]);
478
8.66k
    }
479
4.33k
  }
480
1.97k
  return err;
481
1.97k
}
482
483
static VOID ixheaace_dft_hbe_apply_win(const FLOAT32 *ptr_x, const FLOAT32 *ptr_y, FLOAT32 *ptr_z,
484
286k
                                       WORD32 n) {
485
286k
  WORD32 i;
486
137M
  for (i = 0; i < n; i++) {
487
137M
    ptr_z[i] = ptr_x[i] * ptr_y[i];
488
137M
  }
489
286k
}
490
491
286k
VOID ixheaace_dft_hbe_fft_memmove(FLOAT32 *ptr_spectrum, WORD32 size) {
492
286k
  WORD32 n = 0;
493
494
69.0M
  while (n < size / 2) {
495
68.7M
    FLOAT32 tmp = ptr_spectrum[n];
496
68.7M
    ptr_spectrum[n] = ptr_spectrum[n + size / 2];
497
68.7M
    ptr_spectrum[n + size / 2] = tmp;
498
68.7M
    n++;
499
68.7M
  }
500
286k
}
501
VOID ixheaace_karth2polar(FLOAT32 *ptr_spectrum, FLOAT32 *ptr_mag, FLOAT32 *ptr_phase,
502
143k
                          WORD32 fft_size) {
503
143k
  WORD32 n;
504
505
32.8M
  for (n = 1; n < fft_size / 2; n++) {
506
32.6M
    ptr_phase[n] = (FLOAT32)atan2(ptr_spectrum[2 * n + 1], ptr_spectrum[2 * n]);
507
32.6M
    ptr_mag[n] = (FLOAT32)sqrt(ptr_spectrum[2 * n] * ptr_spectrum[2 * n] +
508
32.6M
                               ptr_spectrum[2 * n + 1] * ptr_spectrum[2 * n + 1]);
509
32.6M
  }
510
511
143k
  if (ptr_spectrum[0] < 0) {
512
0
    ptr_phase[0] = (FLOAT32)acos(-1);
513
0
    ptr_mag[0] = -ptr_spectrum[0];
514
143k
  } else {
515
143k
    ptr_phase[0] = 0;
516
143k
    ptr_mag[0] = ptr_spectrum[0];
517
143k
  }
518
519
143k
  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
143k
  } else {
523
143k
    ptr_phase[fft_size / 2] = 0;
524
143k
    ptr_mag[fft_size / 2] = ptr_spectrum[1];
525
143k
  }
526
143k
}
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
24.9k
IA_ERRORCODE ixheaace_hbe_fft_map(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) {
568
24.9k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
569
24.9k
  WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag];
570
24.9k
  WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag];
571
572
24.9k
  switch (ana_fft_size) {
573
3.00k
    case 576:
574
3.00k
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576;
575
3.00k
      pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_fft_288;
576
3.00k
      break;
577
7.53k
    case 384:
578
7.53k
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_384;
579
7.53k
      pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn_gen;
580
7.53k
      break;
581
10.8k
    case 512:
582
10.8k
      pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
583
10.8k
      pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn;
584
10.8k
      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
3.51k
    default:
590
3.51k
      return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING;
591
0
      break;
592
24.9k
  }
593
594
21.4k
  switch (syn_fft_size) {
595
6.28k
    case 448:
596
6.28k
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_448;
597
6.28k
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_ifft_224;
598
6.28k
      break;
599
8.50k
    case 512:
600
8.50k
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512;
601
8.50k
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_cfftn;
602
8.50k
      break;
603
3.13k
    case 576:
604
3.13k
      pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576;
605
3.13k
      pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_fft_288;
606
3.13k
      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.4k
  }
619
620
17.9k
  return IA_NO_ERROR;
621
21.4k
}
622
623
VOID ia_dft_hbe_apply_polar_t2(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer,
624
143k
                               WORD32 pitch_in_bins, WORD out_transform_size) {
625
143k
  WORD32 tr;
626
143k
  WORD32 ti;
627
143k
  WORD32 m_tr = 0;
628
143k
  WORD32 p, i;
629
143k
  FLOAT32 mag_t;
630
143k
  FLOAT32 phase_t;
631
143k
  FLOAT32 m_val;
632
143k
  FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf;
633
143k
  FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase;
634
143k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
635
143k
  WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag];
636
143k
  FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx;
637
143k
  FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag;
638
  /* pitch_in_bins is given with the resolution of a 1536 point FFT */
639
143k
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
640
143k
  p = (WORD32)p_flt;
641
143k
  FLOAT32 q_thr = 4.0f;
642
643
143k
  if (T < 2) {
644
    // To avoid invalid access by fd_win_buf
645
0
    T = 2;
646
0
  }
647
143k
  i = 0;
648
73.6M
  while (i <= out_transform_size) {
649
73.5M
    WORD32 utk = i;
650
651
73.5M
    mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ptr_mag[utk];
652
653
73.5M
    phase_t = T * ptr_phase[utk];
654
655
73.5M
    if (phase_t == 0.0) {
656
73.5M
      ptr_spectrum_tx[2 * i] += mag_t;
657
73.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
73.5M
    if (p > 0) {
662
62.0M
      m_val = 0;
663
124M
      for (tr = 1; tr < T; tr++) {
664
62.0M
        FLOAT32 temp;
665
62.0M
        ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f);
666
62.0M
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
667
60.7M
        temp = min(ptr_mag[ti], ptr_mag[ti + p]);
668
60.7M
        if (temp > m_val) {
669
0
          m_val = temp;
670
0
          m_tr = tr;
671
0
          utk = ti;
672
0
        }
673
60.7M
      } /* for tr */
674
675
62.0M
      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
62.0M
    }
683
73.5M
    i++;
684
73.5M
  }
685
143k
}
686
687
VOID ia_dft_hbe_apply_polar_t_3(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer,
688
143k
                                WORD32 pitch_in_bins, WORD out_transform_size) {
689
143k
  WORD32 tr;
690
143k
  WORD32 ti;
691
143k
  WORD32 m_tr = 0;
692
143k
  WORD32 p, i;
693
143k
  FLOAT32 mag_t = 0.0f;
694
143k
  FLOAT32 phase_t;
695
143k
  FLOAT32 m_val;
696
143k
  FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf;
697
143k
  FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase;
698
143k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
699
143k
  WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag];
700
143k
  FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx;
701
143k
  FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag;
702
  /* pitch_in_bins is given with the resolution of a 1536 point FFT */
703
143k
  FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f;
704
143k
  p = (WORD32)p_flt;
705
143k
  FLOAT32 q_thr = 4.0f;
706
707
143k
  if (T < 3) {
708
    // To avoid invalid access by fd_win_buf
709
0
    T = 3;
710
0
  }
711
712
143k
  i = 0;
713
73.6M
  while (i <= out_transform_size) {
714
73.5M
    WORD32 utk = 2 * i / T;
715
73.5M
    FLOAT32 ptk = (2.0f * i / T) - utk;
716
73.5M
    FLOAT32 k;
717
718
73.5M
    if (i % 3 == 0) {
719
24.5M
      mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ptr_mag[utk];
720
49.0M
    } else if (i % 3 == 1) {
721
24.5M
      k = (FLOAT32)cbrt(ptr_mag[utk]);
722
24.5M
      mag_t =
723
24.5M
          (*fd_win_buf)[T - 2][oversampling_flag][i] * k * (FLOAT32)pow(ptr_mag[utk + 1], ptk);
724
24.5M
    } else if (i % 3 == 2) {
725
24.5M
      k = (FLOAT32)cbrt(ptr_mag[utk + 1]);
726
24.5M
      mag_t =
727
24.5M
          (*fd_win_buf)[T - 2][oversampling_flag][i] * (FLOAT32)pow(ptr_mag[utk], 1.0 - ptk) * k;
728
24.5M
    }
729
730
73.5M
    phase_t = T * ((1 - ptk) * ptr_phase[utk] + ptk * ptr_phase[utk + 1]);
731
732
73.5M
    ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t);
733
73.5M
    ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t);
734
735
73.5M
    if (p > 0) {
736
62.0M
      m_val = 0;
737
186M
      for (tr = 1; tr < T; tr++) {
738
124M
        FLOAT32 temp;
739
124M
        ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f);
740
124M
        if ((ti < 0) || (ti + p > fft_size / 2)) continue;
741
122M
        temp = min(ptr_mag[ti], ptr_mag[ti + p]);
742
122M
        if (temp > m_val) {
743
0
          m_val = temp;
744
0
          m_tr = tr;
745
0
          utk = ti;
746
0
        }
747
122M
      } /* for tr */
748
749
62.0M
      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
62.0M
    }
771
73.5M
    i++;
772
73.5M
  }
773
143k
}
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
24.9k
                                    FLOAT32 *ptr_dft_hbe_scratch_buf) {
842
24.9k
  WORD32 in_offset = 0;
843
24.9k
  WORD32 out_offset = 0;
844
24.9k
  WORD32 in_hop_size = pstr_hbe_txposer->in_hop_size;
845
24.9k
  WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag;
846
24.9k
  WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag];
847
848
24.9k
  WORD32 out_hop_size = pstr_hbe_txposer->out_hop_size;
849
24.9k
  WORD32 num_in_samples = num_columns * pstr_hbe_txposer->synth_size;
850
24.9k
  WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag];
851
24.9k
  WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag];
852
853
24.9k
  WORD32 ana_pad_size = (ana_fft_size - pstr_hbe_txposer->ana_fft_size[0]) / 2;
854
24.9k
  WORD32 syn_pad_size = (syn_fft_size - pstr_hbe_txposer->syn_fft_size[0]) / 2;
855
856
24.9k
  FLOAT32 *ptr_input_buf = pstr_hbe_txposer->ptr_input_buf;
857
24.9k
  FLOAT32 *ptr_output_buf = pstr_hbe_txposer->ptr_output_buf;
858
24.9k
  FLOAT32 *ptr_spectrum = pstr_hbe_txposer->ptr_spectrum;
859
24.9k
  FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx;
860
24.9k
  FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag;
861
24.9k
  FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase;
862
24.9k
  WORD32 i, T;
863
24.9k
  FLOAT32 *ptr_cos_fft;
864
24.9k
  FLOAT32 *ptr_cos_ifft;
865
866
24.9k
  WORD32 ana_fft_offset = pstr_hbe_txposer->k_start * fft_size / 32;
867
24.9k
  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
24.9k
  WORD32 err_code = IA_NO_ERROR;
870
871
24.9k
  memcpy(pstr_hbe_txposer->ptr_input_buf,
872
24.9k
         pstr_hbe_txposer->ptr_input_buf + pstr_hbe_txposer->ana_fft_size[0],
873
24.9k
         pstr_hbe_txposer->ana_fft_size[0] * sizeof(pstr_hbe_txposer->ptr_input_buf[0]));
874
875
24.9k
  err_code = ixheaace_real_synth_filt(pstr_hbe_txposer, num_columns, qmf_buf_real, qmf_buf_imag);
876
24.9k
  if (err_code) {
877
0
    return err_code;
878
0
  }
879
880
24.9k
  memcpy(ptr_output_buf, ptr_output_buf + 2 * pstr_hbe_txposer->syn_fft_size[0],
881
24.9k
         2 * pstr_hbe_txposer->syn_fft_size[0] * sizeof(ptr_output_buf[0]));
882
883
24.9k
  memset(ptr_output_buf + 2 * pstr_hbe_txposer->syn_fft_size[0], 0,
884
24.9k
         2 * pstr_hbe_txposer->syn_fft_size[0] * sizeof(ptr_output_buf[0]));
885
886
24.9k
  err_code = ixheaace_hbe_fft_map(pstr_hbe_txposer);
887
24.9k
  if (err_code) {
888
7.02k
    return err_code;
889
7.02k
  }
890
891
161k
  while (in_offset < num_in_samples) {
892
143k
    memset(ptr_spectrum, 0, fft_size * sizeof(ptr_spectrum[0]));
893
143k
    memset(ptr_spectrum_tx, 0, ((fft_size + 2) * sizeof(ptr_spectrum_tx[0])));
894
895
143k
    memset(ptr_mag, 0, (fft_size / 2 + 2) * sizeof(ptr_mag[0]));
896
143k
    memset(ptr_phase, 0, (fft_size / 2 + 2) * sizeof(ptr_phase[0]));
897
143k
    ixheaace_dft_hbe_apply_win(ptr_input_buf + in_offset, pstr_hbe_txposer->ptr_ana_win,
898
143k
                               ptr_spectrum + ana_pad_size + ana_fft_offset,
899
143k
                               pstr_hbe_txposer->ana_fft_size[0]);
900
143k
    ixheaace_dft_hbe_fft_memmove(ptr_spectrum + ana_fft_offset, ana_fft_size);
901
143k
    {
902
143k
      WORD32 len = ana_fft_size;
903
143k
      ptr_cos_fft = pstr_hbe_txposer->ptr_ana_cos_sin_tab;
904
143k
      FLOAT32 *ptr_fft_data = ptr_spectrum + ana_fft_offset;
905
143k
      FLOAT32 tmp1, tmp2, tmp3, tmp4;
906
143k
      (*(pstr_hbe_txposer->ixheaace_hbe_anal_fft))(ptr_fft_data, ptr_dft_hbe_scratch_buf, len / 2,
907
143k
                                                   -1);
908
143k
      tmp1 = ptr_fft_data[0] + ptr_fft_data[1];
909
143k
      ptr_fft_data[1] = ptr_fft_data[0] - ptr_fft_data[1];
910
143k
      ptr_fft_data[0] = tmp1;
911
912
143k
      i = 1;
913
16.5M
      while (i <= (len / 4 + (len % 4) / 2)) {
914
16.4M
        tmp1 = ptr_fft_data[2 * i] - ptr_fft_data[len - 2 * i];
915
16.4M
        tmp2 = ptr_fft_data[2 * i + 1] + ptr_fft_data[len - 2 * i + 1];
916
917
16.4M
        tmp3 = (*(ptr_cos_fft)) * tmp1 - (*(ptr_cos_fft + 1)) * tmp2;
918
16.4M
        tmp4 = (*(ptr_cos_fft + 1)) * tmp1 + (*(ptr_cos_fft)) * tmp2;
919
920
16.4M
        ptr_cos_fft = ptr_cos_fft + 2;
921
922
16.4M
        tmp1 = ptr_fft_data[2 * i] + ptr_fft_data[len - 2 * i];
923
16.4M
        tmp2 = ptr_fft_data[2 * i + 1] - ptr_fft_data[len - 2 * i + 1];
924
925
16.4M
        ptr_fft_data[2 * i + 0] = 0.5f * (tmp1 - tmp3);
926
16.4M
        ptr_fft_data[2 * i + 1] = 0.5f * (tmp2 - tmp4);
927
16.4M
        ptr_fft_data[len - 2 * i + 0] = 0.5f * (tmp1 + tmp3);
928
16.4M
        ptr_fft_data[len - 2 * i + 1] = -0.5f * (tmp2 + tmp4);
929
16.4M
        ++i;
930
16.4M
      }
931
143k
    }
932
143k
    ixheaace_karth2polar(ptr_spectrum + ana_fft_offset, ptr_mag + ana_fft_offset / 2,
933
143k
                         ptr_phase + ana_fft_offset / 2, ana_fft_size);
934
935
429k
    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
286k
      WORD32 out_transform_size;
939
940
      /* 0<i<fft_size/2 */
941
286k
      out_transform_size = (fft_size / 2);
942
286k
      switch (T) {
943
143k
        case 2:
944
143k
          ia_dft_hbe_apply_polar_t2(T, pstr_hbe_txposer, pitch_in_bins, out_transform_size);
945
143k
          break;
946
143k
        case 3:
947
143k
          ia_dft_hbe_apply_polar_t_3(T, pstr_hbe_txposer, pitch_in_bins, out_transform_size);
948
143k
          break;
949
0
        default:
950
0
          ia_dft_hbe_apply_polar_t(T, pstr_hbe_txposer, pitch_in_bins, out_transform_size);
951
286k
      }
952
286k
    } /* for T */
953
954
143k
    ptr_spectrum_tx[syn_fft_offset + 1] =
955
143k
        ptr_spectrum_tx[syn_fft_offset + syn_fft_size]; /* Move Nyquist bin to bin 1 for RFFTN */
956
957
143k
    {
958
143k
      WORD32 len = syn_fft_size;
959
143k
      ptr_cos_ifft = pstr_hbe_txposer->ptr_syn_cos_sin_tab;
960
143k
      FLOAT32 *ptr_fft_data = ptr_spectrum_tx + syn_fft_offset;
961
143k
      FLOAT32 tmp1, tmp2, tmp3, tmp4;
962
963
143k
      FLOAT32 scale = 1.0f / len;
964
143k
      tmp1 = ptr_fft_data[0] + ptr_fft_data[1];
965
143k
      ptr_fft_data[1] = scale * (ptr_fft_data[0] - ptr_fft_data[1]);
966
143k
      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
143k
      (*(pstr_hbe_txposer->ixheaace_hbe_synth_ifft))(ptr_fft_data, ptr_dft_hbe_scratch_buf,
987
143k
                                                     len / 2, 1);
988
143k
    }
989
990
143k
    ixheaace_dft_hbe_fft_memmove(ptr_spectrum_tx + syn_fft_offset, syn_fft_size);
991
143k
    ixheaace_dft_hbe_apply_win(
992
143k
        ptr_spectrum_tx + syn_pad_size + syn_fft_offset, pstr_hbe_txposer->ptr_syn_win,
993
143k
        ptr_spectrum_tx + syn_pad_size + syn_fft_offset, pstr_hbe_txposer->syn_fft_size[0]);
994
995
71.9M
    for (i = 0; i < pstr_hbe_txposer->syn_fft_size[0]; i++) {
996
71.7M
      ptr_output_buf[out_offset + i] += ptr_spectrum_tx[syn_pad_size + syn_fft_offset + i];
997
71.7M
    }
998
999
143k
    in_offset += in_hop_size;
1000
143k
    out_offset += out_hop_size;
1001
1002
143k
  } /* while(in_offset<num_in_samples) */
1003
1004
17.9k
  ixheaace_dft_hbe_cplx_anal_filt(pstr_hbe_txposer, pv_qmf_buf_real, pv_qmf_buf_imag);
1005
1006
17.9k
  return err_code;
1007
17.9k
}