/src/libxaac/encoder/ixheaace_hybrid.c
Line | Count | Source (jump to first uncovered line) |
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 <string.h> |
22 | | |
23 | | #include "ixheaac_type_def.h" |
24 | | #include "ixheaac_error_standards.h" |
25 | | #include "ixheaace_error_codes.h" |
26 | | #include "ixheaace_common_rom.h" |
27 | | #include "ixheaace_sbr_def.h" |
28 | | #include "ixheaace_resampler.h" |
29 | | #include "ixheaace_sbr_rom.h" |
30 | | #include "ixheaace_sbr_hybrid.h" |
31 | | |
32 | | #include "ixheaace_aac_constants.h" |
33 | | |
34 | | VOID ia_enhaacplus_enc_fft(complex *out, WORD32 N, ixheaace_common_tables *); |
35 | | |
36 | | static VOID ixheaace_four_chan_filtering(const FLOAT32 *ptr_qmf_real, const FLOAT32 *ptr_qmf_imag, |
37 | | FLOAT32 **ptr_hyb_real, FLOAT32 **ptr_hyb_imag, |
38 | | WORD32 ch_offset, const FLOAT32 *ptr_p4_13, |
39 | 97.0k | ixheaace_common_tables *pstr_common_tab) { |
40 | 97.0k | WORD32 i, k, n; |
41 | 97.0k | WORD32 mid_tap = IXHEAACE_HYBRID_FILTER_DELAY; |
42 | | |
43 | 97.0k | FLOAT32 cum[8], *ptr_cum; |
44 | 97.0k | FLOAT32 tmp1, tmp2, tmp_p4; |
45 | 97.0k | FLOAT32 real, imag; |
46 | 97.0k | const FLOAT32 *ptr_re, *ptr_im; |
47 | 97.0k | FLOAT32 *ptr_hy_im, *ptr_hy_re; |
48 | 97.0k | ptr_re = &ptr_qmf_real[0]; |
49 | 97.0k | ptr_im = &ptr_qmf_imag[0]; |
50 | 97.0k | ptr_hy_re = &ptr_hyb_real[0][ch_offset]; |
51 | 97.0k | ptr_hy_im = &ptr_hyb_imag[0][ch_offset]; |
52 | | |
53 | 3.20M | for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) { |
54 | 3.10M | real = imag = 0; |
55 | 15.5M | for (k = 0; k < 16; k += 4) { |
56 | 12.4M | tmp_p4 = ptr_p4_13[k]; |
57 | 12.4M | tmp1 = ptr_re[k]; |
58 | 12.4M | tmp2 = ptr_im[k]; |
59 | | |
60 | 12.4M | tmp1 = tmp_p4 * tmp1; |
61 | 12.4M | real = real - tmp1; |
62 | | |
63 | 12.4M | tmp1 = tmp_p4 * tmp2; |
64 | 12.4M | imag = imag + tmp1; |
65 | 12.4M | } |
66 | | |
67 | 3.10M | cum[3] = imag; |
68 | 3.10M | cum[2] = real; |
69 | 3.10M | real = imag = 0; |
70 | | |
71 | 12.4M | for (k = 3; k < 15; k += 4) { |
72 | 9.31M | tmp_p4 = ptr_p4_13[k]; |
73 | 9.31M | tmp1 = ptr_re[k]; |
74 | 9.31M | tmp2 = ptr_im[k]; |
75 | 9.31M | tmp1 = tmp_p4 * tmp1; |
76 | 9.31M | real = real + tmp1; |
77 | 9.31M | tmp1 = tmp_p4 * tmp2; |
78 | 9.31M | imag = imag + tmp1; |
79 | 9.31M | } |
80 | | |
81 | 3.10M | tmp1 = imag + real; |
82 | 3.10M | cum[7] = tmp1 * IXHEAACE_COS_PI_BY_4; |
83 | 3.10M | tmp1 = imag - real; |
84 | 3.10M | cum[6] = tmp1 * IXHEAACE_COS_PI_BY_4; |
85 | | |
86 | 3.10M | cum[1] = ptr_p4_13[mid_tap] * ptr_re[mid_tap]; |
87 | 3.10M | cum[0] = ptr_p4_13[mid_tap] * ptr_im[mid_tap]; |
88 | | |
89 | 3.10M | real = imag = 0; |
90 | | |
91 | 12.4M | for (k = 1; k < 13; k += 4) { |
92 | 9.31M | tmp_p4 = ptr_p4_13[k]; |
93 | 9.31M | tmp1 = ptr_re[k]; |
94 | 9.31M | tmp2 = ptr_im[k]; |
95 | 9.31M | tmp1 = tmp_p4 * tmp1; |
96 | 9.31M | real = real + tmp1; |
97 | 9.31M | tmp1 = tmp_p4 * tmp2; |
98 | 9.31M | imag = imag + tmp1; |
99 | 9.31M | } |
100 | | |
101 | 3.10M | tmp1 = real - imag; |
102 | 3.10M | cum[5] = tmp1 * IXHEAACE_COS_PI_BY_4; |
103 | 3.10M | tmp1 = real + imag; |
104 | 3.10M | cum[4] = tmp1 * IXHEAACE_COS_PI_BY_4; |
105 | | |
106 | 3.10M | ia_enhaacplus_enc_fft((complex *)cum, 4, pstr_common_tab); |
107 | | |
108 | 3.10M | ptr_cum = &cum[0]; |
109 | | |
110 | 15.5M | for (n = 3; n >= 0; n--) { |
111 | 12.4M | tmp1 = *ptr_cum++; |
112 | 12.4M | tmp2 = *ptr_cum++; |
113 | 12.4M | *ptr_hy_im++ = tmp1; |
114 | 12.4M | *ptr_hy_re++ = tmp2; |
115 | 12.4M | } |
116 | 3.10M | ptr_re++; |
117 | 3.10M | ptr_im++; |
118 | 3.10M | ptr_hy_re += IXHEAACE_QMF_TIME_SLOTS - 4; |
119 | 3.10M | ptr_hy_im += IXHEAACE_QMF_TIME_SLOTS - 4; |
120 | 3.10M | } |
121 | 97.0k | } |
122 | | |
123 | | static VOID ixheaace_eight_chan_filtering(const FLOAT32 *ptr_qmf_real, |
124 | | const FLOAT32 *ptr_qmf_imag, FLOAT32 **ptr_hyb_real, |
125 | | FLOAT32 **ptr_hyb_imag, const FLOAT32 *ptr_p8_13, |
126 | | ixheaace_common_tables *pstr_common_tab) |
127 | | |
128 | 48.5k | { |
129 | 48.5k | LOOPINDEX i, n; |
130 | 48.5k | LOOPINDEX mid_tap = IXHEAACE_HYBRID_FILTER_DELAY; |
131 | 48.5k | FLOAT32 real, imag; |
132 | 48.5k | FLOAT32 cum[16], *ptr_cum; |
133 | 48.5k | FLOAT32 tmp1, tmp2, tmp3; |
134 | 48.5k | const FLOAT32 *ptr_re, *ptr_im; |
135 | 48.5k | FLOAT32 *ptr_hy_re, *ptr_hy_im; |
136 | 48.5k | ptr_re = &ptr_qmf_real[0]; |
137 | 48.5k | ptr_im = &ptr_qmf_imag[0]; |
138 | 48.5k | ptr_hy_re = &ptr_hyb_real[0][0]; |
139 | 48.5k | ptr_hy_im = &ptr_hyb_imag[0][0]; |
140 | | |
141 | 1.60M | for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) { |
142 | 1.55M | tmp1 = ptr_p8_13[4] * ptr_re[4]; |
143 | 1.55M | tmp2 = ptr_p8_13[12] * ptr_re[12]; |
144 | | |
145 | 1.55M | tmp3 = ptr_im[4]; |
146 | 1.55M | real = tmp1 + tmp2; |
147 | 1.55M | tmp2 = ptr_im[12]; |
148 | 1.55M | tmp1 = ptr_p8_13[4] * tmp3; |
149 | 1.55M | tmp2 = ptr_p8_13[12] * tmp2; |
150 | 1.55M | imag = tmp1 + tmp2; |
151 | | |
152 | 1.55M | tmp1 = imag - real; |
153 | 1.55M | cum[5] = tmp1 * IXHEAACE_COS_PI_BY_4; |
154 | | |
155 | 1.55M | tmp1 = imag + real; |
156 | 1.55M | tmp3 = ptr_re[3]; |
157 | 1.55M | cum[4] = -tmp1 * IXHEAACE_COS_PI_BY_4; |
158 | 1.55M | tmp2 = ptr_re[11]; |
159 | 1.55M | tmp1 = ptr_p8_13[3] * tmp3; |
160 | 1.55M | tmp2 = ptr_p8_13[11] * tmp2; |
161 | 1.55M | tmp3 = ptr_im[3]; |
162 | 1.55M | real = tmp1 + tmp2; |
163 | 1.55M | tmp2 = ptr_im[11]; |
164 | 1.55M | tmp1 = ptr_p8_13[3] * tmp3; |
165 | 1.55M | tmp2 = ptr_p8_13[11] * tmp2; |
166 | 1.55M | imag = tmp1 + tmp2; |
167 | | |
168 | 1.55M | tmp1 = imag * IXHEAACE_COS_PI_BY_8; |
169 | 1.55M | tmp2 = real * IXHEAACE_SIN_PI_BY_8; |
170 | 1.55M | cum[13] = tmp1 - tmp2; |
171 | | |
172 | 1.55M | tmp1 = imag * IXHEAACE_SIN_PI_BY_8; |
173 | 1.55M | tmp2 = real * IXHEAACE_COS_PI_BY_8; |
174 | 1.55M | tmp3 = ptr_re[2]; |
175 | 1.55M | cum[12] = -tmp1 - tmp2; |
176 | 1.55M | tmp2 = ptr_re[10]; |
177 | 1.55M | tmp1 = ptr_p8_13[2] * tmp3; |
178 | 1.55M | tmp2 = ptr_p8_13[10] * tmp2; |
179 | 1.55M | tmp3 = ptr_im[2]; |
180 | 1.55M | cum[2] = -tmp1 - tmp2; |
181 | 1.55M | tmp2 = ptr_im[10]; |
182 | 1.55M | tmp1 = ptr_p8_13[2] * tmp3; |
183 | 1.55M | tmp2 = ptr_p8_13[10] * tmp2; |
184 | 1.55M | cum[3] = tmp1 + tmp2; |
185 | | |
186 | 1.55M | tmp1 = ptr_p8_13[1] * ptr_re[1]; |
187 | 1.55M | tmp2 = ptr_p8_13[9] * ptr_re[9]; |
188 | 1.55M | real = tmp1 + tmp2; |
189 | | |
190 | 1.55M | tmp1 = ptr_p8_13[1] * ptr_im[1]; |
191 | 1.55M | tmp2 = ptr_p8_13[9] * ptr_im[9]; |
192 | 1.55M | imag = tmp1 + tmp2; |
193 | | |
194 | 1.55M | tmp1 = imag * IXHEAACE_COS_PI_BY_8; |
195 | 1.55M | tmp2 = real * IXHEAACE_SIN_PI_BY_8; |
196 | 1.55M | cum[11] = tmp1 + tmp2; |
197 | | |
198 | 1.55M | tmp1 = imag * IXHEAACE_SIN_PI_BY_8; |
199 | 1.55M | tmp2 = real * IXHEAACE_COS_PI_BY_8; |
200 | 1.55M | cum[10] = tmp1 - tmp2; |
201 | | |
202 | 1.55M | tmp1 = ptr_p8_13[0] * ptr_re[0]; |
203 | 1.55M | tmp2 = ptr_p8_13[8] * ptr_re[8]; |
204 | 1.55M | real = tmp1 + tmp2; |
205 | | |
206 | 1.55M | tmp1 = ptr_p8_13[0] * ptr_im[0]; |
207 | 1.55M | tmp2 = ptr_p8_13[8] * ptr_im[8]; |
208 | 1.55M | imag = tmp1 + tmp2; |
209 | | |
210 | 1.55M | tmp1 = imag + real; |
211 | 1.55M | cum[7] = tmp1 * IXHEAACE_COS_PI_BY_4; |
212 | | |
213 | 1.55M | tmp1 = imag - real; |
214 | 1.55M | cum[6] = tmp1 * IXHEAACE_COS_PI_BY_4; |
215 | | |
216 | 1.55M | real = ptr_p8_13[7] * ptr_re[7]; |
217 | 1.55M | imag = ptr_p8_13[7] * ptr_im[7]; |
218 | | |
219 | 1.55M | tmp1 = imag * IXHEAACE_SIN_PI_BY_8; |
220 | 1.55M | tmp2 = real * IXHEAACE_COS_PI_BY_8; |
221 | 1.55M | cum[15] = tmp1 + tmp2; |
222 | | |
223 | 1.55M | tmp1 = imag * IXHEAACE_COS_PI_BY_8; |
224 | 1.55M | tmp2 = real * IXHEAACE_SIN_PI_BY_8; |
225 | 1.55M | cum[14] = tmp1 - tmp2; |
226 | | |
227 | 1.55M | cum[1] = ptr_p8_13[mid_tap] * ptr_re[mid_tap]; |
228 | 1.55M | cum[0] = ptr_p8_13[mid_tap] * ptr_im[mid_tap]; |
229 | | |
230 | 1.55M | real = ptr_p8_13[5] * ptr_re[5]; |
231 | 1.55M | imag = ptr_p8_13[5] * ptr_im[5]; |
232 | | |
233 | 1.55M | tmp1 = real * IXHEAACE_COS_PI_BY_8; |
234 | 1.55M | tmp2 = imag * IXHEAACE_SIN_PI_BY_8; |
235 | 1.55M | cum[9] = tmp1 - tmp2; |
236 | | |
237 | 1.55M | tmp1 = real * IXHEAACE_SIN_PI_BY_8; |
238 | 1.55M | tmp2 = imag * IXHEAACE_COS_PI_BY_8; |
239 | 1.55M | cum[8] = tmp1 + tmp2; |
240 | | |
241 | 1.55M | ia_enhaacplus_enc_fft((complex *)cum, 8, pstr_common_tab); |
242 | | |
243 | 1.55M | ptr_cum = &cum[0]; |
244 | | |
245 | 13.9M | for (n = 7; n >= 0; n--) { |
246 | 12.4M | tmp1 = *ptr_cum++; |
247 | 12.4M | tmp2 = *ptr_cum++; |
248 | 12.4M | *ptr_hy_im++ = tmp1; |
249 | 12.4M | *ptr_hy_re++ = tmp2; |
250 | 12.4M | } |
251 | 1.55M | ptr_re++; |
252 | 1.55M | ptr_im++; |
253 | 1.55M | ptr_hy_re += IXHEAACE_QMF_TIME_SLOTS - 8; |
254 | 1.55M | ptr_hy_im += IXHEAACE_QMF_TIME_SLOTS - 8; |
255 | 1.55M | } |
256 | 48.5k | } |
257 | | |
258 | | IA_ERRORCODE ixheaace_hybrid_analysis(const FLOAT32 **ptr_qmf_real_in, |
259 | | const FLOAT32 **ptr_qmf_imag_in, FLOAT32 **ptr_hyb_real_in, |
260 | | FLOAT32 **ptr_hyb_imag_in, ixheaace_pstr_hybrid pstr_hybrid, |
261 | | ixheaace_str_ps_tab *pstr_ps_tab, |
262 | 48.5k | ixheaace_common_tables *pstr_common_tab) { |
263 | 48.5k | WORD32 band, i; |
264 | 48.5k | ixheaace_hybrid_res hybrid_res; |
265 | 48.5k | WORD32 ch_offset = 0; |
266 | | |
267 | 48.5k | FLOAT32 *ptr_re, *ptr_im; |
268 | 48.5k | const FLOAT32 *ptr_qmf_real, *ptr_qmf_imag; |
269 | 48.5k | FLOAT32 tmp1, tmp2; |
270 | | |
271 | 194k | for (band = 0; band < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; band++) { |
272 | 145k | hybrid_res = (ixheaace_hybrid_res)pstr_ps_tab->a_hyb_res[band]; |
273 | | |
274 | 145k | memcpy(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_qmf_buf_real[band], |
275 | 145k | IXHEAACE_QMF_BUFFER_MOVE * sizeof(FLOAT32)); |
276 | 145k | memcpy(pstr_hybrid->ptr_work_imag, pstr_hybrid->ptr_qmf_buf_imag[band], |
277 | 145k | IXHEAACE_QMF_BUFFER_MOVE * sizeof(FLOAT32)); |
278 | 145k | ptr_re = &pstr_hybrid->ptr_work_real[IXHEAACE_QMF_BUFFER_MOVE]; |
279 | 145k | ptr_im = &pstr_hybrid->ptr_work_imag[IXHEAACE_QMF_BUFFER_MOVE]; |
280 | 145k | ptr_qmf_real = &ptr_qmf_real_in[0][band]; |
281 | 145k | ptr_qmf_imag = &ptr_qmf_imag_in[0][band]; |
282 | | |
283 | 4.80M | for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) { |
284 | 4.65M | tmp1 = *ptr_qmf_real; |
285 | 4.65M | tmp2 = *ptr_qmf_imag; |
286 | | |
287 | 4.65M | ptr_qmf_real += IXHEAACE_QMF_CHANNELS; |
288 | 4.65M | ptr_qmf_imag += IXHEAACE_QMF_CHANNELS; |
289 | | |
290 | 4.65M | *ptr_im++ = tmp2; |
291 | 4.65M | *ptr_re++ = tmp1; |
292 | 4.65M | } |
293 | | |
294 | 145k | ptr_re = &pstr_hybrid->ptr_qmf_buf_real[band][0]; |
295 | 145k | ptr_im = &pstr_hybrid->ptr_qmf_buf_imag[band][0]; |
296 | | |
297 | 145k | ptr_qmf_real = &ptr_qmf_real_in[IXHEAACE_QMF_TIME_SLOTS - IXHEAACE_QMF_BUFFER_MOVE][band]; |
298 | 145k | ptr_qmf_imag = &ptr_qmf_imag_in[IXHEAACE_QMF_TIME_SLOTS - IXHEAACE_QMF_BUFFER_MOVE][band]; |
299 | | |
300 | 1.89M | for (i = 0; i < IXHEAACE_QMF_BUFFER_MOVE; i++) { |
301 | 1.74M | tmp1 = *ptr_qmf_real; |
302 | 1.74M | ptr_qmf_real += IXHEAACE_QMF_CHANNELS; |
303 | 1.74M | tmp2 = *ptr_qmf_imag; |
304 | 1.74M | ptr_qmf_imag += IXHEAACE_QMF_CHANNELS; |
305 | 1.74M | *ptr_re++ = tmp1; |
306 | 1.74M | *ptr_im++ = tmp2; |
307 | 1.74M | } |
308 | | |
309 | 145k | switch (hybrid_res) { |
310 | 97.0k | case IXHEAACE_HYBRID_4_CPLX: |
311 | 97.0k | ixheaace_four_chan_filtering(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_work_imag, |
312 | 97.0k | ptr_hyb_real_in, ptr_hyb_imag_in, ch_offset, |
313 | 97.0k | pstr_ps_tab->p4_13, pstr_common_tab); |
314 | 97.0k | break; |
315 | 48.5k | case IXHEAACE_HYBRID_8_CPLX: |
316 | 48.5k | ixheaace_eight_chan_filtering(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_work_imag, |
317 | 48.5k | ptr_hyb_real_in, ptr_hyb_imag_in, pstr_ps_tab->p8_13, |
318 | 48.5k | pstr_common_tab); |
319 | 48.5k | break; |
320 | 0 | default: |
321 | 0 | return IA_EXHEAACE_EXE_FATAL_PS_INVALID_HYBRID_RES_VAL; |
322 | 0 | break; |
323 | 145k | } |
324 | 145k | ch_offset += hybrid_res; |
325 | 145k | } |
326 | 48.5k | return IA_NO_ERROR; |
327 | 48.5k | } |
328 | | |
329 | | VOID ixheaace_hybrid_synthesis(const FLOAT32 **ptr_hybrid_real_flt, |
330 | | const FLOAT32 **ptr_hybrid_imag_flt, FLOAT32 **ptr_qmf_real_flt, |
331 | 24.2k | FLOAT32 **ptr_qmf_imag_flt, const WORD32 *ptr_hyb_res) { |
332 | 24.2k | WORD32 k, n, band; |
333 | 24.2k | ixheaace_hybrid_res hybrid_res; |
334 | 24.2k | WORD32 ch_offset = 0; |
335 | | |
336 | 24.2k | FLOAT32 temp1, temp2; |
337 | 24.2k | FLOAT32 *ptr_qmf_real; |
338 | 24.2k | FLOAT32 *ptr_qmf_imag; |
339 | | |
340 | 97.0k | for (band = 0; band < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; band++) { |
341 | 72.7k | const FLOAT32 *ptr_hybrid_real = &ptr_hybrid_real_flt[0][ch_offset]; |
342 | 72.7k | const FLOAT32 *ptr_hybrid_imag = &ptr_hybrid_imag_flt[0][ch_offset]; |
343 | | |
344 | 72.7k | hybrid_res = (ixheaace_hybrid_res)ptr_hyb_res[band]; |
345 | | |
346 | 72.7k | ptr_qmf_real = &ptr_qmf_real_flt[0][band]; |
347 | 72.7k | ptr_qmf_imag = &ptr_qmf_imag_flt[0][band]; |
348 | | |
349 | 2.40M | for (n = 0; n < IXHEAACE_QMF_TIME_SLOTS; n++) { |
350 | 2.32M | FLOAT32 temo_real = 0, temo_imag = 0; |
351 | | |
352 | 14.7M | for (k = hybrid_res - 1; k >= 0; k--) { |
353 | 12.4M | temp1 = *ptr_hybrid_real++; |
354 | 12.4M | temp2 = *ptr_hybrid_imag++; |
355 | 12.4M | temo_real += temp1; |
356 | 12.4M | temo_imag += temp2; |
357 | 12.4M | } |
358 | | |
359 | 2.32M | ptr_hybrid_real += IXHEAACE_QMF_TIME_SLOTS - hybrid_res; |
360 | 2.32M | ptr_hybrid_imag += IXHEAACE_QMF_TIME_SLOTS - hybrid_res; |
361 | | |
362 | 2.32M | *ptr_qmf_real = temo_real; |
363 | 2.32M | ptr_qmf_real += IXHEAACE_QMF_CHANNELS; |
364 | | |
365 | 2.32M | *ptr_qmf_imag = temo_imag; |
366 | 2.32M | ptr_qmf_imag += IXHEAACE_QMF_CHANNELS; |
367 | 2.32M | } |
368 | 72.7k | ch_offset += hybrid_res; |
369 | 72.7k | } |
370 | 24.2k | } |