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 "ixheaac_type_def.h"
22 #include "ixheaacd_mps_struct_def.h"
23 #include "ixheaacd_mps_res_rom.h"
24 #include "ixheaacd_mps_aac_struct.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaac_basic_ops32.h"
27 #include "ixheaac_basic_ops40.h"
28 #include "ixheaacd_bitbuffer.h"
29 #include "ixheaacd_common_rom.h"
30 #include "ixheaacd_sbrdecsettings.h"
31 #include "ixheaacd_sbr_scale.h"
32 #include "ixheaacd_env_extr_part.h"
33 #include "ixheaacd_sbr_rom.h"
34 #include "ixheaacd_hybrid.h"
35 #include "ixheaacd_ps_dec.h"
36 #include "ixheaacd_mps_polyphase.h"
37 #include "ixheaacd_config.h"
38 #include "ixheaacd_qmf_dec.h"
39 #include "ixheaacd_mps_dec.h"
40 #include "ixheaacd_mps_macro_def.h"
41 #include "ixheaacd_mps_apply_common.h"
42 #include "ixheaacd_mps_basic_op.h"
43 #include "ixheaacd_mps_get_index.h"
44
ixheaacd_apply_m2(ia_heaac_mps_state_struct * pstr_mps_state)45 VOID ixheaacd_apply_m2(ia_heaac_mps_state_struct *pstr_mps_state) {
46 WORD32 ts, qs, row, col;
47 ia_heaac_mps_state_struct *curr_state = pstr_mps_state;
48 ia_mps_persistent_mem *persistent_mem = &curr_state->mps_persistent_mem;
49 ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
50 ia_mps_dec_m2_param_struct *p_m2_param = pstr_mps_state->aux_struct->m2_param;
51
52 WORD32 num_direct_signals = curr_state->num_direct_signals;
53 WORD32 temp_1, loop_counter, col_counter = num_direct_signals + curr_state->num_decor_signals;
54
55 WORD32 *rout_ptr, *rout_kernel_ptr;
56
57 WORD32 *hyb_output_real_dry, *hyb_output_imag_dry, *hyb_output_real_wet, *hyb_output_imag_wet;
58
59 WORD32 *p_hyb_out_dry_real, *p_hyb_out_dry_imag, *p_hyb_out_dry_re, *p_hyb_out_dry_im;
60
61 WORD32 *w_wet_real, *w_wet_imag, *w_dry_real, *w_dry_imag;
62
63 WORD32 *m2_decor_real_prev = persistent_mem->m2_decor_real_prev;
64 WORD32 *m2_decor_imag_prev = persistent_mem->m2_decor_imag_prev;
65
66 WORD32 *p_buffer_real, *p_buffer_imag, *p_buffer_re, *p_buffer_im;
67 WORD32 *p_buf_real, *p_buf_imag, *p_buf_re, *p_buf_im;
68
69 WORD32 *m2_resid_real_prev = persistent_mem->m2_resid_real_prev;
70 WORD32 *m2_resid_imag_prev = persistent_mem->m2_resid_imag_prev;
71
72 WORD32 idx = 0;
73 WORD32 w_wet_offset = num_direct_signals * TSXHB;
74
75 WORD32 num_output_channels = curr_state->num_output_channels;
76 WORD32 time_slots = curr_state->time_slots;
77 WORD32 hybrid_bands = curr_state->hybrid_bands;
78 WORD32 m2_param_imag_present = curr_state->m2_param_imag_present;
79 WORD32 num_parameter_bands = curr_state->num_parameter_bands;
80 WORD32 up_mix_type = curr_state->up_mix_type;
81 WORD32 residual_coding = curr_state->residual_coding;
82 WORD32 *index_ptr = curr_state->index;
83
84 SIZE_T params[4];
85
86 params[0] = (SIZE_T)(&curr_state->kernels[0]);
87 params[1] = time_slots;
88 params[2] = num_parameter_bands;
89 params[3] = hybrid_bands;
90
91 rout_ptr = pstr_mps_state->mps_scratch_mem_v;
92 rout_kernel_ptr =
93 rout_ptr + IXHEAAC_GET_SIZE_ALIGNED_TYPE(TSXHB, sizeof(*rout_kernel_ptr), BYTE_ALIGN_8);
94
95 p_hyb_out_dry_real = p_array_struct->hyb_output_real_dry;
96 p_hyb_out_dry_imag = p_array_struct->hyb_output_imag_dry;
97
98 for (row = 0; row < num_output_channels; row++) {
99 hyb_output_real_dry = p_hyb_out_dry_real;
100 hyb_output_imag_dry = p_hyb_out_dry_imag;
101
102 for (ts = 0; ts < time_slots; ts++) {
103 memset(hyb_output_real_dry, 0, (hybrid_bands) * sizeof(hyb_output_real_dry[0]));
104 memset(hyb_output_imag_dry, 0, (hybrid_bands) * sizeof(hyb_output_imag_dry[0]));
105
106 hyb_output_real_dry += MAX_HYBRID_BANDS;
107 hyb_output_imag_dry += MAX_HYBRID_BANDS;
108 }
109
110 p_hyb_out_dry_real += TSXHB;
111 p_hyb_out_dry_imag += TSXHB;
112 }
113
114 if (residual_coding)
115 loop_counter = col_counter;
116 else
117 loop_counter = num_direct_signals;
118
119 idx = 0;
120
121 p_hyb_out_dry_real = p_array_struct->hyb_output_real_dry;
122 p_hyb_out_dry_imag = p_array_struct->hyb_output_imag_dry;
123
124 for (row = 0; row < num_output_channels; row++) {
125 p_buffer_real = p_array_struct->buf_real;
126 p_buffer_imag = p_array_struct->buf_imag;
127
128 for (col = 0; col < num_direct_signals; col++) {
129 p_buffer_re = p_buffer_real;
130 p_buffer_im = p_buffer_imag;
131
132 if (curr_state->m2_param_present[row][col] & 2) {
133 ixheaacd_dec_interp_umx(p_m2_param->m2_resid_real[idx++], rout_ptr, m2_resid_real_prev,
134 pstr_mps_state);
135 ixheaacd_apply_abs_kernels(rout_ptr, rout_kernel_ptr, params);
136
137 p_hyb_out_dry_re = p_hyb_out_dry_real;
138 p_hyb_out_dry_im = p_hyb_out_dry_imag;
139
140 for (ts = 0; ts < time_slots; ts++) {
141 hyb_output_real_dry = p_hyb_out_dry_re;
142 hyb_output_imag_dry = p_hyb_out_dry_im;
143
144 w_dry_real = p_buffer_re;
145 w_dry_imag = p_buffer_im;
146
147 for (qs = 0; qs < hybrid_bands; qs++) {
148 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_real, *rout_kernel_ptr);
149 w_dry_real++;
150 *hyb_output_real_dry = *hyb_output_real_dry + temp_1;
151 hyb_output_real_dry++;
152
153 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_imag, *rout_kernel_ptr);
154 w_dry_imag++;
155 rout_kernel_ptr++;
156 *hyb_output_imag_dry = *hyb_output_imag_dry + temp_1;
157 hyb_output_imag_dry++;
158 }
159 p_buffer_re += MAX_HYBRID_BANDS;
160 p_buffer_im += MAX_HYBRID_BANDS;
161
162 p_hyb_out_dry_re += MAX_HYBRID_BANDS;
163 p_hyb_out_dry_im += MAX_HYBRID_BANDS;
164 }
165 m2_resid_real_prev += num_parameter_bands;
166 }
167 p_buffer_real += TSXHB;
168 p_buffer_imag += TSXHB;
169 }
170
171 for (; col < loop_counter; col++) {
172 WORD32 index;
173 WORD32 res = ixheaacd_get_res_idx(pstr_mps_state, col);
174 index = index_ptr[res];
175
176 if (curr_state->m2_param_present[row][col] & 2) {
177 WORD32 *p_dry_real = p_array_struct->w_dry_real + res * TSXHB;
178 WORD32 *p_dry_imag = p_array_struct->w_dry_imag + res * TSXHB;
179
180 ixheaacd_dec_interp_umx(p_m2_param->m2_resid_real[idx++], rout_ptr, m2_resid_real_prev,
181 pstr_mps_state);
182 ixheaacd_apply_abs_kernels(rout_ptr, rout_kernel_ptr, params);
183
184 p_hyb_out_dry_re = p_hyb_out_dry_real;
185 p_hyb_out_dry_im = p_hyb_out_dry_imag;
186
187 for (ts = 0; ts < time_slots; ts++) {
188 hyb_output_real_dry = p_hyb_out_dry_re;
189 hyb_output_imag_dry = p_hyb_out_dry_im;
190
191 w_dry_real = p_dry_real;
192 w_dry_imag = p_dry_imag;
193
194 for (qs = 0; qs < index; qs++) {
195 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_real, *rout_kernel_ptr);
196 w_dry_real++;
197 *hyb_output_real_dry = *hyb_output_real_dry + temp_1;
198 hyb_output_real_dry++;
199
200 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_imag, *rout_kernel_ptr);
201 w_dry_imag++;
202 rout_kernel_ptr++;
203 *hyb_output_imag_dry = *hyb_output_imag_dry + temp_1;
204 hyb_output_imag_dry++;
205 }
206 rout_kernel_ptr += hybrid_bands - index;
207
208 p_hyb_out_dry_re += MAX_HYBRID_BANDS;
209 p_hyb_out_dry_im += MAX_HYBRID_BANDS;
210
211 p_dry_real += MAX_HYBRID_BANDS;
212 p_dry_imag += MAX_HYBRID_BANDS;
213 }
214 m2_resid_real_prev += num_parameter_bands;
215 }
216 }
217
218 p_hyb_out_dry_real += TSXHB;
219 p_hyb_out_dry_imag += TSXHB;
220 }
221
222 if (up_mix_type == 2) {
223 if (m2_param_imag_present) {
224 if (residual_coding)
225 loop_counter = col_counter;
226 else
227 loop_counter = num_direct_signals;
228
229 idx = 0;
230
231 p_hyb_out_dry_real = p_array_struct->hyb_output_real_dry;
232 p_hyb_out_dry_imag = p_array_struct->hyb_output_imag_dry;
233
234 for (row = 0; row < num_output_channels; row++) {
235 p_buffer_real = p_array_struct->buf_real;
236 p_buffer_imag = p_array_struct->buf_imag;
237
238 for (col = 0; col < num_direct_signals; col++) {
239 p_buffer_re = p_buffer_real;
240 p_buffer_im = p_buffer_imag;
241
242 if (curr_state->m2_param_present[row][col] & 2) {
243 ixheaacd_dec_interp_umx(p_m2_param->m2_resid_imag[idx++], rout_ptr,
244 m2_resid_imag_prev, pstr_mps_state);
245 ixheaacd_apply_abs_kernels(rout_ptr, rout_kernel_ptr, params);
246
247 p_hyb_out_dry_re = p_hyb_out_dry_real;
248 p_hyb_out_dry_im = p_hyb_out_dry_imag;
249
250 for (ts = 0; ts < time_slots; ts++) {
251 hyb_output_real_dry = p_hyb_out_dry_re;
252 hyb_output_imag_dry = p_hyb_out_dry_im;
253
254 w_dry_real = p_buffer_re;
255 w_dry_imag = p_buffer_im;
256
257 for (qs = 0; qs < 2; qs++) {
258 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_imag, *rout_kernel_ptr);
259 w_dry_imag++;
260 *hyb_output_real_dry = *hyb_output_real_dry + temp_1;
261 hyb_output_real_dry++;
262
263 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_real, *rout_kernel_ptr);
264 w_dry_real++;
265 rout_kernel_ptr++;
266 *hyb_output_imag_dry = *hyb_output_imag_dry - temp_1;
267 hyb_output_imag_dry++;
268 }
269
270 for (; qs < hybrid_bands; qs++) {
271 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_imag, *rout_kernel_ptr);
272 w_dry_imag++;
273 *hyb_output_real_dry = *hyb_output_real_dry - temp_1;
274 hyb_output_real_dry++;
275
276 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_real, *rout_kernel_ptr);
277 w_dry_real++;
278 rout_kernel_ptr++;
279 *hyb_output_imag_dry = *hyb_output_imag_dry + temp_1;
280 hyb_output_imag_dry++;
281 }
282 p_buffer_re += MAX_HYBRID_BANDS;
283 p_buffer_im += MAX_HYBRID_BANDS;
284
285 p_hyb_out_dry_re += MAX_HYBRID_BANDS;
286 p_hyb_out_dry_im += MAX_HYBRID_BANDS;
287 }
288 m2_resid_imag_prev += num_parameter_bands;
289 }
290 p_buffer_real += TSXHB;
291 p_buffer_imag += TSXHB;
292 }
293
294 for (; col < loop_counter; col++) {
295 WORD32 index;
296 WORD32 res = ixheaacd_get_res_idx(pstr_mps_state, col);
297 index = index_ptr[res];
298
299 if (curr_state->m2_param_present[row][col] & 2) {
300 WORD32 *p_dry_real = p_array_struct->w_dry_real + res * TSXHB;
301 WORD32 *p_dry_imag = p_array_struct->w_dry_imag + res * TSXHB;
302 ixheaacd_dec_interp_umx(p_m2_param->m2_resid_imag[idx++], rout_ptr,
303 m2_resid_imag_prev, pstr_mps_state);
304 ixheaacd_apply_abs_kernels(rout_ptr, rout_kernel_ptr, params);
305
306 p_hyb_out_dry_re = p_hyb_out_dry_real;
307 p_hyb_out_dry_im = p_hyb_out_dry_imag;
308
309 for (ts = 0; ts < time_slots; ts++) {
310 hyb_output_real_dry = p_hyb_out_dry_re;
311 hyb_output_imag_dry = p_hyb_out_dry_im;
312
313 w_dry_real = p_dry_real;
314 w_dry_imag = p_dry_imag;
315
316 for (qs = 0; qs < 2; qs++) {
317 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_imag, *rout_kernel_ptr);
318 w_dry_imag++;
319 *hyb_output_real_dry = *hyb_output_real_dry + temp_1;
320 hyb_output_real_dry++;
321
322 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_real, *rout_kernel_ptr);
323 w_dry_real++;
324 rout_kernel_ptr++;
325 *hyb_output_imag_dry = *hyb_output_imag_dry - temp_1;
326 hyb_output_imag_dry++;
327 }
328
329 for (; qs < index; qs++) {
330 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_imag, *rout_kernel_ptr);
331 w_dry_imag++;
332 *hyb_output_real_dry = *hyb_output_real_dry - temp_1;
333 hyb_output_real_dry++;
334
335 temp_1 = ixheaacd_mps_mult32_shr_15(*w_dry_real, *rout_kernel_ptr);
336 w_dry_real++;
337 rout_kernel_ptr++;
338 *hyb_output_imag_dry = *hyb_output_imag_dry + temp_1;
339 hyb_output_imag_dry++;
340 }
341 rout_kernel_ptr += hybrid_bands - index;
342
343 p_hyb_out_dry_re += MAX_HYBRID_BANDS;
344 p_hyb_out_dry_im += MAX_HYBRID_BANDS;
345
346 p_dry_real += MAX_HYBRID_BANDS;
347 p_dry_imag += MAX_HYBRID_BANDS;
348 }
349 m2_resid_imag_prev += num_parameter_bands;
350 }
351 }
352 p_hyb_out_dry_real += TSXHB;
353 p_hyb_out_dry_imag += TSXHB;
354 }
355 }
356 }
357 p_buffer_real = p_array_struct->buf_real;
358 p_buffer_imag = p_array_struct->buf_imag;
359
360 for (row = 0; row < num_output_channels; row++) {
361 hyb_output_real_wet = p_buffer_real;
362 hyb_output_imag_wet = p_buffer_imag;
363
364 for (ts = 0; ts < time_slots; ts++) {
365 memset(hyb_output_real_wet, 0, (hybrid_bands) * sizeof(*hyb_output_real_wet));
366 memset(hyb_output_imag_wet, 0, (hybrid_bands) * sizeof(*hyb_output_imag_wet));
367
368 hyb_output_real_wet += MAX_HYBRID_BANDS;
369 hyb_output_imag_wet += MAX_HYBRID_BANDS;
370 }
371 p_buffer_real += TSXHB;
372 p_buffer_imag += TSXHB;
373 }
374 idx = 0;
375
376 p_buffer_real = p_array_struct->buf_real;
377 p_buffer_imag = p_array_struct->buf_imag;
378
379 for (row = 0; row < num_output_channels; row++) {
380 p_buf_real = p_array_struct->buffer_real + w_wet_offset;
381 p_buf_imag = p_array_struct->buffer_imag + w_wet_offset;
382 for (col = num_direct_signals; col < col_counter; col++) {
383 if (curr_state->m2_param_present[row][col] & 1) {
384 ixheaacd_dec_interp_umx(p_m2_param->m2_decor_real[idx++], rout_ptr, m2_decor_real_prev,
385 pstr_mps_state);
386
387 ixheaacd_apply_abs_kernels(rout_ptr, rout_kernel_ptr, params);
388 p_buffer_re = p_buffer_real;
389 p_buffer_im = p_buffer_imag;
390
391 p_buf_re = p_buf_real;
392 p_buf_im = p_buf_imag;
393 for (ts = 0; ts < time_slots; ts++) {
394 hyb_output_real_wet = p_buffer_re;
395 hyb_output_imag_wet = p_buffer_im;
396
397 w_wet_real = p_buf_re;
398 w_wet_imag = p_buf_im;
399
400 for (qs = 0; qs < hybrid_bands; qs++) {
401 temp_1 = ixheaacd_mps_mult32_shr_15(*w_wet_real, *rout_kernel_ptr);
402 w_wet_real++;
403 *hyb_output_real_wet = *hyb_output_real_wet + temp_1;
404 hyb_output_real_wet++;
405
406 temp_1 = ixheaacd_mps_mult32_shr_15(*w_wet_imag, *rout_kernel_ptr);
407 w_wet_imag++;
408 rout_kernel_ptr++;
409 *hyb_output_imag_wet = *hyb_output_imag_wet + temp_1;
410 hyb_output_imag_wet++;
411 }
412 p_buffer_re += MAX_HYBRID_BANDS;
413 p_buffer_im += MAX_HYBRID_BANDS;
414
415 p_buf_re += MAX_HYBRID_BANDS;
416 p_buf_im += MAX_HYBRID_BANDS;
417 }
418 m2_decor_real_prev += num_parameter_bands;
419 }
420 p_buf_real += TSXHB;
421 p_buf_imag += TSXHB;
422 }
423 p_buffer_real += TSXHB;
424 p_buffer_imag += TSXHB;
425 }
426
427 if (up_mix_type == 2) {
428 if (m2_param_imag_present) {
429 idx = 0;
430
431 p_buffer_real = p_array_struct->buf_real;
432 p_buffer_imag = p_array_struct->buf_imag;
433
434 for (row = 0; row < num_output_channels; row++) {
435 m2_decor_imag_prev += num_parameter_bands * num_direct_signals;
436 p_buf_real = p_array_struct->buffer_real + w_wet_offset;
437 p_buf_imag = p_array_struct->buffer_imag + w_wet_offset;
438 for (col = num_direct_signals; col < col_counter; col++) {
439 if (curr_state->m2_param_present[row][col] & 1) {
440 ixheaacd_dec_interp_umx(p_m2_param->m2_decor_imag[idx++], rout_ptr,
441 m2_decor_imag_prev, pstr_mps_state);
442 ixheaacd_apply_abs_kernels(rout_ptr, rout_kernel_ptr, params);
443
444 p_buffer_re = p_buffer_real;
445 p_buffer_im = p_buffer_imag;
446
447 p_buf_re = p_buf_real;
448 p_buf_im = p_buf_imag;
449 for (ts = 0; ts < time_slots; ts++) {
450 hyb_output_real_wet = p_buffer_re;
451 hyb_output_imag_wet = p_buffer_im;
452
453 w_wet_real = p_buf_re;
454 w_wet_imag = p_buf_im;
455
456 for (qs = 0; qs < 2; qs++) {
457 temp_1 = ixheaacd_mps_mult32_shr_15(*w_wet_imag, *rout_kernel_ptr);
458 w_wet_imag++;
459 *hyb_output_real_wet = *hyb_output_real_wet + temp_1;
460 hyb_output_real_wet++;
461
462 temp_1 = ixheaacd_mps_mult32_shr_15(*w_wet_real, *rout_kernel_ptr);
463 w_wet_real++;
464 rout_kernel_ptr++;
465 *hyb_output_imag_wet = *hyb_output_imag_wet - temp_1;
466 hyb_output_imag_wet++;
467 }
468
469 for (; qs < hybrid_bands; qs++) {
470 temp_1 = ixheaacd_mps_mult32_shr_15(*w_wet_imag, *rout_kernel_ptr);
471 w_wet_imag++;
472 *hyb_output_real_wet = *hyb_output_real_wet - temp_1;
473 hyb_output_real_wet++;
474
475 temp_1 = ixheaacd_mps_mult32_shr_15(*w_wet_real, *rout_kernel_ptr);
476 w_wet_real++;
477 rout_kernel_ptr++;
478 *hyb_output_imag_wet = *hyb_output_imag_wet + temp_1;
479 hyb_output_imag_wet++;
480 }
481 p_buffer_re += MAX_HYBRID_BANDS;
482 p_buffer_im += MAX_HYBRID_BANDS;
483
484 p_buf_re += MAX_HYBRID_BANDS;
485 p_buf_im += MAX_HYBRID_BANDS;
486 }
487 m2_decor_imag_prev += num_parameter_bands;
488 }
489 p_buf_real += TSXHB;
490 p_buf_imag += TSXHB;
491 }
492 p_buffer_real += TSXHB;
493 p_buffer_imag += TSXHB;
494 }
495 }
496 }
497 return;
498 }
499