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 <string.h>
21 #include "ixheaacd_sbr_common.h"
22 #include "ixheaac_type_def.h"
23
24 #include "ixheaac_constants.h"
25 #include "ixheaac_basic_ops32.h"
26 #include "ixheaac_basic_ops16.h"
27 #include "ixheaac_basic_ops40.h"
28 #include "ixheaac_basic_ops.h"
29
30 #include "ixheaacd_intrinsics.h"
31 #include "ixheaacd_common_rom.h"
32 #include "ixheaacd_bitbuffer.h"
33 #include "ixheaacd_sbrdecsettings.h"
34 #include "ixheaacd_sbr_scale.h"
35 #include "ixheaacd_lpp_tran.h"
36 #include "ixheaacd_env_extr_part.h"
37 #include "ixheaacd_sbr_rom.h"
38 #include "ixheaacd_hybrid.h"
39 #include "ixheaacd_ps_dec.h"
40 #include "ixheaacd_env_extr.h"
41 #include "ixheaacd_qmf_dec.h"
42
43 #include "ixheaac_basic_op.h"
44 #include "ixheaacd_env_calc.h"
45
46 #include "ixheaacd_interface.h"
47 #include "ixheaacd_function_selector.h"
48 #include "ixheaacd_audioobjtypes.h"
49
50 #define DCT3_LEN (32)
51 #define DCT2_LEN (64)
52
53 #define LP_SHIFT_VAL 7
54 #define HQ_SHIFT_64 4
55 #define RADIXSHIFT 1
56 #define ROUNDING_SPECTRA 1
57 #define HQ_SHIFT_VAL 4
58
59 extern const WORD32 ixheaacd_ldmps_polyphase_filter_coeff_fix[1280];
60
ixheaacd_dct3_32(WORD32 * input,WORD32 * output,const WORD16 * main_twidle_fwd,const WORD16 * post_tbl,const WORD16 * w_16,const WORD32 * p_table)61 VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output,
62 const WORD16 *main_twidle_fwd, const WORD16 *post_tbl,
63 const WORD16 *w_16, const WORD32 *p_table) {
64 WORD32 n, k;
65
66 WORD32 temp1[6];
67 WORD32 temp2[4];
68 WORD16 twid_re, twid_im;
69 WORD32 *ptr_reverse, *ptr_forward, *p_out, *ptr_out1;
70 const WORD16 *twidle_fwd, *twidle_rev;
71
72 ptr_forward = &input[49];
73 ptr_reverse = &input[47];
74
75 p_out = output;
76 twidle_fwd = main_twidle_fwd;
77 twidle_fwd += 4;
78
79 *p_out++ = input[48] >> LP_SHIFT_VAL;
80 *p_out++ = 0;
81
82 for (n = 1; n < DCT3_LEN / 2; n++) {
83 temp1[0] = *ptr_forward++;
84 temp1[1] = *ptr_reverse--;
85 temp1[0] = ixheaac_add32_sat(ixheaac_shr32(temp1[0], LP_SHIFT_VAL),
86 ixheaac_shr32(temp1[1], LP_SHIFT_VAL));
87
88 temp1[2] = *(ptr_forward - 33);
89 temp1[3] = *(ptr_reverse - 31);
90 temp1[1] = ixheaac_sub32_sat(ixheaac_shr32(temp1[2], LP_SHIFT_VAL),
91 ixheaac_shr32(temp1[3], LP_SHIFT_VAL));
92 twid_re = *twidle_fwd++;
93
94 twid_im = *twidle_fwd;
95 twidle_fwd += 3;
96
97 *p_out++ = ixheaac_add32_sat(ixheaac_mult32x16in32(temp1[0], twid_re),
98 ixheaac_mult32x16in32(temp1[1], twid_im));
99 *p_out++ = ixheaac_sub32_sat(ixheaac_mult32x16in32(temp1[0], twid_im),
100 ixheaac_mult32x16in32(temp1[1], twid_re));
101 }
102
103 twid_re = *twidle_fwd++;
104
105 twid_im = *twidle_fwd;
106 twidle_fwd += 3;
107
108 temp1[1] = *ptr_reverse--;
109 temp1[0] = *(ptr_reverse - 31);
110 temp1[1] = ixheaac_sub32_sat(ixheaac_shr32(temp1[1], LP_SHIFT_VAL),
111 ixheaac_shr32(temp1[0], LP_SHIFT_VAL));
112
113 temp1[0] = temp1[1];
114
115 temp2[2] = ixheaac_add32_sat(ixheaac_mult32x16in32(temp1[0], twid_re),
116 ixheaac_mult32x16in32(temp1[1], twid_im));
117 temp2[3] = ixheaac_sub32_sat(ixheaac_mult32x16in32(temp1[0], twid_im),
118 ixheaac_mult32x16in32(temp1[1], twid_re));
119
120 ptr_forward = output;
121 ptr_reverse = &output[DCT3_LEN - 1];
122
123 temp2[0] = *ptr_forward++;
124 temp2[1] = *ptr_forward--;
125
126 temp1[0] = ixheaac_negate32_sat(ixheaac_add32_sat(temp2[1], temp2[3]));
127 temp1[1] = ixheaac_sub32_sat(temp2[0], temp2[2]);
128 temp2[0] =
129 ixheaac_add32_sat(ixheaac_add32_sat(temp2[0], temp2[2]), temp1[0]);
130 temp2[1] =
131 ixheaac_add32_sat(ixheaac_sub32_sat(temp2[1], temp2[3]), temp1[1]);
132
133 temp2[0] >>= 1;
134 temp2[1] >>= 1;
135
136 *ptr_forward++ = temp2[0];
137 *ptr_forward++ = temp2[1];
138
139 twidle_fwd = post_tbl + 2;
140 twidle_rev = post_tbl + 14;
141
142 for (n = 1; n < DCT3_LEN / 4; n++) {
143 temp2[0] = *ptr_forward++;
144 temp2[1] = *ptr_forward--;
145 temp2[3] = *ptr_reverse--;
146 temp2[2] = *ptr_reverse++;
147
148 twid_re = *twidle_rev;
149 twidle_rev -= 2;
150 twid_im = *twidle_fwd;
151 twidle_fwd += 2;
152
153 temp1[0] = ixheaac_sub32_sat(temp2[0], temp2[2]);
154 temp1[1] = ixheaac_add32_sat(temp2[0], temp2[2]);
155
156 temp1[2] = ixheaac_add32_sat(temp2[1], temp2[3]);
157 temp1[3] = ixheaac_sub32_sat(temp2[1], temp2[3]);
158
159 temp1[4] = ixheaac_add32_sat(ixheaac_mult32x16in32(temp1[0], twid_re),
160 ixheaac_mult32x16in32(temp1[2], twid_im));
161 temp1[5] = ixheaac_sub32_sat(ixheaac_mult32x16in32(temp1[0], twid_im),
162 ixheaac_mult32x16in32(temp1[2], twid_re));
163
164 temp1[1] >>= 1;
165 temp1[3] >>= 1;
166
167 *ptr_forward++ = ixheaac_sub32_sat(temp1[1], temp1[4]);
168 *ptr_forward++ = ixheaac_add32_sat(temp1[3], temp1[5]);
169
170 *ptr_reverse-- = ixheaac_sub32_sat(temp1[5], temp1[3]);
171 *ptr_reverse-- = ixheaac_add32_sat(temp1[1], temp1[4]);
172 }
173 temp2[0] = *ptr_forward++;
174 temp2[1] = *ptr_forward--;
175 temp2[3] = *ptr_reverse--;
176 temp2[2] = *ptr_reverse++;
177
178 twid_re = -*twidle_rev;
179 twidle_rev -= 2;
180 twid_im = *twidle_fwd;
181 twidle_fwd += 2;
182
183 temp1[0] = ixheaac_sub32_sat(temp2[0], temp2[2]);
184 temp1[1] = ixheaac_add32_sat(temp2[0], temp2[2]);
185
186 temp1[2] = ixheaac_add32_sat(temp2[1], temp2[3]);
187 temp1[3] = ixheaac_sub32_sat(temp2[1], temp2[3]);
188
189 temp1[4] = ixheaac_sub32_sat(ixheaac_mult32x16in32(temp1[0], twid_re),
190 ixheaac_mult32x16in32(temp1[2], twid_im));
191 temp1[5] = ixheaac_add32_sat(ixheaac_mult32x16in32(temp1[2], twid_re),
192 ixheaac_mult32x16in32(temp1[0], twid_im));
193
194 temp1[1] >>= 1;
195 temp1[3] >>= 1;
196 *ptr_forward++ = ixheaac_add32_sat(temp1[1], temp1[4]);
197 *ptr_forward++ = ixheaac_add32_sat(temp1[3], temp1[5]);
198
199 ixheaacd_radix4bfly(w_16, output, 1, 4);
200 ixheaacd_postradixcompute4(input, output, p_table, 16);
201
202 output[0] = input[0];
203 output[2] = input[1];
204
205 p_out = input + 2;
206 ptr_forward = output + 1;
207 ptr_reverse = output + 30;
208 ptr_out1 = input + 18;
209
210 for (k = (DCT3_LEN / 4) - 1; k != 0; k--) {
211 WORD32 tempre, tempim;
212
213 tempre = *p_out++;
214 tempim = *p_out++;
215 *ptr_forward = (tempim);
216 ptr_forward += 2;
217 *ptr_forward = (tempre);
218 ptr_forward += 2;
219
220 tempre = *ptr_out1++;
221 tempim = *ptr_out1++;
222 *ptr_reverse = (tempim);
223 ptr_reverse -= 2;
224 *ptr_reverse = (tempre);
225 ptr_reverse -= 2;
226 }
227
228 {
229 WORD32 tempre, tempim;
230 tempre = *p_out++;
231 tempim = *p_out++;
232 *ptr_forward = (tempim);
233 ptr_forward += 2;
234 *ptr_forward = (tempre);
235 ptr_forward += 2;
236 }
237
238 return;
239 }
ixheaacd_dct2_64(WORD32 * x,WORD32 * X,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD16 * filter_states)240 VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X,
241 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
242 WORD16 *filter_states) {
243 ixheaacd_pretwdct2(x, X);
244
245 ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x,
246 qmf_dec_tables_ptr->dig_rev_table2_128,
247 qmf_dec_tables_ptr->dig_rev_table2_128,
248 qmf_dec_tables_ptr->dig_rev_table2_128,
249 qmf_dec_tables_ptr->dig_rev_table2_128);
250
251 ixheaacd_fftposttw(x, qmf_dec_tables_ptr);
252
253 ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr);
254
255 return;
256 }
257
ixheaacd_cos_sin_mod(WORD32 * subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,WORD16 * p_twiddle,WORD32 * p_dig_rev_tbl)258 VOID ixheaacd_cos_sin_mod(WORD32 *subband,
259 ia_sbr_qmf_filter_bank_struct *qmf_bank,
260 WORD16 *p_twiddle, WORD32 *p_dig_rev_tbl) {
261 WORD32 M = ixheaac_shr32(qmf_bank->no_channels, 1);
262
263 const WORD16 *p_sin;
264 const WORD16 *p_sin_cos = &qmf_bank->cos_twiddle[0];
265 WORD32 subband_tmp[128];
266
267 ixheaacd_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp);
268
269 if (M == 32) {
270 ixheaacd_sbr_imdct_using_fft(
271 (const WORD32 *)p_twiddle, 32, subband_tmp, subband,
272 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
273 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
274
275 ixheaacd_sbr_imdct_using_fft(
276 (const WORD32 *)p_twiddle, 32, &subband_tmp[64], &subband[64],
277 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
278 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
279
280 } else {
281 ixheaacd_sbr_imdct_using_fft(
282 (const WORD32 *)p_twiddle, 16, subband_tmp, subband,
283 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
284 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
285
286 ixheaacd_sbr_imdct_using_fft(
287 (const WORD32 *)p_twiddle, 16, &subband_tmp[64], &subband[64],
288 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
289 (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
290 }
291
292 p_sin = &qmf_bank->alt_sin_twiddle[0];
293 ixheaacd_cos_sin_mod_loop2(subband, p_sin, M);
294 }
295
ixheaacd_fwd_modulation(const WORD32 * p_time_in1,WORD32 * real_subband,WORD32 * imag_subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD32 ld_mps_flag)296 VOID ixheaacd_fwd_modulation(const WORD32 *p_time_in1, WORD32 *real_subband,
297 WORD32 *imag_subband,
298 ia_sbr_qmf_filter_bank_struct *qmf_bank,
299 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
300 WORD32 ld_mps_flag) {
301 WORD32 i;
302 const WORD32 *p_time_in2 = &p_time_in1[2 * qmf_bank->no_channels - 1];
303 WORD32 temp1, temp2;
304 WORD32 *t_real_subband = real_subband;
305 WORD32 *t_imag_subband = imag_subband;
306 const WORD16 *tcos;
307
308 for (i = qmf_bank->no_channels - 1; i >= 0; i--) {
309 temp1 = ixheaac_shr32(*p_time_in1++, HQ_SHIFT_VAL);
310 temp2 = ixheaac_shr32(*p_time_in2--, HQ_SHIFT_VAL);
311
312 *t_real_subband++ = ixheaac_sub32_sat(temp1, temp2);
313 ;
314 *t_imag_subband++ = ixheaac_add32_sat(temp1, temp2);
315 ;
316 }
317
318 ixheaacd_cos_sin_mod(real_subband, qmf_bank,
319 (WORD16 *)qmf_dec_tables_ptr->w1024,
320 (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128);
321
322 tcos = qmf_bank->t_cos;
323
324 if (ld_mps_flag == 0) {
325 for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) {
326 WORD16 cosh, sinh;
327 WORD32 re, im;
328
329 re = *real_subband;
330 im = *imag_subband;
331 cosh = *tcos++;
332 sinh = *tcos++;
333 *real_subband++ =
334 ixheaac_add32_sat(ixheaac_mult32x16in32_shl(re, cosh),
335 ixheaac_mult32x16in32_shl(im, sinh));
336 *imag_subband++ =
337 ixheaac_sub32_sat(ixheaac_mult32x16in32_shl(im, cosh),
338 ixheaac_mult32x16in32_shl(re, sinh));
339 }
340 } else {
341 WORD32 i_band;
342 for (i = 0; i < min(64, qmf_bank->no_channels); i += 2) {
343 i_band = real_subband[i];
344 real_subband[i] = -imag_subband[i];
345 imag_subband[i] = i_band;
346
347 i_band = -real_subband[i + 1];
348 real_subband[i + 1] = imag_subband[i + 1];
349 imag_subband[i + 1] = i_band;
350 }
351 }
352 }
353
ixheaacd_cplx_anal_qmffilt(const WORD16 * time_sample_buf,ia_sbr_scale_fact_struct * sbr_scale_factor,WORD32 ** qmf_real,WORD32 ** qmf_imag,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD32 ch_fac,WORD32 low_pow_flag,WORD audio_object_type)354 VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf,
355 ia_sbr_scale_fact_struct *sbr_scale_factor, WORD32 **qmf_real,
356 WORD32 **qmf_imag, ia_sbr_qmf_filter_bank_struct *qmf_bank,
357 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, WORD32 ch_fac,
358 WORD32 low_pow_flag, WORD audio_object_type) {
359 WORD32 i, k;
360 WORD32 num_time_slots = qmf_bank->num_time_slots;
361
362 WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS];
363 WORD16 *filter_states = qmf_bank->core_samples_buffer;
364
365 WORD16 *fp1, *fp2, *tmp;
366
367 WORD16 *filter_1;
368 WORD16 *filter_2;
369 WORD16 *filt_ptr;
370 if (audio_object_type != AOT_ER_AAC_ELD &&
371 audio_object_type != AOT_ER_AAC_LD) {
372 qmf_bank->filter_pos +=
373 (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff);
374 qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c;
375 } else {
376 qmf_bank->filter_pos +=
377 (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff);
378 qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3;
379 }
380
381 filter_1 = qmf_bank->filter_pos;
382
383 if (audio_object_type != AOT_ER_AAC_ELD &&
384 audio_object_type != AOT_ER_AAC_LD) {
385 filter_2 = filter_1 + 64;
386 } else {
387 filter_2 = filter_1 + 32;
388 }
389
390 sbr_scale_factor->st_lb_scale = 0;
391 sbr_scale_factor->lb_scale = -10;
392 if (!low_pow_flag) {
393 if (audio_object_type != AOT_ER_AAC_ELD &&
394 audio_object_type != AOT_ER_AAC_LD) {
395 sbr_scale_factor->lb_scale = -8;
396 } else {
397 sbr_scale_factor->lb_scale = -9;
398 }
399 qmf_bank->cos_twiddle =
400 (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32;
401 qmf_bank->alt_sin_twiddle =
402 (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32;
403 if (audio_object_type != AOT_ER_AAC_ELD &&
404 audio_object_type != AOT_ER_AAC_LD) {
405 qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32;
406 } else {
407 qmf_bank->t_cos =
408 (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld;
409 }
410 }
411
412 fp1 = qmf_bank->anal_filter_states;
413 fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS;
414
415 if (audio_object_type == AOT_ER_AAC_ELD ||
416 audio_object_type == AOT_ER_AAC_LD) {
417 filter_2 = qmf_bank->filter_2;
418 fp1 = qmf_bank->fp1_anal;
419 fp2 = qmf_bank->fp2_anal;
420 }
421
422 for (i = 0; i < num_time_slots; i++) {
423 for (k = 0; k < NO_ANALYSIS_CHANNELS; k++)
424 filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k];
425
426 if (audio_object_type != AOT_ER_AAC_ELD &&
427 audio_object_type != AOT_ER_AAC_LD) {
428 ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2,
429 analysis_buffer, filter_states,
430 time_sample_buf, ch_fac);
431 }
432
433 else {
434 ixheaacd_sbr_qmfanal32_winadd_eld(fp1, fp2, filter_1, filter_2,
435 analysis_buffer);
436 }
437
438 time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac;
439
440 filter_states -= NO_ANALYSIS_CHANNELS;
441 if (filter_states < qmf_bank->anal_filter_states) {
442 filter_states = qmf_bank->anal_filter_states + 288;
443 }
444
445 tmp = fp1;
446 fp1 = fp2;
447 fp2 = tmp;
448 if (audio_object_type != AOT_ER_AAC_ELD &&
449 audio_object_type != AOT_ER_AAC_LD) {
450 filter_1 += 64;
451 filter_2 += 64;
452 } else {
453 filter_1 += 32;
454 filter_2 += 32;
455 }
456
457 filt_ptr = filter_1;
458 filter_1 = filter_2;
459 filter_2 = filt_ptr;
460 if (audio_object_type != AOT_ER_AAC_ELD &&
461 audio_object_type != AOT_ER_AAC_LD) {
462 if (filter_2 > (qmf_bank->analy_win_coeff + 640)) {
463 filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
464 filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64;
465 }
466 } else {
467 if (filter_2 > (qmf_bank->analy_win_coeff + 320)) {
468 filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
469 filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32;
470 }
471 }
472
473 if (!low_pow_flag) {
474 ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i], qmf_bank,
475 qmf_dec_tables_ptr, 0);
476 } else {
477 ixheaacd_dct3_32(
478 (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw,
479 qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16,
480 qmf_dec_tables_ptr->dig_rev_table4_16);
481 }
482 }
483
484 qmf_bank->filter_pos = filter_1;
485 qmf_bank->core_samples_buffer = filter_states;
486
487 if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD)
488
489 {
490 qmf_bank->fp1_anal = fp1;
491 qmf_bank->fp2_anal = fp2;
492 qmf_bank->filter_2 = filter_2;
493 }
494 }
495
ixheaacd_cplx_anal_qmffilt_32(const WORD32 * time_sample_buf,ia_sbr_scale_fact_struct * sbr_scale_factor,WORD32 ** qmf_real,WORD32 ** qmf_imag,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD32 ch_fac,WORD32 ldsbr_present)496 VOID ixheaacd_cplx_anal_qmffilt_32(const WORD32 *time_sample_buf,
497 ia_sbr_scale_fact_struct *sbr_scale_factor,
498 WORD32 **qmf_real, WORD32 **qmf_imag,
499 ia_sbr_qmf_filter_bank_struct *qmf_bank,
500 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
501 WORD32 ch_fac, WORD32 ldsbr_present) {
502 WORD32 i, k;
503 WORD32 num_time_slots = qmf_bank->num_time_slots;
504
505 WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS];
506 WORD32 *filter_states = qmf_bank->core_samples_buffer_32;
507
508 WORD32 *fp1, *fp2, *tmp;
509
510 WORD32 *filter_1;
511 WORD32 *filter_2;
512 WORD32 *filt_ptr;
513 WORD32 start_slot = 2;
514
515 if (ldsbr_present) {
516 qmf_bank->filter_pos_32 +=
517 (qmf_dec_tables_ptr->qmf_c_ldsbr_mps - qmf_bank->analy_win_coeff_32);
518 qmf_bank->analy_win_coeff_32 = qmf_dec_tables_ptr->qmf_c_ldsbr_mps;
519 } else {
520 qmf_bank->filter_pos_32 += (ixheaacd_ldmps_polyphase_filter_coeff_fix -
521 qmf_bank->analy_win_coeff_32);
522 qmf_bank->analy_win_coeff_32 =
523 (WORD32 *)ixheaacd_ldmps_polyphase_filter_coeff_fix;
524 }
525
526 filter_1 = qmf_bank->filter_pos_32;
527 filter_2 = filter_1 + qmf_bank->no_channels;
528
529 sbr_scale_factor->st_lb_scale = 0;
530 sbr_scale_factor->lb_scale = -10;
531
532 sbr_scale_factor->lb_scale = -9;
533 if (qmf_bank->no_channels != 64) {
534 qmf_bank->cos_twiddle =
535 (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32;
536 qmf_bank->alt_sin_twiddle =
537 (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32;
538 } else {
539 qmf_bank->cos_twiddle =
540 (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l64;
541 qmf_bank->alt_sin_twiddle =
542 (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l64;
543 }
544 qmf_bank->t_cos =
545 (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld;
546
547 fp1 = qmf_bank->anal_filter_states_32;
548 fp2 = qmf_bank->anal_filter_states_32 + qmf_bank->no_channels;
549
550 filter_2 = qmf_bank->filter_2_32;
551 fp1 = qmf_bank->fp1_anal_32;
552 fp2 = qmf_bank->fp2_anal_32;
553
554 for (i = start_slot; i < num_time_slots + start_slot; i++) {
555 for (k = 0; k < qmf_bank->no_channels; k++)
556 filter_states[qmf_bank->no_channels - 1 - k] =
557 time_sample_buf[ch_fac * k];
558
559 if (ldsbr_present) {
560 ixheaacd_sbr_qmfanal32_winadd_eld_32(fp1, fp2, filter_1, filter_2,
561 analysis_buffer);
562 } else {
563 ixheaacd_sbr_qmfanal32_winadd_eld_mps(fp1, fp2, filter_1, filter_2,
564 analysis_buffer);
565 }
566
567 time_sample_buf += qmf_bank->no_channels * ch_fac;
568
569 filter_states -= qmf_bank->no_channels;
570
571 if (filter_states < qmf_bank->anal_filter_states_32) {
572 filter_states = qmf_bank->anal_filter_states_32 +
573 ((qmf_bank->no_channels * 10) - qmf_bank->no_channels);
574 }
575
576 tmp = fp1;
577 fp1 = fp2;
578 fp2 = tmp;
579
580 filter_1 += qmf_bank->no_channels;
581 filter_2 += qmf_bank->no_channels;
582
583 filt_ptr = filter_1;
584 filter_1 = filter_2;
585 filter_2 = filt_ptr;
586
587 if (filter_2 >
588 (qmf_bank->analy_win_coeff_32 + (qmf_bank->no_channels * 10))) {
589 filter_1 = (WORD32 *)qmf_bank->analy_win_coeff_32;
590 filter_2 = (WORD32 *)qmf_bank->analy_win_coeff_32 + qmf_bank->no_channels;
591 }
592
593 ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i], qmf_bank,
594 qmf_dec_tables_ptr, 1);
595 }
596
597 qmf_bank->filter_pos_32 = filter_1;
598 qmf_bank->core_samples_buffer_32 = filter_states;
599
600 qmf_bank->fp1_anal_32 = fp1;
601 qmf_bank->fp2_anal_32 = fp2;
602 qmf_bank->filter_2_32 = filter_2;
603 }
604
ixheaacd_inv_modulation_lp(WORD32 * qmf_real,WORD16 * filter_states,ia_sbr_qmf_filter_bank_struct * syn_qmf,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)605 VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states,
606 ia_sbr_qmf_filter_bank_struct *syn_qmf,
607 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
608 WORD32 L = syn_qmf->no_channels;
609 const WORD32 M = (L >> 1);
610 WORD32 *dct_in = qmf_real;
611 WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS];
612
613 WORD32 ui_rem = ((WORD64)(&time_out[0]) % 8);
614 WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem);
615
616 if (L == 64)
617 ixheaacd_dct2_64(dct_in, ptime_out, qmf_dec_tables_ptr, filter_states + M);
618 else
619 ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states);
620
621 filter_states[3 * M] = 0;
622 }
623
ixheaacd_inv_emodulation(WORD32 * qmf_real,ia_sbr_qmf_filter_bank_struct * syn_qmf,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)624 VOID ixheaacd_inv_emodulation(WORD32 *qmf_real,
625 ia_sbr_qmf_filter_bank_struct *syn_qmf,
626 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
627 ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024,
628 (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128);
629 }
630
ixheaacd_esbr_radix4bfly(const WORD32 * w,WORD32 * x,WORD32 index1,WORD32 index)631 VOID ixheaacd_esbr_radix4bfly(const WORD32 *w, WORD32 *x, WORD32 index1,
632 WORD32 index) {
633 int i;
634 WORD32 l1, l2, h2, fft_jmp;
635 WORD64 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0;
636 WORD64 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0;
637 WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1;
638 WORD32 x_h2_0, x_h2_1;
639 WORD32 si10, si20, si30, co10, co20, co30;
640
641 WORD64 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6;
642 WORD64 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12;
643 WORD32 *x_l1;
644 WORD32 *x_l2;
645 WORD32 *x_h2;
646 const WORD32 *w_ptr = w;
647 WORD32 i1;
648
649 h2 = index << 1;
650 l1 = index << 2;
651 l2 = (index << 2) + (index << 1);
652
653 x_l1 = &(x[l1]);
654 x_l2 = &(x[l2]);
655 x_h2 = &(x[h2]);
656
657 fft_jmp = 6 * (index);
658
659 for (i1 = 0; i1 < index1; i1++) {
660 for (i = 0; i < index; i++) {
661 si10 = (*w_ptr++);
662 co10 = (*w_ptr++);
663 si20 = (*w_ptr++);
664 co20 = (*w_ptr++);
665 si30 = (*w_ptr++);
666 co30 = (*w_ptr++);
667
668 x_0 = x[0];
669 x_h2_0 = x[h2];
670 x_l1_0 = x[l1];
671 x_l2_0 = x[l2];
672
673 xh0_0 = (WORD64)x_0 + (WORD64)x_l1_0;
674 xl0_0 = (WORD64)x_0 - (WORD64)x_l1_0;
675
676 xh20_0 = (WORD64)x_h2_0 + (WORD64)x_l2_0;
677 xl20_0 = (WORD64)x_h2_0 - (WORD64)x_l2_0;
678
679 x[0] = (WORD32)ixheaac_add64_sat(xh0_0, xh20_0);
680 xt0_0 = (WORD64)xh0_0 - (WORD64)xh20_0;
681
682 x_1 = x[1];
683 x_h2_1 = x[h2 + 1];
684 x_l1_1 = x[l1 + 1];
685 x_l2_1 = x[l2 + 1];
686
687 xh1_0 = (WORD64)x_1 + (WORD64)x_l1_1;
688 xl1_0 = (WORD64)x_1 - (WORD64)x_l1_1;
689
690 xh21_0 = (WORD64)x_h2_1 + (WORD64)x_l2_1;
691 xl21_0 = (WORD64)x_h2_1 - (WORD64)x_l2_1;
692
693 x[1] = (WORD32)ixheaac_add64_sat(xh1_0, xh21_0);
694 yt0_0 = (WORD64)xh1_0 - (WORD64)xh21_0;
695
696 xt1_0 = (WORD64)xl0_0 + (WORD64)xl21_0;
697 xt2_0 = (WORD64)xl0_0 - (WORD64)xl21_0;
698
699 yt2_0 = (WORD64)xl1_0 + (WORD64)xl20_0;
700 yt1_0 = (WORD64)xl1_0 - (WORD64)xl20_0;
701
702 mul_11 = ixheaac_mult64(xt2_0, co30);
703 mul_3 = ixheaac_mult64(yt2_0, si30);
704 x[l2] = ixheaac_sat64_32(((mul_3 + mul_11) >> 32) << RADIXSHIFT);
705
706 mul_5 = ixheaac_mult64(xt2_0, si30);
707 mul_9 = ixheaac_mult64(yt2_0, co30);
708 x[l2 + 1] = ixheaac_sat64_32(((mul_9 - mul_5) >> 32) << RADIXSHIFT);
709
710 mul_12 = ixheaac_mult64(xt0_0, co20);
711 mul_2 = ixheaac_mult64(yt0_0, si20);
712 x[l1] = ixheaac_sat64_32(((mul_2 + mul_12) >> 32) << RADIXSHIFT);
713
714 mul_6 = ixheaac_mult64(xt0_0, si20);
715 mul_8 = ixheaac_mult64(yt0_0, co20);
716 x[l1 + 1] = ixheaac_sat64_32(((mul_8 - mul_6) >> 32) << RADIXSHIFT);
717
718 mul_4 = ixheaac_mult64(xt1_0, co10);
719 mul_1 = ixheaac_mult64(yt1_0, si10);
720 x[h2] = ixheaac_sat64_32(((mul_1 + mul_4) >> 32) << RADIXSHIFT);
721
722 mul_10 = ixheaac_mult64(xt1_0, si10);
723 mul_7 = ixheaac_mult64(yt1_0, co10);
724 x[h2 + 1] = ixheaac_sat64_32(((mul_7 - mul_10) >> 32) << RADIXSHIFT);
725
726 x += 2;
727 }
728 x += fft_jmp;
729 w_ptr = w_ptr - fft_jmp;
730 }
731 }
732
ixheaacd_esbr_postradixcompute2(WORD32 * ptr_y,WORD32 * ptr_x,const WORD32 * pdig_rev_tbl,WORD32 npoints)733 VOID ixheaacd_esbr_postradixcompute2(WORD32 *ptr_y, WORD32 *ptr_x,
734 const WORD32 *pdig_rev_tbl,
735 WORD32 npoints) {
736 WORD32 i, k;
737 WORD32 h2;
738 WORD32 x_0, x_1, x_2, x_3;
739 WORD32 x_4, x_5, x_6, x_7;
740 WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f;
741 WORD32 n0, j0;
742 WORD32 *x2, *x0;
743 WORD32 *y0, *y1, *y2, *y3;
744
745 y0 = ptr_y;
746 y2 = ptr_y + (WORD32)npoints;
747 x0 = ptr_x;
748 x2 = ptr_x + (WORD32)(npoints >> 1);
749
750 y1 = y0 + (WORD32)(npoints >> 2);
751 y3 = y2 + (WORD32)(npoints >> 2);
752 j0 = 8;
753 n0 = npoints >> 1;
754
755 for (k = 0; k < 2; k++) {
756 for (i = 0; i<npoints>> 1; i += 8) {
757 h2 = *pdig_rev_tbl++ >> 2;
758
759 x_0 = *x0++;
760 x_1 = *x0++;
761 x_2 = *x0++;
762 x_3 = *x0++;
763 x_4 = *x0++;
764 x_5 = *x0++;
765 x_6 = *x0++;
766 x_7 = *x0++;
767
768 y0[h2] = ixheaac_add32_sat(x_0, x_2);
769 y0[h2 + 1] = ixheaac_add32_sat(x_1, x_3);
770 y1[h2] = ixheaac_add32_sat(x_4, x_6);
771 y1[h2 + 1] = ixheaac_add32_sat(x_5, x_7);
772 y2[h2] = ixheaac_sub32_sat(x_0, x_2);
773 y2[h2 + 1] = ixheaac_sub32_sat(x_1, x_3);
774 y3[h2] = ixheaac_sub32_sat(x_4, x_6);
775 y3[h2 + 1] = ixheaac_sub32_sat(x_5, x_7);
776
777 x_8 = *x2++;
778 x_9 = *x2++;
779 x_a = *x2++;
780 x_b = *x2++;
781 x_c = *x2++;
782 x_d = *x2++;
783 x_e = *x2++;
784 x_f = *x2++;
785
786 y0[h2 + 2] = ixheaac_add32_sat(x_8, x_a);
787 y0[h2 + 3] = ixheaac_add32_sat(x_9, x_b);
788 y1[h2 + 2] = ixheaac_add32_sat(x_c, x_e);
789 y1[h2 + 3] = ixheaac_add32_sat(x_d, x_f);
790 y2[h2 + 2] = ixheaac_sub32_sat(x_8, x_a);
791 y2[h2 + 3] = ixheaac_sub32_sat(x_9, x_b);
792 y3[h2 + 2] = ixheaac_sub32_sat(x_c, x_e);
793 y3[h2 + 3] = ixheaac_sub32_sat(x_d, x_f);
794 }
795 x0 += (WORD32)npoints >> 1;
796 x2 += (WORD32)npoints >> 1;
797 }
798 }
799
ixheaacd_esbr_postradixcompute4(WORD32 * ptr_y,WORD32 * ptr_x,const WORD32 * p_dig_rev_tbl,WORD32 npoints)800 VOID ixheaacd_esbr_postradixcompute4(WORD32 *ptr_y, WORD32 *ptr_x,
801 const WORD32 *p_dig_rev_tbl,
802 WORD32 npoints) {
803 WORD32 i, k;
804 WORD32 h2;
805 WORD32 xh0_0, xh1_0, xl0_0, xl1_0;
806 WORD32 xh0_1, xh1_1, xl0_1, xl1_1;
807 WORD32 x_0, x_1, x_2, x_3;
808 WORD32 xh0_2, xh1_2, xl0_2, xl1_2, xh0_3, xh1_3, xl0_3, xl1_3;
809 WORD32 x_4, x_5, x_6, x_7;
810 WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f;
811 WORD32 n00, n10, n20, n30, n01, n11, n21, n31;
812 WORD32 n02, n12, n22, n32, n03, n13, n23, n33;
813 WORD32 n0, j0;
814 WORD32 *x2, *x0;
815 WORD32 *y0, *y1, *y2, *y3;
816
817 y0 = ptr_y;
818 y2 = ptr_y + (WORD32)npoints;
819 x0 = ptr_x;
820 x2 = ptr_x + (WORD32)(npoints >> 1);
821
822 y1 = y0 + (WORD32)(npoints >> 1);
823 y3 = y2 + (WORD32)(npoints >> 1);
824
825 j0 = 4;
826 n0 = npoints >> 2;
827
828 for (k = 0; k < 2; k++) {
829 for (i = 0; i<npoints>> 1; i += 8) {
830 h2 = *p_dig_rev_tbl++ >> 2;
831 x_0 = *x0++;
832 x_1 = *x0++;
833 x_2 = *x0++;
834 x_3 = *x0++;
835 x_4 = *x0++;
836 x_5 = *x0++;
837 x_6 = *x0++;
838 x_7 = *x0++;
839
840 xh0_0 = ixheaac_add32_sat(x_0, x_4);
841 xh1_0 = ixheaac_add32_sat(x_1, x_5);
842 xl0_0 = ixheaac_sub32_sat(x_0, x_4);
843 xl1_0 = ixheaac_sub32_sat(x_1, x_5);
844 xh0_1 = ixheaac_add32_sat(x_2, x_6);
845 xh1_1 = ixheaac_add32_sat(x_3, x_7);
846 xl0_1 = ixheaac_sub32_sat(x_2, x_6);
847 xl1_1 = ixheaac_sub32_sat(x_3, x_7);
848
849 n00 = ixheaac_add32_sat(xh0_0, xh0_1);
850 n01 = ixheaac_add32_sat(xh1_0, xh1_1);
851 n10 = ixheaac_add32_sat(xl0_0, xl1_1);
852 n11 = ixheaac_sub32_sat(xl1_0, xl0_1);
853 n20 = ixheaac_sub32_sat(xh0_0, xh0_1);
854 n21 = ixheaac_sub32_sat(xh1_0, xh1_1);
855 n30 = ixheaac_sub32_sat(xl0_0, xl1_1);
856 n31 = ixheaac_add32_sat(xl1_0, xl0_1);
857
858 y0[h2] = n00;
859 y0[h2 + 1] = n01;
860 y1[h2] = n10;
861 y1[h2 + 1] = n11;
862 y2[h2] = n20;
863 y2[h2 + 1] = n21;
864 y3[h2] = n30;
865 y3[h2 + 1] = n31;
866
867 x_8 = *x2++;
868 x_9 = *x2++;
869 x_a = *x2++;
870 x_b = *x2++;
871 x_c = *x2++;
872 x_d = *x2++;
873 x_e = *x2++;
874 x_f = *x2++;
875
876 xh0_2 = ixheaac_add32_sat(x_8, x_c);
877 xh1_2 = ixheaac_add32_sat(x_9, x_d);
878 xl0_2 = ixheaac_sub32_sat(x_8, x_c);
879 xl1_2 = ixheaac_sub32_sat(x_9, x_d);
880 xh0_3 = ixheaac_add32_sat(x_a, x_e);
881 xh1_3 = ixheaac_add32_sat(x_b, x_f);
882 xl0_3 = ixheaac_sub32_sat(x_a, x_e);
883 xl1_3 = ixheaac_sub32_sat(x_b, x_f);
884
885 n02 = ixheaac_add32_sat(xh0_2, xh0_3);
886 n03 = ixheaac_add32_sat(xh1_2, xh1_3);
887 n12 = ixheaac_add32_sat(xl0_2, xl1_3);
888 n13 = ixheaac_sub32_sat(xl1_2, xl0_3);
889 n22 = ixheaac_sub32_sat(xh0_2, xh0_3);
890 n23 = ixheaac_sub32_sat(xh1_2, xh1_3);
891 n32 = ixheaac_sub32_sat(xl0_2, xl1_3);
892 n33 = ixheaac_add32_sat(xl1_2, xl0_3);
893
894 y0[h2 + 2] = n02;
895 y0[h2 + 3] = n03;
896 y1[h2 + 2] = n12;
897 y1[h2 + 3] = n13;
898 y2[h2 + 2] = n22;
899 y2[h2 + 3] = n23;
900 y3[h2 + 2] = n32;
901 y3[h2 + 3] = n33;
902 }
903 x0 += (WORD32)npoints >> 1;
904 x2 += (WORD32)npoints >> 1;
905 }
906 }
907
ixheaacd_esbr_cos_sin_mod(WORD32 * subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,WORD32 * p_twiddle,WORD32 * p_dig_rev_tbl)908 VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband,
909 ia_sbr_qmf_filter_bank_struct *qmf_bank,
910 WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) {
911 WORD32 z;
912 WORD32 temp[128];
913 WORD32 scaleshift = 0;
914
915 WORD32 re2, re3;
916 WORD32 wim, wre;
917
918 WORD32 i, M_2;
919 WORD32 M = ixheaac_shr32(qmf_bank->no_channels, 1);
920
921 const WORD32 *p_sin;
922 const WORD32 *p_sin_cos;
923
924 WORD32 subband_tmp[128];
925 WORD32 re;
926 WORD32 im;
927 WORD32 *psubband, *psubband1;
928 WORD32 *psubband_t, *psubband1_t;
929 WORD32 *psubband2, *psubband12;
930 WORD32 *psubband_t2, *psubband1_t2;
931
932 M_2 = ixheaac_shr32(M, 1);
933
934 p_sin_cos = qmf_bank->esbr_cos_twiddle;
935
936 psubband = &subband[0];
937 psubband1 = &subband[2 * M - 1];
938 psubband_t = subband_tmp;
939 psubband1_t = &subband_tmp[2 * M - 1];
940
941 psubband2 = &subband[64];
942 psubband12 = &subband[2 * M - 1 + 64];
943 psubband_t2 = &subband_tmp[64];
944 psubband1_t2 = &subband_tmp[2 * M - 1 + 64];
945
946 for (i = (M_2 >> 1) - 1; i >= 0; i--) {
947 re = *psubband++;
948 im = *psubband1--;
949
950 wim = *p_sin_cos++;
951 wre = *p_sin_cos++;
952
953 *psubband_t++ = (WORD32)(
954 (ixheaac_add64(ixheaac_mult64(re, wre), ixheaac_mult64(im, wim))) >>
955 32);
956 *psubband_t++ = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wre),
957 ixheaac_mult64(re, wim))) >>
958 32);
959
960 re = *psubband2++;
961 im = *psubband12--;
962
963 *psubband_t2++ = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wim),
964 ixheaac_mult64(re, wre))) >>
965 32);
966 *psubband_t2++ = (WORD32)(
967 (ixheaac_add64(ixheaac_mult64(re, wim), ixheaac_mult64(im, wre))) >>
968 32);
969
970 re = *psubband1--;
971 im = *psubband++;
972
973 wim = *p_sin_cos++;
974 wre = *p_sin_cos++;
975
976 *psubband1_t-- = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wre),
977 ixheaac_mult64(re, wim))) >>
978 32);
979 *psubband1_t-- = (WORD32)(
980 (ixheaac_add64(ixheaac_mult64(re, wre), ixheaac_mult64(im, wim))) >>
981 32);
982
983 re = *psubband12--;
984 im = *psubband2++;
985
986 *psubband1_t2-- = (WORD32)(
987 (ixheaac_add64(ixheaac_mult64(re, wim), ixheaac_mult64(im, wre))) >>
988 32);
989 *psubband1_t2-- = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wim),
990 ixheaac_mult64(re, wre))) >>
991 32);
992
993 re = *psubband++;
994 im = *psubband1--;
995
996 wim = *p_sin_cos++;
997 wre = *p_sin_cos++;
998
999 *psubband_t++ = (WORD32)(
1000 (ixheaac_add64(ixheaac_mult64(re, wre), ixheaac_mult64(im, wim))) >>
1001 32);
1002 *psubband_t++ = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wre),
1003 ixheaac_mult64(re, wim))) >>
1004 32);
1005
1006 re = *psubband2++;
1007 im = *psubband12--;
1008
1009 *psubband_t2++ = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wim),
1010 ixheaac_mult64(re, wre))) >>
1011 32);
1012 *psubband_t2++ = (WORD32)(
1013 (ixheaac_add64(ixheaac_mult64(re, wim), ixheaac_mult64(im, wre))) >>
1014 32);
1015
1016 re = *psubband1--;
1017 im = *psubband++;
1018 ;
1019
1020 wim = *p_sin_cos++;
1021 wre = *p_sin_cos++;
1022
1023 *psubband1_t-- = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wre),
1024 ixheaac_mult64(re, wim))) >>
1025 32);
1026 *psubband1_t-- = (WORD32)(
1027 (ixheaac_add64(ixheaac_mult64(re, wre), ixheaac_mult64(im, wim))) >>
1028 32);
1029
1030 re = *psubband12--;
1031 im = *psubband2++;
1032 ;
1033
1034 *psubband1_t2-- = (WORD32)(
1035 (ixheaac_add64(ixheaac_mult64(re, wim), ixheaac_mult64(im, wre))) >>
1036 32);
1037 *psubband1_t2-- = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wim),
1038 ixheaac_mult64(re, wre))) >>
1039 32);
1040 }
1041
1042 if (M == 32) {
1043 ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8);
1044 ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2);
1045 ixheaacd_esbr_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32);
1046
1047 ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8);
1048 ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2);
1049 ixheaacd_esbr_postradixcompute2(&subband[64], &subband_tmp[64],
1050 p_dig_rev_tbl, 32);
1051
1052 }
1053
1054 else if (M == 16) {
1055 ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4);
1056 ixheaacd_esbr_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16);
1057
1058 ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4);
1059 ixheaacd_esbr_postradixcompute4(&subband[64], &subband_tmp[64],
1060 p_dig_rev_tbl, 16);
1061
1062 }
1063
1064 else if (M == 12) {
1065 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1066 temp[z] = subband_tmp[2 * z];
1067 temp[12 + z] = subband_tmp[2 * z + 1];
1068 }
1069
1070 ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
1071
1072 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1073 subband[2 * z] = temp[z];
1074 subband[2 * z + 1] = temp[z + 12];
1075 }
1076 scaleshift = 0;
1077 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1078 temp[z] = subband_tmp[64 + 2 * z];
1079 temp[12 + z] = subband_tmp[64 + 2 * z + 1];
1080 }
1081
1082 ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
1083
1084 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1085 subband[64 + 2 * z] = temp[z];
1086 subband[64 + 2 * z + 1] = temp[z + 12];
1087 }
1088
1089 }
1090
1091 else {
1092 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1093 temp[z] = subband_tmp[2 * z];
1094 temp[8 + z] = subband_tmp[2 * z + 1];
1095 }
1096
1097 (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
1098
1099 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1100 subband[2 * z] = ixheaac_shl32_sat(temp[z], scaleshift);
1101 subband[2 * z + 1] = ixheaac_shl32_sat(temp[z + 8], scaleshift);
1102 }
1103 scaleshift = 0;
1104 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1105 temp[z] = subband_tmp[64 + 2 * z];
1106 temp[8 + z] = subband_tmp[64 + 2 * z + 1];
1107 }
1108
1109 (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
1110
1111 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
1112 subband[64 + 2 * z] = ixheaac_shl32_sat(temp[z], scaleshift);
1113 subband[64 + 2 * z + 1] = ixheaac_shl32_sat(temp[8 + z], scaleshift);
1114 }
1115 }
1116
1117 psubband = &subband[0];
1118 psubband1 = &subband[2 * M - 1];
1119
1120 re = *psubband1;
1121
1122 *psubband = *psubband >> 1;
1123 psubband++;
1124 *psubband1 = ixheaac_negate32(*psubband >> 1);
1125 psubband1--;
1126
1127 p_sin = qmf_bank->esbr_alt_sin_twiddle;
1128
1129 wim = *p_sin++;
1130 wre = *p_sin++;
1131
1132 im = *psubband1;
1133 ;
1134
1135 *psubband1-- = (WORD32)(
1136 (ixheaac_add64(ixheaac_mult64(re, wre), ixheaac_mult64(im, wim))) >>
1137 32);
1138 *psubband++ = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wre),
1139 ixheaac_mult64(re, wim))) >>
1140 32);
1141
1142 psubband2 = &subband[64];
1143 psubband12 = &subband[2 * M - 1 + 64];
1144
1145 re = *psubband12;
1146 ;
1147
1148 *psubband12-- = ixheaac_negate32_sat(*psubband2 >> 1);
1149 ;
1150 *psubband2 = psubband2[1] >> 1;
1151 ;
1152 psubband2++;
1153
1154 im = *psubband12;
1155 ;
1156
1157 *psubband2++ = ixheaac_negate32_sat((WORD32)(
1158 (ixheaac_add64(ixheaac_mult64(re, wre), ixheaac_mult64(im, wim))) >>
1159 32));
1160 *psubband12-- = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(re, wim),
1161 ixheaac_mult64(im, wre))) >>
1162 32);
1163
1164 for (i = (M_2 - 2); i >= 0; i--) {
1165 im = psubband[0];
1166 ;
1167 re = psubband[1];
1168 ;
1169 re2 = *psubband1;
1170 ;
1171
1172 *psubband++ = (WORD32)(
1173 (ixheaac_add64(ixheaac_mult64(re, wim), ixheaac_mult64(im, wre))) >>
1174 32);
1175 *psubband1-- = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wim),
1176 ixheaac_mult64(re, wre))) >>
1177 32);
1178
1179 im = psubband2[0];
1180 ;
1181 re = psubband2[1];
1182 ;
1183 re3 = *psubband12;
1184 ;
1185
1186 *psubband12-- = ixheaac_negate32_sat((WORD32)(
1187 (ixheaac_add64(ixheaac_mult64(re, wim), ixheaac_mult64(im, wre))) >>
1188 32));
1189 *psubband2++ = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(re, wre),
1190 ixheaac_mult64(im, wim))) >>
1191 32);
1192
1193 wim = *p_sin++;
1194 wre = *p_sin++;
1195 im = psubband1[0];
1196 ;
1197
1198 *psubband1-- = (WORD32)(
1199 (ixheaac_add64(ixheaac_mult64(re2, wre), ixheaac_mult64(im, wim))) >>
1200 32);
1201 *psubband++ = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(im, wre),
1202 ixheaac_mult64(re2, wim))) >>
1203 32);
1204
1205 im = psubband12[0];
1206 ;
1207
1208 *psubband2++ = ixheaac_negate32_sat((WORD32)(
1209 (ixheaac_add64(ixheaac_mult64(re3, wre), ixheaac_mult64(im, wim))) >>
1210 32));
1211 *psubband12-- = (WORD32)((ixheaac_sub64_sat(ixheaac_mult64(re3, wim),
1212 ixheaac_mult64(im, wre))) >>
1213 32);
1214 }
1215 }
1216
ixheaacd_esbr_fwd_modulation(const WORD32 * time_sample_buf,WORD32 * real_subband,WORD32 * imag_subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)1217 VOID ixheaacd_esbr_fwd_modulation(
1218 const WORD32 *time_sample_buf, WORD32 *real_subband, WORD32 *imag_subband,
1219 ia_sbr_qmf_filter_bank_struct *qmf_bank,
1220 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
1221 WORD32 i;
1222 const WORD32 *time_sample_buf1 =
1223 &time_sample_buf[2 * qmf_bank->no_channels - 1];
1224 WORD32 temp1, temp2;
1225 WORD32 *t_real_subband = real_subband;
1226 WORD32 *t_imag_subband = imag_subband;
1227 const WORD32 *tcos;
1228
1229 for (i = qmf_bank->no_channels - 1; i >= 0; i--) {
1230 temp1 = ixheaac_shr32(*time_sample_buf++, HQ_SHIFT_64);
1231 temp2 = ixheaac_shr32(*time_sample_buf1--, HQ_SHIFT_64);
1232
1233 *t_real_subband++ = ixheaac_sub32_sat(temp1, temp2);
1234 ;
1235 *t_imag_subband++ = ixheaac_add32_sat(temp1, temp2);
1236 ;
1237 }
1238
1239 ixheaacd_esbr_cos_sin_mod(real_subband, qmf_bank,
1240 qmf_dec_tables_ptr->esbr_w_16,
1241 qmf_dec_tables_ptr->dig_rev_table4_16);
1242
1243 tcos = qmf_bank->esbr_t_cos;
1244
1245 for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) {
1246 WORD32 cosh, sinh;
1247 WORD32 re, im;
1248
1249 re = *real_subband;
1250 im = *imag_subband;
1251 cosh = *tcos++;
1252 sinh = *tcos++;
1253 *real_subband++ =
1254 ixheaac_sat64_32((ixheaac_add64(ixheaac_mult64(re, cosh),
1255 ixheaac_mult64(im, sinh))) >>
1256 31);
1257 *imag_subband++ =
1258 ixheaac_sat64_32((ixheaac_sub64_sat(ixheaac_mult64(im, cosh),
1259 ixheaac_mult64(re, sinh))) >>
1260 31);
1261 }
1262 }
1263
ixheaacd_esbr_qmfsyn64_winadd(WORD32 * tmp1,WORD32 * tmp2,WORD32 * inp1,WORD32 * sample_buffer,WORD32 ch_fac)1264 VOID ixheaacd_esbr_qmfsyn64_winadd(WORD32 *tmp1, WORD32 *tmp2, WORD32 *inp1,
1265 WORD32 *sample_buffer, WORD32 ch_fac) {
1266 WORD32 k;
1267
1268 for (k = 0; k < 64; k++) {
1269 WORD64 syn_out = 0;
1270
1271 syn_out =
1272 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[0 + k], inp1[k + 0]));
1273 syn_out =
1274 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[256 + k], inp1[k + 128]));
1275 syn_out =
1276 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[512 + k], inp1[k + 256]));
1277 syn_out =
1278 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[768 + k], inp1[k + 384]));
1279 syn_out =
1280 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[1024 + k], inp1[k + 512]));
1281
1282 syn_out =
1283 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[128 + k], inp1[k + 64]));
1284 syn_out =
1285 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[384 + k], inp1[k + 192]));
1286 syn_out =
1287 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[640 + k], inp1[k + 320]));
1288 syn_out =
1289 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[896 + k], inp1[k + 448]));
1290 syn_out =
1291 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[1152 + k], inp1[k + 576]));
1292
1293 sample_buffer[ch_fac * k] = ixheaac_sat64_32(syn_out >> 31);
1294 }
1295 }
1296
ixheaacd_esbr_qmfsyn32_winadd(WORD32 * tmp1,WORD32 * tmp2,WORD32 * inp1,WORD32 * sample_buffer,WORD32 ch_fac)1297 VOID ixheaacd_esbr_qmfsyn32_winadd(WORD32 *tmp1, WORD32 *tmp2, WORD32 *inp1,
1298 WORD32 *sample_buffer, WORD32 ch_fac) {
1299 WORD32 k;
1300
1301 for (k = 0; k < 32; k++) {
1302 WORD64 syn_out = 0;
1303
1304 syn_out =
1305 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[0 + k], inp1[2 * (k + 0)]));
1306 syn_out =
1307 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[128 + k], inp1[2 * (k + 64)]));
1308 syn_out =
1309 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[256 + k], inp1[2 * (k + 128)]));
1310 syn_out =
1311 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[384 + k], inp1[2 * (k + 192)]));
1312 syn_out =
1313 ixheaac_add64(syn_out, ixheaac_mult64(tmp1[512 + k], inp1[2 * (k + 256)]));
1314
1315 syn_out =
1316 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[64 + k], inp1[2 * (k + 32)]));
1317 syn_out =
1318 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[192 + k], inp1[2 * (k + 96)]));
1319 syn_out =
1320 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[320 + k], inp1[2 * (k + 160)]));
1321 syn_out =
1322 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[448 + k], inp1[2 * (k + 224)]));
1323 syn_out =
1324 ixheaac_add64(syn_out, ixheaac_mult64(tmp2[576 + k], inp1[2 * (k + 288)]));
1325
1326 sample_buffer[ch_fac * k] = (WORD32)(syn_out >> 31);
1327 }
1328 }
1329
ixheaacd_shiftrountine(WORD32 * qmf_real,WORD32 * qmf_imag,WORD32 len,WORD32 common_shift)1330 VOID ixheaacd_shiftrountine(WORD32 *qmf_real, WORD32 *qmf_imag, WORD32 len,
1331 WORD32 common_shift) {
1332 WORD32 treal, timag;
1333 WORD32 j;
1334
1335 if (common_shift < 0) {
1336 WORD32 cshift = -common_shift;
1337 cshift = ixheaac_min32(cshift, 31);
1338 for (j = len - 1; j >= 0; j--) {
1339 treal = *qmf_real;
1340 timag = *qmf_imag;
1341
1342 treal = (ixheaac_shr32(treal, cshift));
1343 timag = (ixheaac_shr32(timag, cshift));
1344
1345 *qmf_real++ = treal;
1346 *qmf_imag++ = timag;
1347 }
1348 } else {
1349 for (j = len - 1; j >= 0; j--) {
1350 treal = (ixheaac_shl32_sat(*qmf_real, common_shift));
1351 timag = (ixheaac_shl32_sat(*qmf_imag, common_shift));
1352 *qmf_real++ = treal;
1353 *qmf_imag++ = timag;
1354 }
1355 }
1356 }
1357
ixheaacd_shiftrountine_with_rnd_hq(WORD32 * qmf_real,WORD32 * qmf_imag,WORD32 * filter_states,WORD32 len,WORD32 shift)1358 VOID ixheaacd_shiftrountine_with_rnd_hq(WORD32 *qmf_real, WORD32 *qmf_imag,
1359 WORD32 *filter_states, WORD32 len,
1360 WORD32 shift) {
1361 WORD32 *filter_states_rev = filter_states + len;
1362 WORD32 treal, timag;
1363 WORD32 j;
1364
1365 for (j = (len - 1); j >= 0; j -= 2) {
1366 WORD32 r1, r2, i1, i2;
1367 i2 = qmf_imag[j];
1368 r2 = qmf_real[j];
1369 r1 = *qmf_real++;
1370 i1 = *qmf_imag++;
1371
1372 timag = ixheaac_add32_sat(i1, r1);
1373 timag = (ixheaac_shl32_sat(timag, shift));
1374 filter_states_rev[j] = timag;
1375
1376 treal = ixheaac_sub32_sat(i2, r2);
1377 treal = (ixheaac_shl32_sat(treal, shift));
1378 filter_states[j] = treal;
1379
1380 treal = ixheaac_sub32_sat(i1, r1);
1381 treal = (ixheaac_shl32_sat(treal, shift));
1382 *filter_states++ = treal;
1383
1384 timag = ixheaac_add32_sat(i2, r2);
1385 timag = (ixheaac_shl32_sat(timag, shift));
1386 *filter_states_rev++ = timag;
1387 }
1388 }
1389
ixheaacd_radix4bfly(const WORD16 * w,WORD32 * x,WORD32 index1,WORD32 index)1390 VOID ixheaacd_radix4bfly(const WORD16 *w, WORD32 *x, WORD32 index1,
1391 WORD32 index) {
1392 int i;
1393 WORD32 l1, l2, h2, fft_jmp;
1394 WORD32 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0;
1395 WORD32 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0;
1396 WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1;
1397 WORD32 x_h2_0, x_h2_1;
1398 WORD16 si10, si20, si30, co10, co20, co30;
1399
1400 WORD32 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6;
1401 WORD32 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12;
1402 WORD32 *x_l1;
1403 WORD32 *x_l2;
1404 WORD32 *x_h2;
1405 const WORD16 *w_ptr = w;
1406 WORD32 i1;
1407
1408 h2 = index << 1;
1409 l1 = index << 2;
1410 l2 = (index << 2) + (index << 1);
1411
1412 x_l1 = &(x[l1]);
1413 x_l2 = &(x[l2]);
1414 x_h2 = &(x[h2]);
1415
1416 fft_jmp = 6 * (index);
1417
1418 for (i1 = 0; i1 < index1; i1++) {
1419 for (i = 0; i < index; i++) {
1420 si10 = (*w_ptr++);
1421 co10 = (*w_ptr++);
1422 si20 = (*w_ptr++);
1423 co20 = (*w_ptr++);
1424 si30 = (*w_ptr++);
1425 co30 = (*w_ptr++);
1426
1427 x_0 = x[0];
1428 x_h2_0 = x[h2];
1429 x_l1_0 = x[l1];
1430 x_l2_0 = x[l2];
1431
1432 xh0_0 = ixheaac_add32_sat(x_0, x_l1_0);
1433 xl0_0 = ixheaac_sub32_sat(x_0, x_l1_0);
1434
1435 xh20_0 = ixheaac_add32_sat(x_h2_0, x_l2_0);
1436 xl20_0 = ixheaac_sub32_sat(x_h2_0, x_l2_0);
1437
1438 x[0] = ixheaac_add32_sat(xh0_0, xh20_0);
1439 xt0_0 = ixheaac_sub32_sat(xh0_0, xh20_0);
1440
1441 x_1 = x[1];
1442 x_h2_1 = x[h2 + 1];
1443 x_l1_1 = x[l1 + 1];
1444 x_l2_1 = x[l2 + 1];
1445
1446 xh1_0 = ixheaac_add32_sat(x_1, x_l1_1);
1447 xl1_0 = ixheaac_sub32_sat(x_1, x_l1_1);
1448
1449 xh21_0 = ixheaac_add32_sat(x_h2_1, x_l2_1);
1450 xl21_0 = ixheaac_sub32_sat(x_h2_1, x_l2_1);
1451
1452 x[1] = ixheaac_add32_sat(xh1_0, xh21_0);
1453 yt0_0 = ixheaac_sub32_sat(xh1_0, xh21_0);
1454
1455 xt1_0 = ixheaac_add32_sat(xl0_0, xl21_0);
1456 xt2_0 = ixheaac_sub32_sat(xl0_0, xl21_0);
1457
1458 yt2_0 = ixheaac_add32_sat(xl1_0, xl20_0);
1459 yt1_0 = ixheaac_sub32_sat(xl1_0, xl20_0);
1460
1461 mul_11 = ixheaac_mult32x16in32(xt2_0, co30);
1462 mul_3 = ixheaac_mult32x16in32(yt2_0, si30);
1463 x[l2] = ixheaac_shl32_sat((mul_3 + mul_11), RADIXSHIFT);
1464
1465 mul_5 = ixheaac_mult32x16in32(xt2_0, si30);
1466 mul_9 = ixheaac_mult32x16in32(yt2_0, co30);
1467 x[l2 + 1] = ixheaac_shl32_sat((mul_9 - mul_5), RADIXSHIFT);
1468
1469 mul_12 = ixheaac_mult32x16in32(xt0_0, co20);
1470 mul_2 = ixheaac_mult32x16in32(yt0_0, si20);
1471 x[l1] = ixheaac_shl32_sat((mul_2 + mul_12), RADIXSHIFT);
1472
1473 mul_6 = ixheaac_mult32x16in32(xt0_0, si20);
1474 mul_8 = ixheaac_mult32x16in32(yt0_0, co20);
1475 x[l1 + 1] = ixheaac_shl32_sat((mul_8 - mul_6), RADIXSHIFT);
1476
1477 mul_4 = ixheaac_mult32x16in32(xt1_0, co10);
1478 mul_1 = ixheaac_mult32x16in32(yt1_0, si10);
1479 x[h2] = ixheaac_shl32_sat((mul_1 + mul_4), RADIXSHIFT);
1480
1481 mul_10 = ixheaac_mult32x16in32(xt1_0, si10);
1482 mul_7 = ixheaac_mult32x16in32(yt1_0, co10);
1483 x[h2 + 1] = ixheaac_shl32_sat((mul_7 - mul_10), RADIXSHIFT);
1484
1485 x += 2;
1486 }
1487 x += fft_jmp;
1488 w_ptr = w_ptr - fft_jmp;
1489 }
1490 }
1491