/src/libxaac/encoder/ixheaace_sbr_hbe_polyphase.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 | | #include "ixheaac_type_def.h" |
21 | | #include "ixheaace_bitbuffer.h" |
22 | | #include "ixheaac_error_standards.h" |
23 | | #include "ixheaace_error_codes.h" |
24 | | |
25 | | #include "iusace_tns_usac.h" |
26 | | #include "iusace_cnst.h" |
27 | | #include "ixheaace_sbr_def.h" |
28 | | #include "ixheaace_resampler.h" |
29 | | #include "ixheaace_sbr_hbe.h" |
30 | | #include "ixheaace_sbr_hbe_fft.h" |
31 | | #include "ixheaac_esbr_rom.h" |
32 | | #include <string.h> |
33 | | |
34 | 109k | IA_ERRORCODE ixheaace_complex_anal_filt(ixheaace_str_esbr_hbe_txposer *ptr_hbe_txposer) { |
35 | 109k | WORD32 idx; |
36 | 109k | WORD32 anal_size = 2 * ptr_hbe_txposer->synth_size; |
37 | 109k | WORD32 N = (10 * anal_size); |
38 | | |
39 | 109k | WORD32 no_bins = ptr_hbe_txposer->no_bins >> 1; |
40 | | |
41 | 109k | if (ptr_hbe_txposer->esbr_hq != 0) { |
42 | 0 | anal_size = 2 * ptr_hbe_txposer->analy_size; |
43 | 0 | no_bins = ptr_hbe_txposer->no_bins; |
44 | 0 | } |
45 | | |
46 | 109k | idx = 0; |
47 | 2.49M | while (idx < no_bins) { |
48 | 2.38M | WORD32 i, j, k, l; |
49 | 2.38M | FLOAT32 window_output[640] = {0}; |
50 | 2.38M | FLOAT32 u[128] = {0}, u_in[256] = {0}, u_out[256] = {0}; |
51 | 2.38M | FLOAT32 accu_r, accu_i; |
52 | 2.38M | const FLOAT32 *ptr_inp_signal; |
53 | 2.38M | FLOAT32 *ptr_anal_buf; |
54 | | |
55 | 2.38M | FLOAT32 *ptr_analy_cos_sin_tab = ptr_hbe_txposer->ptr_analy_cos_sin_tab; |
56 | 2.38M | const FLOAT32 *ptr_interp_window_coeff = ptr_hbe_txposer->ptr_ana_win_coeff; |
57 | 2.38M | FLOAT32 *ptr_x = ptr_hbe_txposer->analy_buf; |
58 | | |
59 | 2.38M | if (ptr_hbe_txposer->esbr_hq != 0) { |
60 | 0 | memset(ptr_hbe_txposer->qmf_in_buf[idx], 0, sizeof(ptr_hbe_txposer->qmf_in_buf[idx])); |
61 | 0 | ptr_inp_signal = ptr_hbe_txposer->ptr_output_buf + idx * ptr_hbe_txposer->analy_size + 1; |
62 | 0 | ptr_anal_buf = &ptr_hbe_txposer->qmf_in_buf[idx][4 * ptr_hbe_txposer->a_start]; |
63 | 2.38M | } else { |
64 | 2.38M | memset(ptr_hbe_txposer->qmf_in_buf[idx + IXHEAACE_HBE_OPER_WIN_LEN - 1], 0, |
65 | 2.38M | sizeof(ptr_hbe_txposer->qmf_in_buf[idx + IXHEAACE_HBE_OPER_WIN_LEN - 1])); |
66 | | |
67 | 2.38M | ptr_inp_signal = ptr_hbe_txposer->ptr_input_buf + idx * 2 * ptr_hbe_txposer->synth_size + 1; |
68 | 2.38M | ptr_anal_buf = |
69 | 2.38M | &ptr_hbe_txposer |
70 | 2.38M | ->qmf_in_buf[idx + IXHEAACE_HBE_OPER_WIN_LEN - 1][4 * ptr_hbe_txposer->k_start]; |
71 | 2.38M | } |
72 | | |
73 | 618M | for (i = N - 1; i >= anal_size; i--) { |
74 | 616M | ptr_x[i] = ptr_x[i - anal_size]; |
75 | 616M | } |
76 | | |
77 | 70.8M | for (i = anal_size - 1; i >= 0; i--) { |
78 | 68.4M | ptr_x[i] = ptr_inp_signal[anal_size - 1 - i]; |
79 | 68.4M | } |
80 | | |
81 | 687M | for (i = 0; i < N; i++) { |
82 | 684M | window_output[i] = ptr_x[i] * ptr_interp_window_coeff[i]; |
83 | 684M | } |
84 | | |
85 | 139M | for (i = 0; i < 2 * anal_size; i++) { |
86 | 136M | accu_r = 0.0; |
87 | 821M | for (j = 0; j < 5; j++) { |
88 | 684M | accu_r = accu_r + window_output[i + j * 2 * anal_size]; |
89 | 684M | } |
90 | 136M | u[i] = accu_r; |
91 | 136M | } |
92 | 2.38M | if (anal_size == 40 || anal_size == 56) { |
93 | 11.8M | for (i = 1; i < anal_size; i++) { |
94 | 11.5M | FLOAT32 temp1 = u[i] + u[2 * anal_size - i]; |
95 | 11.5M | FLOAT32 temp2 = u[i] - u[2 * anal_size - i]; |
96 | 11.5M | u[i] = temp1; |
97 | 11.5M | u[2 * anal_size - i] = temp2; |
98 | 11.5M | } |
99 | | |
100 | 295k | k = 0; |
101 | 12.1M | while (k < anal_size) { |
102 | 11.8M | accu_r = u[anal_size]; |
103 | 11.8M | if (k & 1) |
104 | 5.90M | accu_i = u[0]; |
105 | 5.90M | else |
106 | 5.90M | accu_i = -u[0]; |
107 | 472M | for (l = 1; l < anal_size; l++) { |
108 | 460M | accu_r = accu_r + u[0 + l] * ptr_analy_cos_sin_tab[2 * l + 0]; |
109 | 460M | accu_i = accu_i + u[2 * anal_size - l] * ptr_analy_cos_sin_tab[2 * l + 1]; |
110 | 460M | } |
111 | 11.8M | ptr_analy_cos_sin_tab += (2 * anal_size); |
112 | 11.8M | *ptr_anal_buf++ = (FLOAT32)accu_r; |
113 | 11.8M | *ptr_anal_buf++ = (FLOAT32)accu_i; |
114 | 11.8M | k++; |
115 | 11.8M | } |
116 | 2.08M | } else { |
117 | 2.08M | FLOAT32 *ptr_u = u_in; |
118 | 2.08M | FLOAT32 *ptr_v = u_out; |
119 | 115M | for (k = 0; k < anal_size * 2; k++) { |
120 | 113M | *ptr_u++ = ((*ptr_analy_cos_sin_tab++) * u[k]); |
121 | 113M | *ptr_u++ = ((*ptr_analy_cos_sin_tab++) * u[k]); |
122 | 113M | } |
123 | 2.08M | if (ptr_hbe_txposer->ixheaace_cmplx_anal_fft != NULL) { |
124 | 2.08M | (*(ptr_hbe_txposer->ixheaace_cmplx_anal_fft))(u_in, u_out, anal_size * 2); |
125 | 2.08M | } else { |
126 | 0 | return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_FFT; |
127 | 0 | } |
128 | | |
129 | 30.4M | for (k = 0; k < anal_size / 2; k++) { |
130 | 28.3M | *(ptr_anal_buf + 1) = -*ptr_v++; |
131 | 28.3M | *ptr_anal_buf = *ptr_v++; |
132 | | |
133 | 28.3M | ptr_anal_buf += 2; |
134 | | |
135 | 28.3M | *(ptr_anal_buf + 1) = *ptr_v++; |
136 | 28.3M | *ptr_anal_buf = -*ptr_v++; |
137 | | |
138 | 28.3M | ptr_anal_buf += 2; |
139 | 28.3M | } |
140 | 2.08M | } |
141 | 2.38M | idx++; |
142 | 2.38M | } |
143 | 109k | return IA_NO_ERROR; |
144 | 109k | } |
145 | | |
146 | | IA_ERRORCODE ixheaace_real_synth_filt(ixheaace_str_esbr_hbe_txposer *ptr_hbe_txposer, |
147 | | WORD32 num_columns, FLOAT32 qmf_buf_real[][64], |
148 | 136k | FLOAT32 qmf_buf_imag[][64]) { |
149 | 136k | WORD32 i, j, k, l, idx; |
150 | 136k | FLOAT32 g[640]; |
151 | 136k | FLOAT32 w[640]; |
152 | 136k | FLOAT32 synth_out[128]; |
153 | 136k | FLOAT32 accu_r; |
154 | 136k | WORD32 synth_size = ptr_hbe_txposer->synth_size; |
155 | 136k | FLOAT32 *ptr_cos_tab_trans_qmf = |
156 | 136k | (FLOAT32 *)&ixheaac_cos_table_trans_qmf[0][0] + ptr_hbe_txposer->k_start * 32; |
157 | 136k | FLOAT32 *ptr_buffer = ptr_hbe_txposer->synth_buf; |
158 | 136k | FLOAT32 *ptr_inp_buf = ptr_hbe_txposer->ptr_input_buf + ptr_hbe_txposer->ana_fft_size[0]; |
159 | | |
160 | 5.84M | for (idx = 0; idx < num_columns; idx++) { |
161 | 5.70M | FLOAT32 loc_qmf_buf[64]; |
162 | 5.70M | FLOAT32 *ptr_synth_buf_r = loc_qmf_buf; |
163 | 5.70M | FLOAT32 *ptr_out_buf; |
164 | 5.70M | if (ptr_hbe_txposer->esbr_hq == 1) { |
165 | 0 | ptr_out_buf = ptr_inp_buf + (idx - 1) * ptr_hbe_txposer->synth_size; |
166 | 5.70M | } else { |
167 | 5.70M | ptr_out_buf = ptr_hbe_txposer->ptr_input_buf + (idx + 1) * ptr_hbe_txposer->synth_size; |
168 | 5.70M | } |
169 | | |
170 | 5.70M | FLOAT32 *ptr_synth_cos_tab = ptr_hbe_txposer->ptr_syn_cos_tab; |
171 | 5.70M | const FLOAT32 *ptr_interp_window_coeff = ptr_hbe_txposer->ptr_syn_win_coeff; |
172 | 5.70M | if (ptr_hbe_txposer->k_start < 0) { |
173 | 0 | return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_START_BAND; |
174 | 0 | } |
175 | | |
176 | 5.70M | k = 0; |
177 | 87.6M | while (k < synth_size) { |
178 | 81.9M | WORD32 ki = ptr_hbe_txposer->k_start + k; |
179 | 81.9M | ptr_synth_buf_r[k] = (FLOAT32)(ptr_cos_tab_trans_qmf[(k << 1) + 0] * qmf_buf_real[idx][ki] + |
180 | 81.9M | ptr_cos_tab_trans_qmf[(k << 1) + 1] * qmf_buf_imag[idx][ki]); |
181 | | |
182 | 81.9M | ptr_synth_buf_r[k + ptr_hbe_txposer->synth_size] = 0; |
183 | 81.9M | k++; |
184 | 81.9M | } |
185 | | |
186 | 1.48G | for (l = (20 * synth_size - 1); l >= 2 * synth_size; l--) { |
187 | 1.47G | ptr_buffer[l] = ptr_buffer[l - 2 * synth_size]; |
188 | 1.47G | } |
189 | | |
190 | 5.70M | if (synth_size == 20) { |
191 | 719k | FLOAT32 *ptr_psynth_cos_tab = ptr_synth_cos_tab; |
192 | | |
193 | 15.8M | for (l = 0; l < (synth_size + 1); l++) { |
194 | 15.1M | accu_r = 0.0; |
195 | 317M | for (k = 0; k < synth_size; k++) { |
196 | 302M | accu_r += ptr_synth_buf_r[k] * ptr_psynth_cos_tab[k]; |
197 | 302M | } |
198 | 15.1M | ptr_buffer[0 + l] = accu_r; |
199 | 15.1M | ptr_buffer[synth_size - l] = accu_r; |
200 | 15.1M | ptr_psynth_cos_tab = ptr_psynth_cos_tab + synth_size; |
201 | 15.1M | } |
202 | 7.19M | for (l = (synth_size + 1); l < (2 * synth_size - synth_size / 2); l++) { |
203 | 6.47M | accu_r = 0.0; |
204 | 135M | for (k = 0; k < synth_size; k++) { |
205 | 129M | accu_r += ptr_synth_buf_r[k] * ptr_psynth_cos_tab[k]; |
206 | 129M | } |
207 | 6.47M | ptr_buffer[0 + l] = accu_r; |
208 | 6.47M | ptr_buffer[3 * synth_size - l] = -accu_r; |
209 | 6.47M | ptr_psynth_cos_tab = ptr_psynth_cos_tab + synth_size; |
210 | 6.47M | } |
211 | 719k | accu_r = 0.0; |
212 | 15.1M | for (k = 0; k < synth_size; k++) { |
213 | 14.3M | accu_r += ptr_synth_buf_r[k] * ptr_psynth_cos_tab[k]; |
214 | 14.3M | } |
215 | 719k | ptr_buffer[3 * synth_size >> 1] = accu_r; |
216 | 4.98M | } else { |
217 | 4.98M | FLOAT32 tmp; |
218 | 4.98M | FLOAT32 *ptr_u = synth_out; |
219 | 4.98M | WORD32 kmax = (synth_size >> 1); |
220 | 4.98M | FLOAT32 *ptr_syn_buf = &ptr_buffer[kmax]; |
221 | 4.98M | kmax += synth_size; |
222 | | |
223 | 4.98M | if (ptr_hbe_txposer->ixheaace_real_synth_fft != NULL) { |
224 | 4.98M | (*(ptr_hbe_txposer->ixheaace_real_synth_fft))(ptr_synth_buf_r, synth_out, synth_size * 2); |
225 | 4.98M | } else { |
226 | 0 | return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_FFT; |
227 | 0 | } |
228 | | |
229 | 106M | for (k = 0; k < kmax; k++) { |
230 | 101M | tmp = ((*ptr_u++) * (*ptr_synth_cos_tab++)); |
231 | 101M | tmp -= ((*ptr_u++) * (*ptr_synth_cos_tab++)); |
232 | 101M | *ptr_syn_buf++ = tmp; |
233 | 101M | } |
234 | | |
235 | 4.98M | ptr_syn_buf = &ptr_buffer[0]; |
236 | 4.98M | kmax -= synth_size; |
237 | | |
238 | 38.7M | for (k = 0; k < kmax; k++) { |
239 | 33.7M | tmp = ((*ptr_u++) * (*ptr_synth_cos_tab++)); |
240 | 33.7M | tmp -= ((*ptr_u++) * (*ptr_synth_cos_tab++)); |
241 | 33.7M | *ptr_syn_buf++ = tmp; |
242 | 33.7M | } |
243 | 4.98M | } |
244 | | |
245 | 34.2M | for (i = 0; i < 5; i++) { |
246 | 28.5M | memcpy(&g[(2 * i + 0) * synth_size], &ptr_buffer[(4 * i + 0) * synth_size], |
247 | 28.5M | sizeof(g[0]) * synth_size); |
248 | 28.5M | memcpy(&g[(2 * i + 1) * synth_size], &ptr_buffer[(4 * i + 3) * synth_size], |
249 | 28.5M | sizeof(g[0]) * synth_size); |
250 | 28.5M | } |
251 | | |
252 | 825M | for (k = 0; k < 10 * synth_size; k++) { |
253 | 819M | w[k] = g[k] * ptr_interp_window_coeff[k]; |
254 | 819M | } |
255 | | |
256 | 87.6M | for (i = 0; i < synth_size; i++) { |
257 | 81.9M | accu_r = 0.0; |
258 | 901M | for (j = 0; j < 10; j++) { |
259 | 819M | accu_r = accu_r + w[synth_size * j + i]; |
260 | 819M | } |
261 | 81.9M | ptr_out_buf[i] = (FLOAT32)accu_r; |
262 | 81.9M | } |
263 | 5.70M | } |
264 | 136k | return IA_NO_ERROR; |
265 | 136k | } |
266 | | |
267 | | VOID ixheaace_dft_hbe_cplx_anal_filt(ixheaace_str_esbr_hbe_txposer *ptr_hbe_txposer, |
268 | 19.2k | FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64]) { |
269 | 19.2k | WORD32 idx; |
270 | | |
271 | 19.2k | WORD32 anal_size = ptr_hbe_txposer->analy_size; |
272 | | |
273 | 19.2k | WORD32 N = (10 * ptr_hbe_txposer->analy_size); |
274 | | |
275 | 19.2k | idx = 0; |
276 | 634k | while (idx < ptr_hbe_txposer->no_bins) { |
277 | 615k | WORD32 i, j, k, l; |
278 | 615k | FLOAT32 window_output[640] = {0}; |
279 | 615k | FLOAT32 u[128] = {0}; |
280 | 615k | FLOAT32 accu_r, accu_i; |
281 | 615k | const FLOAT32 *ptr_inp_signal; |
282 | 615k | FLOAT32 *ptr_qmf_buf_r = &qmf_buf_real[idx][ptr_hbe_txposer->a_start]; |
283 | 615k | FLOAT32 *ptr_qmf_buf_i = &qmf_buf_imag[idx][ptr_hbe_txposer->a_start]; |
284 | | |
285 | 615k | const FLOAT32 *ptr_interp_window_coeff = ptr_hbe_txposer->ptr_ana_win_coeff; |
286 | 615k | FLOAT32 *ptr_x = ptr_hbe_txposer->analy_buf; |
287 | | |
288 | 615k | memset(&qmf_buf_real[idx][ptr_hbe_txposer->a_start], 0, |
289 | 615k | (IXHEAACE_NUM_QMF_SYNTH_CHANNELS - ptr_hbe_txposer->a_start) * |
290 | 615k | sizeof(qmf_buf_real[idx][ptr_hbe_txposer->a_start])); |
291 | 615k | memset(&qmf_buf_imag[idx][ptr_hbe_txposer->a_start], 0, |
292 | 615k | IXHEAACE_TWICE_QMF_SYNTH_CH_NUM * sizeof(qmf_buf_imag[idx][ptr_hbe_txposer->a_start])); |
293 | | |
294 | 615k | ptr_inp_signal = ptr_hbe_txposer->ptr_output_buf + idx * ptr_hbe_txposer->analy_size + 1; |
295 | | |
296 | 169M | for (i = N - 1; i >= anal_size; i--) { |
297 | 169M | ptr_x[i] = ptr_x[i - anal_size]; |
298 | 169M | } |
299 | | |
300 | 19.4M | for (i = anal_size - 1; i >= 0; i--) { |
301 | 18.8M | ptr_x[i] = ptr_inp_signal[anal_size - 1 - i]; |
302 | 18.8M | } |
303 | | |
304 | 188M | for (i = 0; i < N; i++) { |
305 | 188M | window_output[i] = ptr_x[i] * ptr_interp_window_coeff[i]; |
306 | 188M | } |
307 | | |
308 | 38.2M | for (i = 0; i < 2 * anal_size; i++) { |
309 | 37.6M | accu_r = 0.0; |
310 | 225M | for (j = 0; j < 5; j++) { |
311 | 188M | accu_r = accu_r + window_output[i + j * 2 * anal_size]; |
312 | 188M | } |
313 | 37.6M | u[i] = accu_r; |
314 | 37.6M | } |
315 | | |
316 | 19.4M | for (k = 0; k < anal_size; k++) { |
317 | 18.8M | accu_r = 0; |
318 | 18.8M | accu_i = 0; |
319 | 1.17G | for (l = 0; l < 2 * anal_size; l++) { |
320 | 1.16G | accu_r = accu_r + u[l] * ptr_hbe_txposer->str_dft_hbe_anal_coeff.real[k][l]; |
321 | 1.16G | accu_i = accu_i + u[l] * ptr_hbe_txposer->str_dft_hbe_anal_coeff.imag[k][l]; |
322 | 1.16G | } |
323 | 18.8M | ptr_qmf_buf_r[k] = (FLOAT32)accu_r; |
324 | 18.8M | ptr_qmf_buf_i[k] = (FLOAT32)accu_i; |
325 | 18.8M | } |
326 | | |
327 | 615k | idx++; |
328 | 615k | } |
329 | 19.2k | } |