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