1 /****************************************************************************** 2 * * 3 * Copyright (C) 2018 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 "ixheaacd_sbr_common.h" 21 #include <ixheaacd_type_def.h> 22 23 #include "ixheaacd_constants.h" 24 #include <ixheaacd_basic_ops32.h> 25 #include <ixheaacd_basic_ops16.h> 26 #include <ixheaacd_basic_ops40.h> 27 #include "ixheaacd_basic_ops.h" 28 29 #include "ixheaacd_defines.h" 30 #include <ixheaacd_aac_rom.h> 31 #include "ixheaacd_bitbuffer.h" 32 #include "ixheaacd_common_rom.h" 33 #include "ixheaacd_basic_funcs.h" 34 35 #include <ixheaacd_basic_op.h> 36 #include "ixheaacd_intrinsics.h" 37 38 #include "ixheaacd_pulsedata.h" 39 40 #include "ixheaacd_pns.h" 41 #include "ixheaacd_drc_data_struct.h" 42 43 #include "ixheaacd_lt_predict.h" 44 #include "ixheaacd_channelinfo.h" 45 #include "ixheaacd_channel.h" 46 #include "ixheaacd_drc_dec.h" 47 #include "ixheaacd_audioobjtypes.h" 48 49 #include "ixheaacd_stereo.h" 50 51 VOID ixheaacd_ms_stereo_process( 52 ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2], 53 ia_aac_dec_tables_struct *ptr_aac_tables) 54 55 { 56 WORD32 win_grp, grp_len, k; 57 WORD32 *l_spec = ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff; 58 WORD32 *r_spec = ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff; 59 WORD8 *ptr_group_len = 60 ptr_aac_dec_channel_info[LEFT]->str_ics_info.window_group_length; 61 const WORD8 *ptr_sfb_width = 62 ptr_aac_tables 63 ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT] 64 ->str_ics_info.window_sequence] 65 .sfb_width; 66 67 UWORD8 *ptr_ms_used = 68 &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0]; 69 70 for (win_grp = 0; 71 win_grp < ptr_aac_dec_channel_info[LEFT]->str_ics_info.num_window_groups; 72 win_grp++) { 73 for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) { 74 WORD32 sfb; 75 WORD32 ixheaacd_drc_offset = 0; 76 77 for (sfb = 0; sfb < ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb; 78 sfb++) { 79 ixheaacd_drc_offset += ptr_sfb_width[sfb]; 80 81 if (*ptr_ms_used++) { 82 for (k = 0; k < ptr_sfb_width[sfb]; k = k + 2) { 83 WORD32 left_coef = *l_spec; 84 WORD32 right_coef = *r_spec; 85 WORD32 left_coef2 = *(l_spec + 1); 86 WORD32 right_coef2 = *(r_spec + 1); 87 88 *l_spec++ = ixheaacd_add32_sat(left_coef, right_coef); 89 *r_spec++ = ixheaacd_sub32_sat(left_coef, right_coef); 90 *l_spec++ = ixheaacd_add32_sat(left_coef2, right_coef2); 91 *r_spec++ = ixheaacd_sub32_sat(left_coef2, right_coef2); 92 } 93 } else { 94 l_spec += ptr_sfb_width[sfb]; 95 r_spec += ptr_sfb_width[sfb]; 96 } 97 } 98 ptr_ms_used -= ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb; 99 l_spec = l_spec + 128 - ixheaacd_drc_offset; 100 r_spec = r_spec + 128 - ixheaacd_drc_offset; 101 } 102 103 ptr_ms_used += JOINT_STEREO_MAX_BANDS; 104 } 105 } 106 107 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32l(WORD32 a, WORD32 b) { 108 WORD32 result; 109 WORD64 temp_result; 110 111 temp_result = (WORD64)a * (WORD64)b; 112 113 result = (WORD32)(temp_result >> 16); 114 115 return (result); 116 } 117 118 VOID ixheaacd_intensity_stereo_process( 119 ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2], 120 ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type, 121 WORD32 aac_sf_data_resil_flag) { 122 UWORD8 *ptr_ms_used = 123 &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0]; 124 WORD8 *ptr_code_book = &ptr_aac_dec_channel_info[RIGHT]->ptr_code_book[0]; 125 WORD16 *ptr_scale_factor = 126 &ptr_aac_dec_channel_info[RIGHT]->ptr_scale_factor[0]; 127 WORD32 *r_spec = &ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff[0]; 128 WORD32 *l_spec = &ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff[0]; 129 WORD8 *ptr_group_len = 130 ptr_aac_dec_channel_info[RIGHT]->str_ics_info.window_group_length; 131 const WORD8 *ptr_sfb_width = 132 ptr_aac_tables 133 ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT] 134 ->str_ics_info.window_sequence] 135 .sfb_width; 136 WORD32 *ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table; 137 WORD32 win_grp, grp_len, k; 138 139 for (win_grp = 0; 140 win_grp < 141 ptr_aac_dec_channel_info[RIGHT]->str_ics_info.num_window_groups; 142 win_grp++) { 143 for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) { 144 WORD32 sfb; 145 WORD32 ixheaacd_drc_offset = 0; 146 147 for (sfb = 0; sfb < ptr_aac_dec_channel_info[RIGHT]->str_ics_info.max_sfb; 148 sfb++) { 149 WORD8 code_book = ptr_code_book[sfb]; 150 ixheaacd_drc_offset += ptr_sfb_width[sfb]; 151 152 if (((code_book >= INTENSITY_HCB2) && 153 ((object_type != AOT_ER_AAC_ELD) && 154 (object_type != AOT_ER_AAC_LD))) || 155 (((code_book == INTENSITY_HCB2) || (code_book == INTENSITY_HCB)) && 156 ((object_type == AOT_ER_AAC_ELD) || 157 (object_type == AOT_ER_AAC_LD)))) 158 159 { 160 WORD32 sfb_factor, scale; 161 WORD32 scf_exp; 162 163 sfb_factor = (ptr_scale_factor[sfb]); 164 if (aac_sf_data_resil_flag) sfb_factor = -sfb_factor; 165 166 scf_exp = (sfb_factor >> 2); 167 scale = *(ptr_scale_table + (sfb_factor & 3)); 168 if (!((ptr_ms_used[sfb]) ^ (code_book & 0x1))) { 169 scale = ixheaacd_negate32(scale); 170 } 171 172 scf_exp = -(scf_exp + 2); 173 174 for (k = 0; k < ptr_sfb_width[sfb]; k++) { 175 WORD32 temp, shift_val; 176 temp = *l_spec++; 177 178 shift_val = ixheaacd_norm32(temp); 179 temp = ixheaacd_shl32(temp, shift_val); 180 181 temp = ixheaacd_mult32x16in32l(temp, scale); 182 shift_val = shift_val + scf_exp; 183 184 if (shift_val < 0) { 185 temp = ixheaacd_shl32_sat(temp, -shift_val); 186 } else { 187 temp = ixheaacd_shr32(temp, shift_val); 188 } 189 *r_spec++ = temp; 190 } 191 192 } else { 193 l_spec += ptr_sfb_width[sfb]; 194 r_spec += ptr_sfb_width[sfb]; 195 } 196 } 197 l_spec += 128 - ixheaacd_drc_offset; 198 r_spec += 128 - ixheaacd_drc_offset; 199 } 200 ptr_ms_used += 64; 201 ptr_code_book += 16; 202 ptr_scale_factor += 16; 203 } 204 } 205