| /****************************************************************************** |
| * |
| * Copyright (C) 2023 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| ***************************************************************************** |
| * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
| */ |
| #include <string.h> |
| #include "ixheaac_type_def.h" |
| #include "ixheaacd_mps_struct_def.h" |
| #include "ixheaacd_mps_res_rom.h" |
| #include "ixheaacd_mps_aac_struct.h" |
| #include "ixheaac_constants.h" |
| #include "ixheaac_basic_ops32.h" |
| #include "ixheaac_basic_ops40.h" |
| #include "ixheaacd_bitbuffer.h" |
| #include "ixheaacd_common_rom.h" |
| #include "ixheaacd_sbrdecsettings.h" |
| #include "ixheaacd_sbr_scale.h" |
| #include "ixheaacd_env_extr_part.h" |
| #include "ixheaacd_sbr_rom.h" |
| #include "ixheaacd_hybrid.h" |
| #include "ixheaacd_ps_dec.h" |
| #include "ixheaacd_mps_polyphase.h" |
| #include "ixheaacd_config.h" |
| #include "ixheaacd_qmf_dec.h" |
| #include "ixheaacd_mps_dec.h" |
| #include "ixheaacd_mps_macro_def.h" |
| #include "ixheaacd_mps_apply_common.h" |
| #include "ixheaacd_mps_basic_op.h" |
| |
| VOID ixheaacd_mps_apply_m1(ia_heaac_mps_state_struct *pstr_mps_state) { |
| ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct; |
| ia_mps_dec_m1_param_struct *m1_param = p_array_struct->m1_param; |
| WORD32 ts, qs, row, col; |
| WORD32 temp_1, temp_2; |
| WORD32 *rout_real_ptr, *rout_imag_ptr, *rout_kernel_real_ptr, *rout_kernel_imag_ptr; |
| WORD32 *v_real, *v_imag, *x_real, *x_imag; |
| WORD32 *p_buffer_real, *p_buffer_imag, *p_v_real, *p_v_imag; |
| |
| ia_heaac_mps_state_struct *curr_state = pstr_mps_state; |
| WORD32 *m1_param_real_prev = curr_state->mps_persistent_mem.m1_param_real_prev; |
| WORD32 *m1_param_imag_prev = curr_state->mps_persistent_mem.m1_param_imag_prev; |
| WORD32 imag_present = curr_state->m1_param_imag_present; |
| WORD32 v_channels = curr_state->num_v_channels; |
| WORD32 x_channels = curr_state->num_x_channels; |
| WORD32 hybrid_bands = curr_state->hybrid_bands; |
| WORD32 num_parameter_bands = curr_state->num_parameter_bands; |
| WORD32 *index = curr_state->index; |
| |
| WORD32 *p_x_re, *p_x_im; |
| |
| WORD32 hyb_bands = hybrid_bands; |
| WORD32 time_slots = curr_state->time_slots; |
| SIZE_T params[4]; |
| |
| params[0] = (SIZE_T)(&curr_state->kernels[0]); |
| params[1] = time_slots; |
| params[2] = num_parameter_bands; |
| params[3] = hybrid_bands; |
| |
| rout_real_ptr = pstr_mps_state->mps_scratch_mem_v; |
| rout_kernel_real_ptr = rout_real_ptr + TSXHB; |
| rout_imag_ptr = rout_kernel_real_ptr + TSXHB; |
| rout_kernel_imag_ptr = rout_imag_ptr + TSXHB; |
| |
| p_buffer_real = p_array_struct->buf_real; |
| p_buffer_imag = p_array_struct->buf_imag; |
| |
| for (row = 0; row < v_channels; row++) { |
| v_real = p_buffer_real; |
| v_imag = p_buffer_imag; |
| |
| for (ts = 0; ts < time_slots; ts++) { |
| memset(v_real, 0, hybrid_bands * sizeof(v_real[0])); |
| memset(v_imag, 0, hybrid_bands * sizeof(v_imag[0])); |
| |
| v_real += MAX_HYBRID_BANDS; |
| v_imag += MAX_HYBRID_BANDS; |
| } |
| p_buffer_real += TSXHB; |
| p_buffer_imag += TSXHB; |
| } |
| |
| p_buffer_real = p_array_struct->buf_real; |
| p_buffer_imag = p_array_struct->buf_imag; |
| |
| if (!imag_present) { |
| for (row = 0; row < v_channels; row++) { |
| WORD32 *p_x_real = p_array_struct->x_real; |
| WORD32 *p_x_imag = p_array_struct->x_imag; |
| |
| for (col = 0; col < x_channels; col++) { |
| if (pstr_mps_state->m1_param_present[row][col]) { |
| WORD32 idx = index[col]; |
| |
| ixheaacd_dec_interp_umx(m1_param->m1_param_real[row][col], rout_real_ptr, |
| m1_param_real_prev, pstr_mps_state); |
| ixheaacd_apply_abs_kernels(rout_real_ptr, rout_kernel_real_ptr, params); |
| |
| p_v_real = p_buffer_real; |
| p_v_imag = p_buffer_imag; |
| |
| p_x_re = p_x_real; |
| p_x_im = p_x_imag; |
| |
| for (ts = 0; ts < time_slots; ts++) { |
| v_real = p_v_real; |
| v_imag = p_v_imag; |
| |
| x_real = p_x_re; |
| x_imag = p_x_im; |
| |
| for (qs = 0; qs < idx; qs++) { |
| temp_1 = ixheaacd_mps_mult32_shr_15(*x_real, *rout_kernel_real_ptr); |
| *v_real = *v_real + temp_1; |
| v_real++; |
| |
| temp_1 = ixheaacd_mps_mult32_shr_15(*x_imag, *rout_kernel_real_ptr); |
| rout_kernel_real_ptr++; |
| *v_imag = *v_imag + temp_1; |
| v_imag++; |
| |
| x_real++; |
| x_imag++; |
| } |
| rout_kernel_real_ptr += hyb_bands - idx; |
| |
| p_v_real += MAX_HYBRID_BANDS; |
| p_v_imag += MAX_HYBRID_BANDS; |
| |
| p_x_re += MAX_HYBRID_BANDS; |
| p_x_im += MAX_HYBRID_BANDS; |
| } |
| |
| m1_param_real_prev += num_parameter_bands; |
| |
| p_x_real += TSXHB; |
| p_x_imag += TSXHB; |
| } else { |
| m1_param_real_prev += num_parameter_bands; |
| |
| p_x_real += TSXHB; |
| p_x_imag += TSXHB; |
| } |
| } |
| p_buffer_real += TSXHB; |
| p_buffer_imag += TSXHB; |
| } |
| } else { |
| for (row = 0; row < v_channels; row++) { |
| WORD32 *p_x_real = p_array_struct->x_real; |
| WORD32 *p_x_imag = p_array_struct->x_imag; |
| |
| for (col = 0; col < x_channels; col++) { |
| if (pstr_mps_state->m1_param_present[row][col]) { |
| WORD32 idx = index[col]; |
| |
| ixheaacd_dec_interp_umx(m1_param->m1_param_real[row][col], rout_real_ptr, |
| m1_param_real_prev, pstr_mps_state); |
| ixheaacd_dec_interp_umx(m1_param->m1_param_imag[row][col], rout_imag_ptr, |
| m1_param_imag_prev, pstr_mps_state); |
| ixheaacd_apply_abs_kernels(rout_real_ptr, rout_kernel_real_ptr, params); |
| ixheaacd_apply_abs_kernels(rout_imag_ptr, rout_kernel_imag_ptr, params); |
| |
| p_v_real = p_buffer_real; |
| p_v_imag = p_buffer_imag; |
| |
| p_x_re = p_x_real; |
| p_x_im = p_x_imag; |
| |
| for (ts = 0; ts < time_slots; ts++) { |
| v_real = p_v_real; |
| v_imag = p_v_imag; |
| |
| x_real = p_x_re; |
| x_imag = p_x_im; |
| for (qs = 0; qs < 2; qs++) { |
| temp_1 = ixheaacd_mps_mult32_shr_15(*x_real, *rout_kernel_real_ptr); |
| temp_2 = ixheaacd_mps_mult32_shr_15(*x_imag, *rout_kernel_imag_ptr); |
| temp_1 += temp_2; |
| |
| *v_real = *v_real + temp_1; |
| v_real++; |
| |
| temp_1 = ixheaacd_mps_mult32_shr_15(*x_imag, *rout_kernel_real_ptr); |
| rout_kernel_real_ptr++; |
| temp_2 = ixheaacd_mps_mult32_shr_15(*x_real, *rout_kernel_imag_ptr); |
| rout_kernel_imag_ptr++; |
| temp_1 -= temp_2; |
| |
| *v_imag = *v_imag + temp_1; |
| v_imag++; |
| |
| x_real++; |
| x_imag++; |
| } |
| for (; qs < idx; qs++) { |
| temp_1 = ixheaacd_mps_mult32_shr_15(*x_real, *rout_kernel_real_ptr); |
| temp_2 = ixheaacd_mps_mult32_shr_15(*x_imag, *rout_kernel_imag_ptr); |
| temp_1 -= temp_2; |
| |
| *v_real = *v_real + temp_1; |
| v_real++; |
| |
| temp_1 = ixheaacd_mps_mult32_shr_15(*x_imag, *rout_kernel_real_ptr); |
| rout_kernel_real_ptr++; |
| temp_2 = ixheaacd_mps_mult32_shr_15(*x_real, *rout_kernel_imag_ptr); |
| rout_kernel_imag_ptr++; |
| temp_1 += temp_2; |
| |
| *v_imag = *v_imag + temp_1; |
| v_imag++; |
| |
| x_real++; |
| x_imag++; |
| } |
| rout_kernel_real_ptr += hyb_bands - idx; |
| rout_kernel_imag_ptr += hyb_bands - idx; |
| |
| p_v_real += MAX_HYBRID_BANDS; |
| p_v_imag += MAX_HYBRID_BANDS; |
| |
| p_x_re += MAX_HYBRID_BANDS; |
| p_x_im += MAX_HYBRID_BANDS; |
| } |
| |
| m1_param_real_prev += num_parameter_bands; |
| m1_param_imag_prev += num_parameter_bands; |
| |
| p_x_real += TSXHB; |
| p_x_imag += TSXHB; |
| } else { |
| m1_param_real_prev += num_parameter_bands; |
| m1_param_imag_prev += num_parameter_bands; |
| |
| p_x_real += TSXHB; |
| p_x_imag += TSXHB; |
| } |
| } |
| p_buffer_real += TSXHB; |
| p_buffer_imag += TSXHB; |
| } |
| } |
| return; |
| } |