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