/****************************************************************************** * * * Copyright (C) 2018 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 "ixheaacd_sbr_common.h" #include <ixheaacd_type_def.h> #include "ixheaacd_constants.h" #include <ixheaacd_basic_ops32.h> #include <ixheaacd_basic_ops16.h> #include <ixheaacd_basic_ops40.h> #include "ixheaacd_basic_ops.h" #include "ixheaacd_defines.h" #include <ixheaacd_aac_rom.h> #include "ixheaacd_bitbuffer.h" #include "ixheaacd_common_rom.h" #include "ixheaacd_basic_funcs.h" #include <ixheaacd_basic_op.h> #include "ixheaacd_intrinsics.h" #include "ixheaacd_pulsedata.h" #include "ixheaacd_pns.h" #include "ixheaacd_drc_data_struct.h" #include "ixheaacd_lt_predict.h" #include "ixheaacd_channelinfo.h" #include "ixheaacd_channel.h" #include "ixheaacd_drc_dec.h" #include "ixheaacd_audioobjtypes.h" #include "ixheaacd_stereo.h" VOID ixheaacd_ms_stereo_process( ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2], ia_aac_dec_tables_struct *ptr_aac_tables) { WORD32 win_grp, grp_len, k; WORD32 *l_spec = ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff; WORD32 *r_spec = ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff; WORD8 *ptr_group_len = ptr_aac_dec_channel_info[LEFT]->str_ics_info.window_group_length; const WORD8 *ptr_sfb_width = ptr_aac_tables ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT] ->str_ics_info.window_sequence] .sfb_width; UWORD8 *ptr_ms_used = &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0]; for (win_grp = 0; win_grp < ptr_aac_dec_channel_info[LEFT]->str_ics_info.num_window_groups; win_grp++) { for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) { WORD32 sfb; WORD32 ixheaacd_drc_offset = 0; for (sfb = 0; sfb < ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb; sfb++) { ixheaacd_drc_offset += ptr_sfb_width[sfb]; if (*ptr_ms_used++) { for (k = 0; k < ptr_sfb_width[sfb]; k = k + 2) { WORD32 left_coef = *l_spec; WORD32 right_coef = *r_spec; WORD32 left_coef2 = *(l_spec + 1); WORD32 right_coef2 = *(r_spec + 1); *l_spec++ = ixheaacd_add32_sat(left_coef, right_coef); *r_spec++ = ixheaacd_sub32_sat(left_coef, right_coef); *l_spec++ = ixheaacd_add32_sat(left_coef2, right_coef2); *r_spec++ = ixheaacd_sub32_sat(left_coef2, right_coef2); } } else { l_spec += ptr_sfb_width[sfb]; r_spec += ptr_sfb_width[sfb]; } } ptr_ms_used -= ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb; l_spec = l_spec + 128 - ixheaacd_drc_offset; r_spec = r_spec + 128 - ixheaacd_drc_offset; } ptr_ms_used += JOINT_STEREO_MAX_BANDS; } } static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32l(WORD32 a, WORD32 b) { WORD32 result; WORD64 temp_result; temp_result = (WORD64)a * (WORD64)b; result = (WORD32)(temp_result >> 16); return (result); } VOID ixheaacd_intensity_stereo_process( ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2], ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type, WORD32 aac_sf_data_resil_flag) { UWORD8 *ptr_ms_used = &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0]; WORD8 *ptr_code_book = &ptr_aac_dec_channel_info[RIGHT]->ptr_code_book[0]; WORD16 *ptr_scale_factor = &ptr_aac_dec_channel_info[RIGHT]->ptr_scale_factor[0]; WORD32 *r_spec = &ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff[0]; WORD32 *l_spec = &ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff[0]; WORD8 *ptr_group_len = ptr_aac_dec_channel_info[RIGHT]->str_ics_info.window_group_length; const WORD8 *ptr_sfb_width = ptr_aac_tables ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT] ->str_ics_info.window_sequence] .sfb_width; WORD32 *ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table; WORD32 win_grp, grp_len, k; for (win_grp = 0; win_grp < ptr_aac_dec_channel_info[RIGHT]->str_ics_info.num_window_groups; win_grp++) { for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) { WORD32 sfb; WORD32 ixheaacd_drc_offset = 0; for (sfb = 0; sfb < ptr_aac_dec_channel_info[RIGHT]->str_ics_info.max_sfb; sfb++) { WORD8 code_book = ptr_code_book[sfb]; ixheaacd_drc_offset += ptr_sfb_width[sfb]; if (((code_book >= INTENSITY_HCB2) && ((object_type != AOT_ER_AAC_ELD) && (object_type != AOT_ER_AAC_LD))) || (((code_book == INTENSITY_HCB2) || (code_book == INTENSITY_HCB)) && ((object_type == AOT_ER_AAC_ELD) || (object_type == AOT_ER_AAC_LD)))) { WORD32 sfb_factor, scale; WORD32 scf_exp; sfb_factor = (ptr_scale_factor[sfb]); if (aac_sf_data_resil_flag) sfb_factor = -sfb_factor; scf_exp = (sfb_factor >> 2); scale = *(ptr_scale_table + (sfb_factor & 3)); if (!((ptr_ms_used[sfb]) ^ (code_book & 0x1))) { scale = ixheaacd_negate32(scale); } scf_exp = -(scf_exp + 2); for (k = 0; k < ptr_sfb_width[sfb]; k++) { WORD32 temp, shift_val; temp = *l_spec++; shift_val = ixheaacd_norm32(temp); temp = ixheaacd_shl32(temp, shift_val); temp = ixheaacd_mult32x16in32l(temp, scale); shift_val = shift_val + scf_exp; if (shift_val < 0) { temp = ixheaacd_shl32_sat(temp, -shift_val); } else { temp = ixheaacd_shr32(temp, shift_val); } *r_spec++ = temp; } } else { l_spec += ptr_sfb_width[sfb]; r_spec += ptr_sfb_width[sfb]; } } l_spec += 128 - ixheaacd_drc_offset; r_spec += 128 - ixheaacd_drc_offset; } ptr_ms_used += 64; ptr_code_book += 16; ptr_scale_factor += 16; } }