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
22 #include "ixheaacd_sbr_common.h"
23 #include <ixheaacd_type_def.h>
24
25 #include "ixheaacd_constants.h"
26 #include "ixheaacd_basic_ops32.h"
27 #include "ixheaacd_basic_ops16.h"
28 #include "ixheaacd_basic_ops40.h"
29 #include "ixheaacd_basic_ops.h"
30
31 #include "ixheaacd_intrinsics.h"
32 #include "ixheaacd_common_rom.h"
33 #include "ixheaacd_bitbuffer.h"
34 #include "ixheaacd_sbrdecsettings.h"
35 #include "ixheaacd_sbr_scale.h"
36 #include "ixheaacd_lpp_tran.h"
37 #include "ixheaacd_env_extr_part.h"
38 #include "ixheaacd_sbr_rom.h"
39 #include "ixheaacd_hybrid.h"
40 #include "ixheaacd_ps_dec.h"
41 #include "ixheaacd_env_extr.h"
42 #include "ixheaacd_qmf_dec.h"
43
44 #include <ixheaacd_basic_op.h>
45 #include "ixheaacd_env_calc.h"
46
47 #include "ixheaacd_interface.h"
48
49 #include "ixheaacd_function_selector.h"
50 #include "ixheaacd_audioobjtypes.h"
51
52 #define mult16x16_16(a, b) ixheaacd_mult16((a), (b))
53 #define mac16x16(a, b, c) ixheaacd_mac16x16in32_sat((a), (b), (c))
54 #define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b))
55 #define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b))
56 #define mpy_32x32(a, b) ixheaacd_mult32((a), (b))
57 #define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b))
58 #define msu16x16(a, b, c) msu16x16in32((a), (b), (c))
59
60 #define DCT3_LEN (32)
61 #define DCT2_LEN (64)
62
63 #define LP_SHIFT_VAL 7
64 #define HQ_SHIFT_64 4
65 #define RADIXSHIFT 1
66 #define ROUNDING_SPECTRA 1
67 #define HQ_SHIFT_VAL 4
68
ixheaacd_dct2_64(WORD32 * x,WORD32 * X,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD16 * filter_states)69 VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X,
70 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
71 WORD16 *filter_states) {
72 ixheaacd_pretwdct2(x, X);
73
74 ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x,
75 qmf_dec_tables_ptr->dig_rev_table2_128,
76 qmf_dec_tables_ptr->dig_rev_table2_128,
77 qmf_dec_tables_ptr->dig_rev_table2_128,
78 qmf_dec_tables_ptr->dig_rev_table2_128);
79
80 ixheaacd_fftposttw(x, qmf_dec_tables_ptr);
81
82 ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr);
83
84 return;
85 }
86
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)87 VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf,
88 ia_sbr_scale_fact_struct *sbr_scale_factor,
89 WORD32 **qmf_real, WORD32 **qmf_imag,
90 ia_sbr_qmf_filter_bank_struct *qmf_bank,
91 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
92 WORD32 ch_fac, WORD32 low_pow_flag,
93 WORD audio_object_type) {
94 WORD32 i, k;
95 WORD32 num_time_slots = qmf_bank->num_time_slots;
96
97 WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS];
98 WORD16 *filter_states = qmf_bank->core_samples_buffer;
99
100 WORD16 *fp1, *fp2, *tmp;
101
102 WORD16 *filter_1;
103 WORD16 *filter_2;
104 WORD16 *filt_ptr;
105 if (audio_object_type != AOT_ER_AAC_ELD &&
106 audio_object_type != AOT_ER_AAC_LD) {
107 qmf_bank->filter_pos +=
108 (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff);
109 qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c;
110 } else {
111 qmf_bank->filter_pos +=
112 (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff);
113 qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3;
114 }
115
116 filter_1 = qmf_bank->filter_pos;
117
118 if (audio_object_type != AOT_ER_AAC_ELD &&
119 audio_object_type != AOT_ER_AAC_LD) {
120 filter_2 = filter_1 + 64;
121 } else {
122 filter_2 = filter_1 + 32;
123 }
124
125 sbr_scale_factor->st_lb_scale = 0;
126 sbr_scale_factor->lb_scale = -10;
127 if (!low_pow_flag) {
128 if (audio_object_type != AOT_ER_AAC_ELD &&
129 audio_object_type != AOT_ER_AAC_LD) {
130 sbr_scale_factor->lb_scale = -8;
131 } else {
132 sbr_scale_factor->lb_scale = -9;
133 }
134 qmf_bank->cos_twiddle =
135 (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32;
136 qmf_bank->alt_sin_twiddle =
137 (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32;
138 if (audio_object_type != AOT_ER_AAC_ELD &&
139 audio_object_type != AOT_ER_AAC_LD) {
140 qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32;
141 } else {
142 qmf_bank->t_cos =
143 (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld;
144 }
145 }
146
147 fp1 = qmf_bank->anal_filter_states;
148 fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS;
149
150 if (audio_object_type == AOT_ER_AAC_ELD ||
151 audio_object_type == AOT_ER_AAC_LD) {
152 filter_2 = qmf_bank->filter_2;
153 fp1 = qmf_bank->fp1_anal;
154 fp2 = qmf_bank->fp2_anal;
155 }
156
157 for (i = 0; i < num_time_slots; i++) {
158 for (k = 0; k < NO_ANALYSIS_CHANNELS; k++)
159 filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k];
160
161 if (audio_object_type != AOT_ER_AAC_ELD &&
162 audio_object_type != AOT_ER_AAC_LD) {
163 ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2,
164 analysis_buffer, filter_states,
165 time_sample_buf, ch_fac);
166 } else {
167 ixheaacd_sbr_qmfanal32_winadds_eld(fp1, fp2, filter_1, filter_2,
168 analysis_buffer, filter_states,
169 time_sample_buf, ch_fac);
170 }
171
172 time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac;
173
174 filter_states -= NO_ANALYSIS_CHANNELS;
175 if (filter_states < qmf_bank->anal_filter_states) {
176 filter_states = qmf_bank->anal_filter_states + 288;
177 }
178
179 tmp = fp1;
180 fp1 = fp2;
181 fp2 = tmp;
182 if (audio_object_type != AOT_ER_AAC_ELD &&
183 audio_object_type != AOT_ER_AAC_LD) {
184 filter_1 += 64;
185 filter_2 += 64;
186 } else {
187 filter_1 += 32;
188 filter_2 += 32;
189 }
190
191 filt_ptr = filter_1;
192 filter_1 = filter_2;
193 filter_2 = filt_ptr;
194 if (audio_object_type != AOT_ER_AAC_ELD &&
195 audio_object_type != AOT_ER_AAC_LD) {
196 if (filter_2 > (qmf_bank->analy_win_coeff + 640)) {
197 filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
198 filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64;
199 }
200 } else {
201 if (filter_2 > (qmf_bank->analy_win_coeff + 320)) {
202 filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
203 filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32;
204 }
205 }
206
207 if (!low_pow_flag) {
208 ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i],
209 qmf_bank, qmf_dec_tables_ptr);
210 } else {
211 ixheaacd_dct3_32(
212 (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw,
213 qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16,
214 qmf_dec_tables_ptr->dig_rev_table4_16);
215 }
216 }
217
218 qmf_bank->filter_pos = filter_1;
219 qmf_bank->core_samples_buffer = filter_states;
220
221 if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD)
222
223 {
224 qmf_bank->fp1_anal = fp1;
225 qmf_bank->fp2_anal = fp2;
226 qmf_bank->filter_2 = filter_2;
227 }
228 }
229
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)230 VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states,
231 ia_sbr_qmf_filter_bank_struct *syn_qmf,
232 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
233 WORD32 L = syn_qmf->no_channels;
234 const WORD32 M = (L >> 1);
235 WORD32 *dct_in = qmf_real;
236 WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS];
237
238 WORD32 ui_rem = ((WORD32)(&time_out[0]) % 8);
239 WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem);
240
241 if (L == 64)
242 ixheaacd_dec_DCT2_64_asm(dct_in, ptime_out, qmf_dec_tables_ptr->w1024,
243 qmf_dec_tables_ptr->dig_rev_table2_128,
244 qmf_dec_tables_ptr->post_fft_tbl,
245 qmf_dec_tables_ptr->dct23_tw, filter_states + M);
246 else
247 ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states);
248
249 filter_states[3 * M] = 0;
250 }
251
ixheaacd_inv_emodulation(WORD32 * qmf_real,ia_sbr_qmf_filter_bank_struct * syn_qmf,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)252 VOID ixheaacd_inv_emodulation(WORD32 *qmf_real,
253 ia_sbr_qmf_filter_bank_struct *syn_qmf,
254 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
255 ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024,
256 (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128);
257 }
258
ixheaacd_esbr_cos_sin_mod(WORD32 * subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,WORD32 * p_twiddle,WORD32 * p_dig_rev_tbl)259 VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband,
260 ia_sbr_qmf_filter_bank_struct *qmf_bank,
261 WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) {
262 WORD32 z;
263 WORD32 temp[128];
264 WORD32 scaleshift = 0;
265
266 WORD32 M_2;
267 WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1);
268
269 const WORD32 *p_sin;
270 const WORD32 *p_sin_cos;
271
272 WORD32 subband_tmp[128];
273
274 p_sin_cos = qmf_bank->esbr_cos_twiddle;
275 ixheaacd_esbr_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp);
276
277 M_2 = ixheaacd_shr32(M, 1);
278 if (M == 32) {
279 ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8);
280 ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2);
281 ixheaacd_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32);
282
283 ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8);
284 ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2);
285 ixheaacd_postradixcompute2(&subband[64], &subband_tmp[64], p_dig_rev_tbl,
286 32);
287
288 }
289
290 else if (M == 16) {
291 ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4);
292 ixheaacd_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16);
293
294 ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4);
295 ixheaacd_postradixcompute4(&subband[64], &subband_tmp[64], p_dig_rev_tbl,
296 16);
297
298 }
299
300 else if (M == 12) {
301 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
302 temp[z] = subband_tmp[2 * z];
303 temp[12 + z] = subband_tmp[2 * z + 1];
304 }
305
306 ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
307
308 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
309 subband[2 * z] = temp[z];
310 subband[2 * z + 1] = temp[z + 12];
311 }
312 scaleshift = 0;
313 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
314 temp[z] = subband_tmp[64 + 2 * z];
315 temp[12 + z] = subband_tmp[64 + 2 * z + 1];
316 }
317
318 ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
319
320 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
321 subband[64 + 2 * z] = temp[z];
322 subband[64 + 2 * z + 1] = temp[z + 12];
323 }
324
325 }
326
327 else {
328 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
329 temp[z] = subband_tmp[2 * z];
330 temp[8 + z] = subband_tmp[2 * z + 1];
331 }
332
333 (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
334
335 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
336 subband[2 * z] = temp[z] << scaleshift;
337 subband[2 * z + 1] = temp[z + 8] << scaleshift;
338 }
339 scaleshift = 0;
340 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
341 temp[z] = subband_tmp[64 + 2 * z];
342 temp[8 + z] = subband_tmp[64 + 2 * z + 1];
343 }
344
345 (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
346
347 for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
348 subband[64 + 2 * z] = temp[z] << scaleshift;
349 subband[64 + 2 * z + 1] = temp[8 + z] << scaleshift;
350 }
351 }
352 p_sin = qmf_bank->esbr_alt_sin_twiddle;
353 ixheaacd_esbr_cos_sin_mod_loop2(subband, p_sin, M);
354 }