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 <string.h> 21 22 #include <ixheaacd_type_def.h> 23 #include "ixheaacd_sbr_common.h" 24 25 #include "ixheaacd_constants.h" 26 #include "ixheaacd_basic_ops32.h" 27 #include "ixheaacd_basic_ops16.h" 28 #include "ixheaacd_basic_ops40.h" 29 #include "ixheaacd_basic_ops.h" 30 31 #include "ixheaacd_bitbuffer.h" 32 33 #include "ixheaacd_audioobjtypes.h" 34 #include "ixheaacd_sbrdecsettings.h" 35 #include "ixheaacd_memory_standards.h" 36 #include "ixheaacd_error_codes.h" 37 38 #include "ixheaacd_defines.h" 39 #include "ixheaacd_aac_rom.h" 40 #include "ixheaacd_pns.h" 41 42 #include "ixheaacd_pulsedata.h" 43 #include "ixheaacd_drc_data_struct.h" 44 45 #include "ixheaacd_lt_predict.h" 46 #include "ixheaacd_channelinfo.h" 47 #include "ixheaacd_drc_dec.h" 48 49 #include "ixheaacd_sbrdecoder.h" 50 #include "ixheaacd_sbr_scale.h" 51 #include "ixheaacd_lpp_tran.h" 52 #include "ixheaacd_env_extr_part.h" 53 #include "ixheaacd_sbr_rom.h" 54 55 #include "ixheaacd_hybrid.h" 56 #include "ixheaacd_ps_dec.h" 57 #include "ixheaacd_ps_bitdec.h" 58 59 #include "ixheaacd_pulsedata.h" 60 61 #include "ixheaacd_pns.h" 62 63 #include "ixheaacd_env_extr.h" 64 #include "ixheaacd_common_rom.h" 65 #include "ixheaacd_block.h" 66 #include "ixheaacd_channel.h" 67 #include "ixheaacd_audioobjtypes.h" 68 #include "ixheaacd_latmdemux.h" 69 #include "ixheaacd_aacdec.h" 70 #include "ixheaacd_config.h" 71 #include "ixheaacd_mps_polyphase.h" 72 #include "ixheaacd_mps_dec.h" 73 #include "ixheaacd_struct_def.h" 74 #include "ixheaacd_headerdecode.h" 75 76 #include "ixheaacd_multichannel.h" 77 #include <ixheaacd_basic_op.h> 78 79 WORD cblock_decode_huff_symbol(UWORD8 *ptr_read_next, WORD32 bit_pos, 80 const UWORD16 *huff_ori, WORD16 *input, 81 WORD32 *readword) 82 83 { 84 const UWORD16 *h; 85 WORD tot_bits; 86 { 87 UWORD16 first_offset; 88 WORD16 sign_ret_val; 89 UWORD32 read_word1; 90 91 read_word1 = *readword << bit_pos; 92 93 h = (UWORD16 *)(huff_ori); 94 first_offset = 7; 95 96 h += (read_word1) >> (32 - first_offset); 97 sign_ret_val = *h; 98 tot_bits = 0; 99 100 while (sign_ret_val > 0) { 101 tot_bits += first_offset; 102 bit_pos += first_offset; 103 104 if ((bit_pos -= 8) >= 0) { 105 *readword = (*readword << 8) | *ptr_read_next; 106 ptr_read_next++; 107 } else { 108 bit_pos += 8; 109 } 110 111 read_word1 = (read_word1) << (first_offset); 112 113 first_offset = (sign_ret_val >> 11); 114 h += sign_ret_val & (0x07FF); 115 116 h += (read_word1) >> (32 - first_offset); 117 sign_ret_val = *h; 118 } 119 120 tot_bits += ((sign_ret_val & 0x7fff) >> 11); 121 bit_pos += ((sign_ret_val & 0x7fff) >> 11); 122 if ((bit_pos - 8) >= 0) { 123 *readword = (*readword << 8) | *ptr_read_next; 124 } 125 126 *input = (sign_ret_val & (0x07FF)) - 60; 127 } 128 129 return tot_bits; 130 } 131 132 WORD16 ixheaacd_dec_coupling_channel_element( 133 ia_handle_bit_buf_struct bs, ia_aac_decoder_struct *aac_handle, 134 WORD32 samp_rate_idx, ia_aac_dec_tables_struct *ptr_aac_tables, 135 ixheaacd_misc_tables *common_tables_ptr, WORD *element_index_order, 136 ia_enhaacplus_dec_ind_cc *ind_channel_info, WORD32 total_channels, 137 WORD32 frame_size, WORD32 audio_object_type, 138 ia_eld_specific_config_struct eld_specific_config, WORD32 ele_type) { 139 WORD32 element_instance_tag; 140 LOOPIDX c; 141 142 WORD ind_sw_cce_flag, num_coupled_elements; 143 144 WORD num_gain_element_lists = 0; 145 WORD cc_domain; 146 WORD gain_element_sign; 147 WORD gain_element_scale; 148 149 const UWORD16 *hcod_sf = 150 ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl; 151 const UWORD32 *table_idx = 152 ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl_index; 153 WORD16 index, length; 154 155 WORD16 error_status = AAC_DEC_OK; 156 157 element_instance_tag = ixheaacd_read_bits_buf(bs, 4); 158 element_index_order[0] = element_instance_tag; 159 160 ind_sw_cce_flag = ixheaacd_read_bits_buf(bs, 1); 161 num_coupled_elements = ixheaacd_read_bits_buf(bs, 3); 162 163 for (c = 0; c < MAX_BS_ELEMENT; c++) 164 ind_channel_info->elements_coupled[c] = -1; 165 166 ind_channel_info->num_coupled_elements = num_coupled_elements; 167 168 for (c = 0; c < (num_coupled_elements + 1); c++) { 169 num_gain_element_lists++; 170 171 ind_channel_info->cc_target_is_cpe[c] = ixheaacd_read_bits_buf(bs, 1); 172 ind_channel_info->cc_target_tag_select[c] = ixheaacd_read_bits_buf(bs, 4); 173 if (ind_channel_info->cc_target_is_cpe[c]) { 174 ind_channel_info->cc_l[c] = ixheaacd_read_bits_buf(bs, 1); 175 ind_channel_info->cc_r[c] = ixheaacd_read_bits_buf(bs, 1); 176 if (ind_channel_info->cc_l[c] && ind_channel_info->cc_r[c]) 177 num_gain_element_lists++; 178 ind_channel_info->elements_coupled[c] = 1; 179 } else 180 ind_channel_info->elements_coupled[c] = 0; 181 } 182 183 cc_domain = ixheaacd_read_bits_buf(bs, 1); 184 gain_element_sign = ixheaacd_read_bits_buf(bs, 1); 185 gain_element_scale = ixheaacd_read_bits_buf(bs, 2); 186 187 aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.num_swb_window = 0; 188 aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.sampling_rate_index = 189 samp_rate_idx; 190 191 aac_handle->pstr_aac_dec_ch_info[0]->common_window = 0; 192 193 error_status = ixheaacd_individual_ch_stream( 194 bs, aac_handle, 1, frame_size, total_channels, audio_object_type, 195 eld_specific_config, ele_type); 196 197 if (error_status) return error_status; 198 199 ind_channel_info->cc_gain[0] = 1 << 29; 200 for (c = 1; c < num_gain_element_lists; c++) { 201 WORD cge; 202 WORD common_gain_element_present[MAX_BS_ELEMENT]; 203 WORD16 norm_value; 204 205 if (ind_sw_cce_flag) 206 cge = 1; 207 else { 208 common_gain_element_present[c] = ixheaacd_read_bits_buf(bs, 1); 209 cge = common_gain_element_present[c]; 210 error_status = 211 (WORD)((WORD32)IA_ENHAACPLUS_DEC_EXE_FATAL_UNIMPLEMENTED_CCE); 212 } 213 if (cge) { 214 UWORD8 *ptr_read_next = bs->ptr_read_next; 215 WORD32 bit_pos = 7 - bs->bit_pos; 216 WORD32 read_word = ixheaacd_aac_showbits_32(ptr_read_next); 217 UWORD32 read_word1; 218 219 read_word1 = read_word << bit_pos; 220 ixheaacd_huffman_decode(read_word1, &index, &length, hcod_sf, table_idx); 221 222 bit_pos += length; 223 224 ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word); 225 while (bit_pos > 8) 226 ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word); 227 228 bs->ptr_read_next = ptr_read_next; 229 bs->bit_pos = 7 - bit_pos; 230 bs->cnt_bits -= length; 231 232 norm_value = index - 60; 233 if (norm_value == -1) 234 ind_channel_info->cc_gain[c] = 235 common_tables_ptr->cc_gain_scale[gain_element_scale]; 236 else { 237 int i; 238 ind_channel_info->cc_gain[c] = 239 common_tables_ptr->cc_gain_scale[gain_element_scale]; 240 for (i = 0; i < (-norm_value) - 1; i++) { 241 ind_channel_info->cc_gain[c] *= 242 common_tables_ptr->cc_gain_scale[gain_element_scale]; 243 } 244 } 245 } else { 246 error_status = 247 (WORD)((WORD32)IA_ENHAACPLUS_DEC_EXE_FATAL_UNIMPLEMENTED_CCE); 248 } 249 } 250 if (bs->cnt_bits < 0) { 251 error_status = (WORD16)( 252 (WORD32)IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES); 253 } 254 return error_status; 255 } 256 257 void ixheaacd_dec_couple_channel(WORD16 *p_time_data, WORD16 *out_samp_cc, 258 WORD16 frame_size, WORD total_channels, 259 WORD32 gain_cc) 260 261 { 262 WORD i; 263 WORD16 out_cc; 264 WORD16 *ptr_out_samp = &out_samp_cc[0]; 265 for (i = frame_size - 1; i >= 0; i--) { 266 out_cc = ixheaacd_round16(ixheaacd_shl32_sat( 267 ixheaacd_mult32x16in32(gain_cc, *ptr_out_samp++), 3)); 268 *p_time_data = ixheaacd_add16_sat(out_cc, *p_time_data); 269 p_time_data += total_channels; 270 } 271 } 272 273 void ixheaacd_dec_ind_coupling( 274 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD16 *coup_ch_output, 275 WORD16 frame_size, WORD total_channels, WORD16 *ptr_time_data) 276 277 { 278 WORD c, j, k; 279 WORD l; 280 WORD coupling_channel; 281 282 WORD16 *out_samp_cc; 283 284 ia_enhaacplus_dec_ind_cc *ind_channel_info; 285 286 { 287 coupling_channel = p_obj_exhaacplus_dec->aac_config.ui_coupling_channel; 288 289 ind_channel_info = &p_obj_exhaacplus_dec->p_state_aac->ind_cc_info; 290 291 out_samp_cc = coup_ch_output; 292 293 j = 0; 294 for (c = 0; c < ind_channel_info->num_coupled_elements + 1; c++) { 295 for (l = 0; l < MAX_BS_ELEMENT; l++) { 296 if (p_obj_exhaacplus_dec->aac_config.element_type[l] == 297 ind_channel_info->elements_coupled[c] && 298 p_obj_exhaacplus_dec->aac_config.element_instance_order[l] == 299 ind_channel_info->cc_target_tag_select[c]) { 300 break; 301 } 302 } 303 if (l == MAX_BS_ELEMENT) { 304 continue; 305 } 306 307 k = p_obj_exhaacplus_dec->aac_config.slot_element[l]; 308 309 if (ind_channel_info->cc_target_is_cpe[c] == 0) { 310 WORD16 *p_time_data = &ptr_time_data[k]; 311 312 WORD32 gain_cc = ind_channel_info->cc_gain[j]; 313 314 ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size, 315 total_channels, gain_cc); 316 } 317 if (ind_channel_info->cc_target_is_cpe[c] == 1) { 318 if (ind_channel_info->cc_l[c] == 1) { 319 WORD16 *p_time_data = &ptr_time_data[k]; 320 321 WORD32 gain_cc = ind_channel_info->cc_gain[j]; 322 323 ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size, 324 total_channels, gain_cc); 325 } 326 327 k = p_obj_exhaacplus_dec->aac_config.slot_element[l]; 328 329 if (ind_channel_info->cc_r[c] == 1) { 330 WORD16 *p_time_data = &ptr_time_data[k + 1]; 331 WORD32 gain_cc = ind_channel_info->cc_gain[j + 1]; 332 333 ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size, 334 total_channels, gain_cc); 335 } 336 } 337 if (ind_channel_info->cc_target_is_cpe[c] == 1) { 338 j += 2; 339 } else { 340 j += 1; 341 } 342 } 343 } 344 } 345 346 void ixheaacd_dec_downmix_to_stereo( 347 ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD16 frame_size, 348 WORD total_elements, WORD16 *ptr_time_data, WORD total_channels) { 349 LOOPIDX i, j; 350 WORD k = 0; 351 if (5 == total_channels) k = 0; 352 if (6 == total_channels) k = 1; 353 if (7 == total_channels) k = 2; 354 if (8 == total_channels) k = 3; 355 356 for (j = 0; j < frame_size; j++) { 357 WORD16 temp_l = 0, temp_r = 0; 358 for (i = 0; i < total_elements; i++) { 359 if (0 == p_obj_exhaacplus_dec->aac_config.element_type[i] || 360 3 == p_obj_exhaacplus_dec->aac_config.element_type[i]) { 361 temp_l += (WORD16)( 362 ixheaacd_mult32x16in32( 363 p_obj_exhaacplus_dec->common_tables->down_mix_martix 364 [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]], 365 ptr_time_data[j * total_channels + 366 p_obj_exhaacplus_dec->aac_config 367 .slot_element[i]]) >> 368 14); 369 370 temp_r += (WORD16)( 371 ixheaacd_mult32x16in32( 372 p_obj_exhaacplus_dec->common_tables->down_mix_martix 373 [k][1][p_obj_exhaacplus_dec->aac_config.slot_element[i]], 374 ptr_time_data[j * total_channels + 375 p_obj_exhaacplus_dec->aac_config 376 .slot_element[i]]) >> 377 14); 378 } 379 if (1 == p_obj_exhaacplus_dec->aac_config.element_type[i]) { 380 temp_l += (WORD16)( 381 ixheaacd_mult32x16in32( 382 p_obj_exhaacplus_dec->common_tables->down_mix_martix 383 [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]], 384 ptr_time_data[j * total_channels + 385 p_obj_exhaacplus_dec->aac_config 386 .slot_element[i]]) >> 387 14); 388 389 temp_r += (WORD16)( 390 ixheaacd_mult32x16in32( 391 p_obj_exhaacplus_dec->common_tables->down_mix_martix 392 [k][1] 393 [p_obj_exhaacplus_dec->aac_config.slot_element[i] + 1], 394 ptr_time_data[j * total_channels + 395 p_obj_exhaacplus_dec->aac_config.slot_element[i] + 396 1]) >> 397 14); 398 } 399 } 400 401 ptr_time_data[2 * j] = temp_l; 402 ptr_time_data[2 * j + 1] = temp_r; 403 } 404 } 405