xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_mps_apply_m2.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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