/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 | } |