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