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 <string.h>
21 #include "ixheaacd_type_def.h"
22 #include "ixheaacd_memory_standards.h"
23 #include "ixheaacd_mps_struct_def.h"
24 #include "ixheaacd_mps_res_rom.h"
25 #include "ixheaacd_mps_aac_struct.h"
26 #include "ixheaacd_constants.h"
27 #include "ixheaacd_basic_ops32.h"
28 #include "ixheaacd_basic_ops40.h"
29 #include "ixheaacd_bitbuffer.h"
30 #include "ixheaacd_common_rom.h"
31 #include "ixheaacd_sbrdecsettings.h"
32 #include "ixheaacd_sbr_scale.h"
33 #include "ixheaacd_env_extr_part.h"
34 #include "ixheaacd_sbr_rom.h"
35 #include "ixheaacd_hybrid.h"
36 #include "ixheaacd_ps_dec.h"
37 #include "ixheaacd_mps_polyphase.h"
38 #include "ixheaacd_config.h"
39 #include "ixheaacd_qmf_dec.h"
40 #include "ixheaacd_mps_dec.h"
41 #include "ixheaacd_mps_decor.h"
42 #include "ixheaacd_mps_hybfilter.h"
43 #include "ixheaacd_mps_mdct_2_qmf.h"
44 #include "ixheaacd_mps_get_index.h"
45 #include "ixheaacd_mps_macro_def.h"
46 #include "ixheaacd_mps_basic_op.h"
47 #include "ixheaacd_error_standards.h"
48
ixheaacd_mdct_2_qmf(ia_heaac_mps_state_struct * pstr_mps_state)49 VOID ixheaacd_mdct_2_qmf(ia_heaac_mps_state_struct *pstr_mps_state) {
50 ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
51 WORD32 ch, rfpsf, qb;
52 WORD32 qmf_global_offset;
53 WORD32 time_slots = pstr_mps_state->time_slots;
54 WORD32 time_slots_x4 = (time_slots << 2);
55 WORD32 qmf_bands = pstr_mps_state->qmf_bands;
56 WORD32 *p_qmf_residual_real_post, *p_qmf_residual_imag_post;
57 VOID *scratch = pstr_mps_state->mps_scratch_mem_v;
58
59 if (pstr_mps_state->up_mix_type != 2) {
60 WORD32 num_ch = pstr_mps_state->num_ott_boxes + pstr_mps_state->num_ttt_boxes;
61 WORD32 rfpsf_max = pstr_mps_state->residual_frames_per_spatial_frame;
62 WORD32 upd_qmf = pstr_mps_state->upd_qmf;
63
64 WORD32 *qmf_residual_real_pre = p_array_struct->qmf_residual_real_pre;
65 WORD32 *qmf_residual_real_post = p_array_struct->qmf_residual_real_post;
66
67 WORD32 *qmf_residual_imag_pre = p_array_struct->qmf_residual_imag_pre;
68 WORD32 *qmf_residual_imag_post = p_array_struct->qmf_residual_imag_post;
69
70 WORD32 *p_res_mdct = p_array_struct->res_mdct;
71
72 for (ch = 0; ch < num_ch; ch++) {
73 if (pstr_mps_state->bs_config.bs_residual_present[ch]) {
74 WORD32 *res_mdct = p_res_mdct;
75 qmf_global_offset = 0;
76
77 p_qmf_residual_real_post = qmf_residual_real_post;
78 p_qmf_residual_imag_post = qmf_residual_imag_post;
79 for (qb = 0; qb < qmf_bands; qb++) {
80 memset(p_qmf_residual_real_post, 0, time_slots_x4);
81 memset(p_qmf_residual_imag_post, 0, time_slots_x4);
82
83 p_qmf_residual_real_post += MAX_TIME_SLOTS;
84 p_qmf_residual_imag_post += MAX_TIME_SLOTS;
85 }
86
87 for (rfpsf = 0; rfpsf < rfpsf_max; rfpsf++) {
88 ixheaacd_mdct2qmf_process(upd_qmf, res_mdct, qmf_residual_real_pre,
89 qmf_residual_real_post, qmf_residual_imag_pre,
90 qmf_residual_imag_post,
91 pstr_mps_state->res_block_type[ch][rfpsf], qmf_global_offset,
92 &(pstr_mps_state->ia_mps_dec_mps_table), scratch, time_slots);
93 qmf_global_offset += upd_qmf;
94 res_mdct += MDCTCOEFX2;
95 }
96 }
97
98 qmf_residual_real_pre += QBXTS;
99 qmf_residual_imag_pre += QBXTS;
100
101 qmf_residual_real_post += QBXTS;
102 qmf_residual_imag_post += QBXTS;
103
104 p_res_mdct += RFX2XMDCTCOEF;
105 }
106 }
107
108 if (pstr_mps_state->arbitrary_downmix == 2) {
109 WORD32 arbdmx_upd_qmf = pstr_mps_state->arbdmx_upd_qmf;
110 WORD32 offset = pstr_mps_state->num_ott_boxes + pstr_mps_state->num_ttt_boxes;
111 WORD32 in_ch = pstr_mps_state->num_input_channels;
112 WORD32 rfpsf_max = pstr_mps_state->arbdmx_frames_per_spatial_frame;
113
114 WORD32 *qmf_residual_real_pre = p_array_struct->qmf_residual_real_pre + offset * QBXTS;
115 WORD32 *qmf_residual_imag_pre = p_array_struct->qmf_residual_imag_pre + offset * QBXTS;
116
117 WORD32 *qmf_residual_real_post = p_array_struct->qmf_residual_real_post + offset * QBXTS;
118 WORD32 *qmf_residual_imag_post = p_array_struct->qmf_residual_imag_post + offset * QBXTS;
119
120 WORD32 *p_res_mdct = p_array_struct->res_mdct + offset * RFX2XMDCTCOEF;
121
122 for (ch = 0; ch < in_ch; ch++) {
123 WORD32 *res_mdct = p_res_mdct;
124 qmf_global_offset = 0;
125
126 p_qmf_residual_real_post = qmf_residual_real_post;
127 p_qmf_residual_imag_post = qmf_residual_imag_post;
128 for (qb = 0; qb < qmf_bands; qb++) {
129 memset(p_qmf_residual_real_post, 0, time_slots_x4);
130 memset(p_qmf_residual_imag_post, 0, time_slots_x4);
131
132 p_qmf_residual_real_post += MAX_TIME_SLOTS;
133 p_qmf_residual_imag_post += MAX_TIME_SLOTS;
134 }
135
136 for (rfpsf = 0; rfpsf < rfpsf_max; rfpsf++) {
137 ixheaacd_mdct2qmf_process(
138 arbdmx_upd_qmf, res_mdct, qmf_residual_real_pre, qmf_residual_real_post,
139 qmf_residual_imag_pre, qmf_residual_imag_post,
140 pstr_mps_state->res_block_type[offset + ch][rfpsf], qmf_global_offset,
141 &(pstr_mps_state->ia_mps_dec_mps_table), scratch, time_slots);
142 qmf_global_offset += arbdmx_upd_qmf;
143 res_mdct += MDCTCOEFX2;
144 }
145
146 qmf_residual_real_pre += QBXTS;
147 qmf_residual_imag_pre += QBXTS;
148
149 qmf_residual_imag_post += QBXTS;
150 qmf_residual_real_post += QBXTS;
151
152 p_res_mdct += RFX2XMDCTCOEF;
153 }
154 }
155 return;
156 }
157
ixheaacd_hybrid_qmf_analysis(ia_heaac_mps_state_struct * pstr_mps_state)158 VOID ixheaacd_hybrid_qmf_analysis(ia_heaac_mps_state_struct *pstr_mps_state) {
159 WORD32 ch;
160 WORD32 in_ch = pstr_mps_state->num_input_channels;
161 WORD32 num_ott_boxes = pstr_mps_state->num_ott_boxes;
162 WORD32 num_ttt_boxes = pstr_mps_state->num_ttt_boxes;
163 WORD32 num_input_channels = in_ch;
164 WORD32 qmf_bands = pstr_mps_state->qmf_bands;
165 WORD32 time_slots = pstr_mps_state->time_slots;
166 WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
167 WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
168 SIZE_T *kernels = pstr_mps_state->kernels;
169 WORD32 *res_bands = pstr_mps_state->res_bands;
170 WORD32 *index = pstr_mps_state->index;
171
172 ia_mps_dec_thyb_filter_state_struct *hyb_filter_state =
173 pstr_mps_state->mps_persistent_mem.hyb_filter_state;
174 ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
175
176 ia_mps_dec_hybrid_tables_struct *hybrid_table_ptr =
177 pstr_mps_state->ia_mps_dec_mps_table.hybrid_table_ptr;
178
179 WORD32 *p_buf_real = p_array_struct->buf_real;
180 WORD32 *p_buf_imag = p_array_struct->buf_imag;
181
182 WORD32 *p_x_real = p_array_struct->x_real;
183 WORD32 *p_x_imag = p_array_struct->x_imag;
184
185 for (ch = 0; ch < in_ch; ch++) {
186 ixheaacd_apply_ana_hyb_filt_bank_create_x(&hyb_filter_state[ch], p_buf_real, p_buf_imag,
187 qmf_bands, time_slots, p_x_real, p_x_imag,
188 hybrid_table_ptr);
189 pstr_mps_state->index[ch] = hybrid_bands;
190
191 p_buf_real += TSXHB;
192 p_buf_imag += TSXHB;
193
194 p_x_real += TSXHB;
195 p_x_imag += TSXHB;
196 }
197
198 if ((pstr_mps_state->residual_coding) && (pstr_mps_state->up_mix_type != 2)) {
199 WORD32 *qmf_residual_real = p_array_struct->qmf_residual_real_pre;
200 WORD32 *qmf_residual_imag = p_array_struct->qmf_residual_imag_pre;
201
202 WORD32 *p_dry_real = p_array_struct->w_dry_real;
203 WORD32 *p_dry_imag = p_array_struct->w_dry_imag;
204
205 for (ch = 0; ch < num_ott_boxes; ch++) {
206 if (res_bands[ch] > 0) {
207 ixheaacd_apply_ana_hyb_filt_bank_merge_res_decor(
208 &hyb_filter_state[ch + num_input_channels], qmf_residual_real, qmf_residual_imag,
209 qmf_bands, time_slots, p_dry_real, p_dry_imag, hybrid_table_ptr);
210 }
211 qmf_residual_real += QBXTS;
212 qmf_residual_imag += QBXTS;
213
214 p_dry_real += TSXHB;
215 p_dry_imag += TSXHB;
216 }
217
218 for (ch = num_ott_boxes; ch < num_ott_boxes + num_ttt_boxes; ch++, in_ch++) {
219 if (res_bands[ch] > 0) {
220 ixheaacd_apply_ana_hyb_filt_bank_create_x_res(
221 &hyb_filter_state[ch + num_input_channels], qmf_residual_real, qmf_residual_imag,
222 qmf_bands, time_slots, p_x_real, p_x_imag, kernels, res_bands[ch], hybrid_bands,
223 num_parameter_bands, &index[in_ch], hybrid_table_ptr);
224 } else
225 index[in_ch] = 0;
226
227 qmf_residual_real += QBXTS;
228 qmf_residual_imag += QBXTS;
229
230 p_x_real += TSXHB;
231 p_x_imag += TSXHB;
232 }
233 }
234
235 in_ch = num_input_channels + num_ttt_boxes;
236 if (pstr_mps_state->arbitrary_downmix == 2) {
237 WORD32 offset = num_ott_boxes + num_ttt_boxes;
238
239 WORD32 *qmf_residual_real = p_array_struct->qmf_residual_real_pre + offset * QBXTS;
240 WORD32 *qmf_residual_imag = p_array_struct->qmf_residual_imag_pre + offset * QBXTS;
241
242 p_x_real = p_array_struct->x_real + in_ch * TSXHB;
243 p_x_imag = p_array_struct->x_imag + in_ch * TSXHB;
244 for (ch = 0; ch < num_input_channels; ch++, in_ch++) {
245 ixheaacd_apply_ana_hyb_filt_bank_create_x_res(
246 &hyb_filter_state[offset + ch + num_input_channels], qmf_residual_real,
247 qmf_residual_imag, qmf_bands, time_slots, p_x_real, p_x_imag, kernels,
248 pstr_mps_state->arbdmx_residual_bands, hybrid_bands, num_parameter_bands, &index[in_ch],
249 hybrid_table_ptr);
250
251 qmf_residual_real += QBXTS;
252 qmf_residual_imag += QBXTS;
253
254 p_x_real += TSXHB;
255 p_x_imag += TSXHB;
256 }
257 }
258 }
259
ixheaacd_merge_res_decor(ia_heaac_mps_state_struct * pstr_mps_state)260 VOID ixheaacd_merge_res_decor(ia_heaac_mps_state_struct *pstr_mps_state) {
261 WORD32 ts, qs, row, res;
262
263 WORD32 temp_1;
264 SIZE_T *idx;
265
266 ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
267 ia_mps_dec_auxilary_struct *p_aux_struct = pstr_mps_state->aux_struct;
268 WORD32 time_slots = pstr_mps_state->time_slots;
269 WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
270 WORD32 num_direct_signals = pstr_mps_state->num_direct_signals;
271 WORD32 num_w_channels = pstr_mps_state->num_w_channels;
272 WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
273 SIZE_T *kernels_ptr = pstr_mps_state->kernels;
274
275 WORD32 *p_buf_real, *p_buf_imag, *p_buf_re, *p_buf_im;
276 WORD32 *buf_real_ch4, *buf_imag_ch4;
277 WORD32 *buf_real_ch3, *buf_imag_ch3;
278
279 p_buf_real = p_array_struct->buffer_real + TSXHBX5;
280 p_buf_imag = p_array_struct->buffer_imag + TSXHBX5;
281
282 for (ts = 0; ts < time_slots; ts++) {
283 p_buf_re = p_buf_real;
284 p_buf_im = p_buf_imag;
285
286 buf_real_ch4 = p_buf_real - TSXHB;
287 buf_imag_ch4 = p_buf_imag - TSXHB;
288
289 buf_real_ch3 = buf_real_ch4 - TSXHB;
290 buf_imag_ch3 = buf_imag_ch4 - TSXHB;
291
292 for (qs = 0; qs < hybrid_bands; qs++) {
293 if ((kernels_ptr[qs] < ((UWORD32)(p_aux_struct->ttt_config[0][0].stop_band)) &&
294 p_aux_struct->ttt_config[0][0].use_ttt_decorr) ||
295 (kernels_ptr[qs] >= ((UWORD32)p_aux_struct->ttt_config[1][0].start_band) &&
296 p_aux_struct->ttt_config[1][0].use_ttt_decorr)) {
297 temp_1 = (WORD32)ONE_BY_SQRT_TWO_Q30;
298
299 *p_buf_re = ixheaacd_mps_mult32_shr_30(*p_buf_re, temp_1);
300 *p_buf_re += (*buf_real_ch3 + *buf_real_ch4);
301
302 *p_buf_im = ixheaacd_mps_mult32_shr_30(*p_buf_im, temp_1);
303 *p_buf_im += (*buf_imag_ch3 + *buf_imag_ch4);
304 }
305 p_buf_re++;
306 p_buf_im++;
307
308 buf_real_ch4++;
309 buf_imag_ch4++;
310
311 buf_real_ch3++;
312 buf_imag_ch3++;
313 }
314 p_buf_real += MAX_HYBRID_BANDS;
315 p_buf_imag += MAX_HYBRID_BANDS;
316 }
317
318 if (pstr_mps_state->residual_coding) {
319 for (row = num_direct_signals; row < num_w_channels; row++) {
320 WORD32 resband;
321 res = ixheaacd_get_res_idx(pstr_mps_state, row);
322 resband = pstr_mps_state->res_bands[res];
323
324 if (resband == 1 && (num_parameter_bands == 20 || num_parameter_bands == 28))
325 pstr_mps_state->index[res] = 3;
326 else {
327 idx = &kernels_ptr[0];
328 for (qs = 0; qs < hybrid_bands; qs++) {
329 if (*idx++ >= (SIZE_T)resband) {
330 pstr_mps_state->index[res] = qs;
331 qs = hybrid_bands;
332 }
333 }
334 }
335 }
336 }
337 }
338
ixheaacd_create_w(ia_heaac_mps_state_struct * pstr_mps_state)339 VOID ixheaacd_create_w(ia_heaac_mps_state_struct *pstr_mps_state) {
340 WORD32 k;
341 ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
342 WORD32 num_direct_signals = pstr_mps_state->num_direct_signals;
343 WORD32 counter = num_direct_signals + pstr_mps_state->num_decor_signals;
344 WORD32 time_slots = pstr_mps_state->time_slots;
345 WORD32 offset = num_direct_signals * TSXHB;
346 WORD32 *p_buffer_real = p_array_struct->buf_real + offset;
347 WORD32 *p_buffer_imag = p_array_struct->buf_imag + offset;
348
349 WORD32 *p_buf_real = p_array_struct->buffer_real + offset;
350 WORD32 *p_buf_imag = p_array_struct->buffer_imag + offset;
351
352 for (k = num_direct_signals; k < counter; k++) {
353 ixheaacd_decorr_apply(pstr_mps_state, time_slots, p_buffer_real, p_buffer_imag, p_buf_real,
354 p_buf_imag, k);
355
356 p_buffer_real += TSXHB;
357 p_buffer_imag += TSXHB;
358
359 p_buf_real += TSXHB;
360 p_buf_imag += TSXHB;
361 }
362 ixheaacd_merge_res_decor(pstr_mps_state);
363 }
364
ixheaacd_update_buffers(ia_heaac_mps_state_struct * pstr_mps_state)365 VOID ixheaacd_update_buffers(ia_heaac_mps_state_struct *pstr_mps_state) {
366 ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
367 WORD32 *temp_addr = p_array_struct->qmf_residual_real_post;
368 p_array_struct->qmf_residual_real_post = p_array_struct->qmf_residual_real_pre;
369 p_array_struct->qmf_residual_real_pre = temp_addr;
370
371 temp_addr = p_array_struct->qmf_residual_imag_post;
372 p_array_struct->qmf_residual_imag_post = p_array_struct->qmf_residual_imag_pre;
373 p_array_struct->qmf_residual_imag_pre = temp_addr;
374
375 p_array_struct->buffer_real = p_array_struct->qmf_residual_real_post;
376 p_array_struct->buffer_imag = p_array_struct->qmf_residual_imag_post;
377
378 p_array_struct->m1_param = (ia_mps_dec_m1_param_struct *)p_array_struct->buffer_real;
379 }
380