| /****************************************************************************** |
| * |
| * 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 <stdio.h> |
| #include <string.h> |
| #include <math.h> |
| #include "impd_type_def.h" |
| #include "impd_drc_bitbuffer.h" |
| #include "impd_drc_extr_delta_coded_info.h" |
| #include "impd_drc_common.h" |
| #include "impd_drc_struct.h" |
| #include "impd_drc_parser.h" |
| #include "impd_drc_filter_bank.h" |
| #include "impd_drc_rom.h" |
| WORD32 impd_parse_loud_eq_instructions( |
| ia_bit_buf_struct* it_bit_buff, |
| ia_loud_eq_instructions_struct* loud_eq_instructions); |
| |
| WORD32 impd_parse_eq_coefficients(ia_bit_buf_struct* it_bit_buff, |
| ia_eq_coeff_struct* str_eq_coeff); |
| |
| WORD32 impd_parse_eq_instructions( |
| ia_bit_buf_struct* it_bit_buff, ia_drc_config* drc_config, |
| ia_eq_instructions_struct* str_eq_instructions); |
| WORD32 impd_dec_initial_gain(ia_bit_buf_struct* it_bit_buff, |
| const WORD32 gain_coding_profile, |
| FLOAT32* initial_gain) { |
| WORD32 sign, magn, bit_2_extract; |
| switch (gain_coding_profile) { |
| case GAIN_CODING_PROFILE_REGULAR: |
| sign = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| magn = impd_read_bits_buf(it_bit_buff, 8); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| *initial_gain = magn * 0.125f; |
| if (sign) *initial_gain = -*initial_gain; |
| break; |
| case GAIN_CODING_PROFILE_FADING: |
| case GAIN_CODING_PROFILE_CLIPPING: |
| bit_2_extract = |
| (gain_coding_profile == GAIN_CODING_PROFILE_FADING) ? 10 : 8; |
| sign = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (sign == 0) |
| *initial_gain = 0.0f; |
| else { |
| magn = impd_read_bits_buf(it_bit_buff, bit_2_extract); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| *initial_gain = -(magn + 1) * 0.125f; |
| } |
| break; |
| |
| case GAIN_CODING_PROFILE_CONSTANT: |
| break; |
| default: |
| return (UNEXPECTED_ERROR); |
| } |
| return (0); |
| } |
| |
| WORD32 impd_dec_gains(ia_bit_buf_struct* it_bit_buff, WORD32 no_nodes, |
| WORD32 gain_coding_profile, ia_node_struct* str_node) { |
| WORD32 err = 0, k, e, m; |
| WORD32 bit; |
| WORD32 num_bits_read; |
| WORD32 code; |
| WORD32 code_found; |
| FLOAT32 drc_gain_delta = 0; |
| const ia_delta_gain_code_table_struct* ptr_delta_gain_code_table; |
| WORD32 no_delta_gain_entries; |
| |
| err = impd_dec_initial_gain(it_bit_buff, gain_coding_profile, |
| &(str_node[0].loc_db_gain)); |
| if (err) return (err); |
| |
| impd_get_delta_gain_code_tbl(gain_coding_profile, &ptr_delta_gain_code_table, |
| &no_delta_gain_entries); |
| for (k = 1; k < no_nodes; k++) { |
| num_bits_read = 0; |
| code = 0; |
| code_found = 0; |
| e = 0; |
| while ((e < no_delta_gain_entries) && (!code_found)) { |
| for (m = 0; m < ptr_delta_gain_code_table[e].size - num_bits_read; m++) { |
| bit = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| code = (code << 1) + bit; |
| num_bits_read++; |
| } |
| while (num_bits_read == ptr_delta_gain_code_table[e].size) { |
| if (code == ptr_delta_gain_code_table[e].code) { |
| drc_gain_delta = ptr_delta_gain_code_table[e].value; |
| code_found = 1; |
| break; |
| } |
| e++; |
| } |
| } |
| if (code_found == 0) { |
| return (UNEXPECTED_ERROR); |
| } |
| str_node[k].loc_db_gain = str_node[k - 1].loc_db_gain + drc_gain_delta; |
| } |
| return (0); |
| } |
| |
| WORD32 impd_dec_slopes(ia_bit_buf_struct* it_bit_buff, WORD32* no_nodes, |
| WORD32 gain_interpolation_type, |
| ia_node_struct* str_node) { |
| WORD32 k, e, bit; |
| WORD32 code; |
| WORD32 code_found; |
| FLOAT32 slope_value = 0; |
| bool end_marker = 0; |
| WORD32 num_bits_read; |
| const ia_slope_code_table_struct* ptr_slope_code_table; |
| WORD32 no_slope_code_entries; |
| |
| ptr_slope_code_table = &(slope_code_tbl_entries_by_size[0]); |
| no_slope_code_entries = NUM_SLOPE_TBL_ENTRIES; |
| |
| k = 0; |
| while (end_marker != 1) { |
| k++; |
| end_marker = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| if (k > NODE_COUNT_MAX) return UNEXPECTED_ERROR; |
| *no_nodes = k; |
| |
| if (gain_interpolation_type == GAIN_INTERPOLATION_TYPE_SPLINE) { |
| for (k = 0; k < *no_nodes; k++) { |
| num_bits_read = 0; |
| code = 0; |
| code_found = 0; |
| e = 0; |
| while ((e < no_slope_code_entries) && (!code_found)) { |
| while (num_bits_read < ptr_slope_code_table[e].size) { |
| bit = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| code = (code << 1) + bit; |
| num_bits_read++; |
| } |
| while (num_bits_read == ptr_slope_code_table[e].size) { |
| if (code == ptr_slope_code_table[e].code) { |
| slope_value = ptr_slope_code_table[e].value; |
| code_found = 1; |
| break; |
| } |
| e++; |
| if (e >= no_slope_code_entries) return UNEXPECTED_ERROR; |
| } |
| } |
| str_node[k].slope = slope_value; |
| } |
| } else { |
| for (k = 0; k < *no_nodes; k++) { |
| str_node[k].slope = 0.0f; |
| } |
| } |
| return (0); |
| } |
| |
| WORD32 impd_dec_times(ia_bit_buf_struct* it_bit_buff, |
| ia_tables_struct* str_tables, WORD32 num_nodes, |
| WORD32 delta_tmin, WORD32 drc_frame_size, |
| WORD32 full_frame, WORD32 time_offset, |
| ia_node_struct* str_node) { |
| WORD32 k, e, m; |
| WORD32 bit; |
| WORD32 num_bits_read; |
| WORD32 code; |
| WORD32 code_found = 0; |
| WORD32 time_delta = 0; |
| WORD32 time_offs = time_offset; |
| ia_delta_time_code_table_entry_struct* delta_time_code_table = |
| str_tables->delta_time_code_table; |
| bool frame_end_flag; |
| WORD32 node_time_tmp; |
| bool node_res_flag; |
| WORD32 exit_cnt; |
| if (full_frame == 0) { |
| frame_end_flag = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } else { |
| frame_end_flag = 1; |
| } |
| |
| if (frame_end_flag == 1) { |
| node_res_flag = 0; |
| for (k = 0; k < num_nodes - 1; k++) { |
| num_bits_read = 0; |
| code = 0; |
| code_found = 0; |
| exit_cnt = 0; |
| e = 1; |
| while ((e < N_DELTA_TIME_CODE_TABLE_ENTRIES_MAX) && (!code_found)) { |
| exit_cnt++; |
| if (exit_cnt > 100000) { |
| return -1; |
| } |
| for (m = 0; m < delta_time_code_table[e].size - num_bits_read; m++) { |
| bit = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| code = (code << 1) + bit; |
| num_bits_read++; |
| } |
| while (num_bits_read == delta_time_code_table[e].size) { |
| if (code == delta_time_code_table[e].code) { |
| time_delta = delta_time_code_table[e].value; |
| code_found = 1; |
| break; |
| } |
| e++; |
| } |
| } |
| node_time_tmp = time_offs + time_delta * delta_tmin; |
| if (node_time_tmp > drc_frame_size + time_offset) { |
| if (node_res_flag == 0) { |
| str_node[k].time = drc_frame_size + time_offset; |
| node_res_flag = 1; |
| } |
| str_node[k + 1].time = node_time_tmp; |
| } else { |
| str_node[k].time = node_time_tmp; |
| } |
| time_offs = node_time_tmp; |
| } |
| if (node_res_flag == 0) { |
| str_node[k].time = drc_frame_size + time_offset; |
| } |
| } else { |
| for (k = 0; k < num_nodes; k++) { |
| num_bits_read = 0; |
| code = 0; |
| code_found = 0; |
| e = 1; |
| exit_cnt = 0; |
| while ((e < N_DELTA_TIME_CODE_TABLE_ENTRIES_MAX) && (!code_found)) { |
| exit_cnt++; |
| if (exit_cnt > 100000) { |
| return (BITSTREAM_ERROR); |
| } |
| for (m = 0; m < delta_time_code_table[e].size - num_bits_read; m++) { |
| bit = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| code = (code << 1) + bit; |
| num_bits_read++; |
| } |
| while (num_bits_read == delta_time_code_table[e].size) { |
| if (code == delta_time_code_table[e].code) { |
| time_delta = delta_time_code_table[e].value; |
| code_found = 1; |
| break; |
| } |
| e++; |
| } |
| } |
| time_offs += time_delta * delta_tmin; |
| if (time_offs >= (2 * AUDIO_CODEC_FRAME_SIZE_MAX - drc_frame_size)) |
| return UNEXPECTED_ERROR; |
| str_node[k].time = time_offs; |
| } |
| } |
| return (0); |
| } |
| |
| WORD32 impd_drc_uni_gain_read(ia_bit_buf_struct* it_bit_buff, |
| ia_drc_bits_dec_struct* pstr_drc_uni_bs_dec, |
| ia_drc_config* drc_config, |
| ia_drc_gain_struct* pstr_uni_drc_gain) { |
| WORD32 err = 0; |
| WORD32 seq; |
| static WORD32 pkt_loss_frame_cnt = 0; |
| ia_spline_nodes_struct* str_spline_nodes = {0}; |
| |
| { |
| WORD32 gain_sequence_count = |
| drc_config->str_p_loc_drc_coefficients_uni_drc[0].gain_sequence_count; |
| |
| for (seq = 0; seq < gain_sequence_count; seq++) { |
| WORD32 index = drc_config->str_p_loc_drc_coefficients_uni_drc[0] |
| .gain_set_params_index_for_gain_sequence[seq]; |
| ia_gain_set_params_struct str_gain_set_params = {0}; |
| ia_gain_set_params_struct* gain_set_params = &str_gain_set_params; |
| |
| if (index != -1) { |
| gain_set_params = &(drc_config->str_p_loc_drc_coefficients_uni_drc |
| ->gain_set_params[index]); |
| } |
| if (gain_set_params->gain_coding_profile == |
| GAIN_CODING_PROFILE_CONSTANT) { |
| str_spline_nodes = |
| &(pstr_uni_drc_gain->drc_gain_sequence[seq].str_spline_nodes[0]); |
| str_spline_nodes->num_nodes = 1; |
| str_spline_nodes->str_node[0].slope = 0.0; |
| str_spline_nodes->str_node[0].time = |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct).drc_frame_size - 1; |
| str_spline_nodes->str_node[0].loc_db_gain = 0.0f; |
| } else { |
| err = impd_parse_drc_gain_sequence( |
| it_bit_buff, pstr_drc_uni_bs_dec, gain_set_params, |
| &(pstr_uni_drc_gain->drc_gain_sequence[seq])); |
| if (err) return (err); |
| } |
| } |
| } |
| |
| if (it_bit_buff->ptr_bit_buf_base == NULL) { |
| pkt_loss_frame_cnt++; |
| |
| if (pkt_loss_frame_cnt * |
| (FLOAT32)pstr_drc_uni_bs_dec->ia_drc_params_struct.drc_frame_size / |
| drc_config->sampling_rate > |
| MAXPACKETLOSSTIME) { |
| drc_config->apply_drc = 0; |
| } |
| } else { |
| pstr_uni_drc_gain->uni_drc_gain_ext_flag = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (pstr_uni_drc_gain->uni_drc_gain_ext_flag == 1) { |
| err = impd_parse_uni_drc_gain_ext(it_bit_buff, |
| &(pstr_uni_drc_gain->uni_drc_gain_ext)); |
| if (err) return (err); |
| } |
| pkt_loss_frame_cnt = 0; |
| drc_config->apply_drc = 1; |
| } |
| |
| return (0); |
| } |
| |
| WORD32 impd_parse_uni_drc_gain_ext( |
| ia_bit_buf_struct* it_bit_buff, |
| ia_uni_drc_gain_ext_struct* uni_drc_gain_ext) { |
| WORD32 k; |
| WORD32 bit_size_len, ext_size_bits, bit_size, other_bit; |
| |
| k = 0; |
| uni_drc_gain_ext->uni_drc_gain_ext_type[k] = |
| impd_read_bits_buf(it_bit_buff, 4); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| while (uni_drc_gain_ext->uni_drc_gain_ext_type[k] != UNIDRCGAINEXT_TERM) { |
| if (k >= (EXT_COUNT_MAX - 1)) return UNEXPECTED_ERROR; |
| bit_size_len = impd_read_bits_buf(it_bit_buff, 3); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| ext_size_bits = bit_size_len + 4; |
| |
| bit_size = impd_read_bits_buf(it_bit_buff, ext_size_bits); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| uni_drc_gain_ext->ext_bit_size[k] = bit_size + 1; |
| |
| other_bit = |
| impd_skip_bits_buf(it_bit_buff, uni_drc_gain_ext->ext_bit_size[k]); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| k++; |
| uni_drc_gain_ext->uni_drc_gain_ext_type[k] = |
| impd_read_bits_buf(it_bit_buff, 4); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| |
| return (0); |
| } |
| |
| WORD32 impd_parse_spline_nodes(ia_bit_buf_struct* it_bit_buff, |
| ia_drc_bits_dec_struct* pstr_drc_uni_bs_dec, |
| ia_gain_set_params_struct* gain_set_params, |
| ia_spline_nodes_struct* str_spline_nodes) { |
| WORD32 err = 0; |
| WORD32 time_offset; |
| if (gain_set_params->time_alignment == 0) { |
| time_offset = -1; |
| } else { |
| if (gain_set_params->time_delt_min_flag) { |
| time_offset = -gain_set_params->time_delt_min_val + |
| (gain_set_params->time_delt_min_val - 1) / 2; |
| } else { |
| time_offset = |
| -pstr_drc_uni_bs_dec->ia_drc_params_struct.delta_tmin_default + |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct.delta_tmin_default - 1) / |
| 2; |
| } |
| } |
| |
| if (it_bit_buff->ptr_bit_buf_base == NULL) { |
| if ((str_spline_nodes->num_nodes < 1) || |
| (str_spline_nodes->num_nodes > NODE_COUNT_MAX)) |
| return UNEXPECTED_ERROR; |
| FLOAT32 prev_db_gain = |
| str_spline_nodes->str_node[str_spline_nodes->num_nodes - 1].loc_db_gain; |
| str_spline_nodes->drc_gain_coding_mode = 0; |
| |
| str_spline_nodes->num_nodes = 1; |
| |
| if (prev_db_gain < 0) { |
| str_spline_nodes->str_node[0].loc_db_gain = prev_db_gain; |
| } else { |
| str_spline_nodes->str_node[0].loc_db_gain = 0.f; |
| } |
| |
| str_spline_nodes->str_node[0].slope = 0.0; |
| str_spline_nodes->str_node[0].time = |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct).drc_frame_size + |
| time_offset; |
| } else { |
| str_spline_nodes->drc_gain_coding_mode = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error == PROC_COMPLETE) { |
| if ((str_spline_nodes->num_nodes < 1) || |
| (str_spline_nodes->num_nodes > NODE_COUNT_MAX)) |
| return UNEXPECTED_ERROR; |
| str_spline_nodes->drc_gain_coding_mode = 0; |
| str_spline_nodes->str_node[0].slope = 0.0; |
| str_spline_nodes->str_node[0].time = |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct).drc_frame_size + |
| time_offset; |
| str_spline_nodes->str_node[0].loc_db_gain = |
| str_spline_nodes->str_node[str_spline_nodes->num_nodes - 1] |
| .loc_db_gain; |
| str_spline_nodes->num_nodes = 1; |
| } else { |
| if (it_bit_buff->error) return (it_bit_buff->error); |
| } |
| if (str_spline_nodes->drc_gain_coding_mode == 0) { |
| str_spline_nodes->num_nodes = 1; |
| |
| err = impd_dec_initial_gain(it_bit_buff, |
| gain_set_params->gain_coding_profile, |
| &(str_spline_nodes->str_node[0].loc_db_gain)); |
| if (err) return (err); |
| |
| str_spline_nodes->str_node[0].slope = 0.0; |
| str_spline_nodes->str_node[0].time = |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct).drc_frame_size + |
| time_offset; |
| } else { |
| err = impd_dec_slopes(it_bit_buff, &str_spline_nodes->num_nodes, |
| gain_set_params->gain_interpolation_type, |
| str_spline_nodes->str_node); |
| if (err) return (err); |
| if (gain_set_params->time_delt_min_flag) { |
| err = impd_dec_times( |
| it_bit_buff, &gain_set_params->str_tables, |
| str_spline_nodes->num_nodes, gain_set_params->time_delt_min_val, |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct).drc_frame_size, |
| gain_set_params->full_frame, time_offset, |
| str_spline_nodes->str_node); |
| if (err) return (err); |
| err = impd_dec_gains(it_bit_buff, str_spline_nodes->num_nodes, |
| gain_set_params->gain_coding_profile, |
| str_spline_nodes->str_node); |
| if (err) return (err); |
| } else { |
| err = impd_dec_times( |
| it_bit_buff, &pstr_drc_uni_bs_dec->tables_default, |
| str_spline_nodes->num_nodes, |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct).delta_tmin_default, |
| (pstr_drc_uni_bs_dec->ia_drc_params_struct).drc_frame_size, |
| gain_set_params->full_frame, time_offset, |
| str_spline_nodes->str_node); |
| if (err) return (err); |
| err = impd_dec_gains(it_bit_buff, str_spline_nodes->num_nodes, |
| gain_set_params->gain_coding_profile, |
| str_spline_nodes->str_node); |
| if (err) return (err); |
| } |
| } |
| } |
| return (0); |
| } |
| |
| WORD32 impd_parse_drc_gain_sequence( |
| ia_bit_buf_struct* it_bit_buff, ia_drc_bits_dec_struct* pstr_drc_uni_bs_dec, |
| ia_gain_set_params_struct* gain_set_params, |
| ia_drc_gain_sequence_struct* drc_gain_sequence) { |
| WORD32 err = 0, i; |
| WORD32 prev_frame_time_buf[NODE_COUNT_MAX], |
| cur_frame_time_buf[NODE_COUNT_MAX]; |
| WORD32 num_nodes_node_reservoir, num_nodes_cur, k, m; |
| |
| if (((pstr_drc_uni_bs_dec->ia_drc_params_struct).delay_mode == |
| DELAY_MODE_LOW_DELAY) && |
| (gain_set_params->full_frame == 0)) { |
| return (PARAM_ERROR); |
| } |
| i = 0; |
| { |
| err = impd_parse_spline_nodes(it_bit_buff, pstr_drc_uni_bs_dec, |
| gain_set_params, |
| &(drc_gain_sequence->str_spline_nodes[i])); |
| if (err) return (err); |
| |
| num_nodes_node_reservoir = 0; |
| num_nodes_cur = 0; |
| for (k = 0; k < drc_gain_sequence->str_spline_nodes[i].num_nodes; k++) { |
| if (drc_gain_sequence->str_spline_nodes[i].str_node[k].time >= |
| pstr_drc_uni_bs_dec->ia_drc_params_struct.drc_frame_size) { |
| prev_frame_time_buf[num_nodes_node_reservoir] = |
| drc_gain_sequence->str_spline_nodes[i].str_node[k].time; |
| num_nodes_node_reservoir++; |
| } else { |
| cur_frame_time_buf[num_nodes_cur] = |
| drc_gain_sequence->str_spline_nodes[i].str_node[k].time; |
| num_nodes_cur++; |
| } |
| } |
| for (k = 0; k < num_nodes_node_reservoir; k++) { |
| WORD32 tmp = prev_frame_time_buf[k] - |
| 2 * pstr_drc_uni_bs_dec->ia_drc_params_struct.drc_frame_size; |
| if (tmp >= (2 * AUDIO_CODEC_FRAME_SIZE_MAX - |
| pstr_drc_uni_bs_dec->ia_drc_params_struct.drc_frame_size)) |
| return UNEXPECTED_ERROR; |
| drc_gain_sequence->str_spline_nodes[i].str_node[k].time = tmp; |
| } |
| for (m = 0; m < num_nodes_cur; m++, k++) { |
| drc_gain_sequence->str_spline_nodes[i].str_node[k].time = |
| cur_frame_time_buf[m]; |
| } |
| } |
| return (0); |
| } |
| WORD32 impd_parse_drc_ext_v1(ia_bit_buf_struct* it_bit_buff, |
| ia_drc_params_bs_dec_struct* ia_drc_params_struct, |
| ia_drc_config* drc_config, |
| ia_drc_config_ext* str_drc_config_ext) { |
| WORD32 dwnmix_instructions_v1_flag; |
| WORD32 dwnmix_instructions_v1_count; |
| WORD32 drc_coeffs_and_instructions_uni_drc_v1_flag; |
| WORD32 drc_coefficients_uni_drc_v1_count; |
| WORD32 drc_instructions_uni_drc_v1_count; |
| |
| WORD32 i = 0, err = 0; |
| const WORD32 version = 1; |
| |
| dwnmix_instructions_v1_flag = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (dwnmix_instructions_v1_flag == 1) { |
| dwnmix_instructions_v1_count = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if ((dwnmix_instructions_v1_count + drc_config->dwnmix_instructions_count) > |
| DOWNMIX_INSTRUCTION_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| for (i = 0; i < dwnmix_instructions_v1_count; i++) { |
| err = impd_parse_dwnmix_instructions( |
| it_bit_buff, version, ia_drc_params_struct, |
| &drc_config->channel_layout, |
| &drc_config |
| ->dwnmix_instructions[i + |
| drc_config->dwnmix_instructions_count]); |
| if (err) return (err); |
| } |
| drc_config->dwnmix_instructions_count += dwnmix_instructions_v1_count; |
| } |
| |
| drc_coeffs_and_instructions_uni_drc_v1_flag = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (drc_coeffs_and_instructions_uni_drc_v1_flag == 1) { |
| drc_coefficients_uni_drc_v1_count = impd_read_bits_buf(it_bit_buff, 3); |
| if ((drc_coefficients_uni_drc_v1_count + |
| drc_config->drc_coefficients_drc_count) > DRC_COEFF_COUNT_MAX) { |
| return (UNEXPECTED_ERROR); |
| } |
| if (it_bit_buff->error) return it_bit_buff->error; |
| for (i = 0; i < drc_coefficients_uni_drc_v1_count; i++) { |
| err = impd_drc_parse_coeff( |
| it_bit_buff, version, ia_drc_params_struct, |
| &drc_config->str_p_loc_drc_coefficients_uni_drc |
| [i + drc_config->drc_coefficients_drc_count]); |
| if (err) return (err); |
| } |
| drc_config->drc_coefficients_drc_count += drc_coefficients_uni_drc_v1_count; |
| |
| drc_instructions_uni_drc_v1_count = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (drc_config->drc_instructions_uni_drc_count + |
| drc_instructions_uni_drc_v1_count > |
| DRC_INSTRUCTIONS_COUNT_MAX) |
| return (UNEXPECTED_ERROR); |
| |
| for (i = 0; i < drc_instructions_uni_drc_v1_count; i++) { |
| err = impd_parse_drc_instructions_uni_drc( |
| it_bit_buff, version, drc_config, |
| &drc_config->str_drc_instruction_str |
| [i + drc_config->drc_instructions_uni_drc_count]); |
| if (err) return (err); |
| } |
| drc_config->drc_instructions_uni_drc_count += |
| drc_instructions_uni_drc_v1_count; |
| } |
| |
| str_drc_config_ext->loud_eq_instructions_flag = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (str_drc_config_ext->loud_eq_instructions_flag == 1) { |
| str_drc_config_ext->loud_eq_instructions_count = |
| impd_read_bits_buf(it_bit_buff, 4); |
| |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (str_drc_config_ext->loud_eq_instructions_count > |
| LOUD_EQ_INSTRUCTIONS_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| for (i = 0; i < str_drc_config_ext->loud_eq_instructions_count; i++) { |
| err = impd_parse_loud_eq_instructions( |
| it_bit_buff, &str_drc_config_ext->loud_eq_instructions[i]); |
| if (err) return (err); |
| } |
| } else { |
| str_drc_config_ext->loud_eq_instructions_count = 0; |
| } |
| |
| str_drc_config_ext->eq_flag = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (str_drc_config_ext->eq_flag == 1) { |
| err = impd_parse_eq_coefficients(it_bit_buff, |
| &str_drc_config_ext->str_eq_coeff); |
| if (err) return (err); |
| str_drc_config_ext->eq_instructions_count = |
| impd_read_bits_buf(it_bit_buff, 4); |
| if (str_drc_config_ext->eq_instructions_count > EQ_INSTRUCTIONS_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| if (it_bit_buff->error) return it_bit_buff->error; |
| for (i = 0; i < str_drc_config_ext->eq_instructions_count; i++) { |
| err = impd_parse_eq_instructions( |
| it_bit_buff, drc_config, &str_drc_config_ext->str_eq_instructions[i]); |
| if (err) return (err); |
| } |
| } |
| return 0; |
| } |
| |
| WORD32 impd_parse_filt_block(ia_bit_buf_struct* it_bit_buff, |
| ia_filt_block_struct* str_filter_block, |
| WORD32 block_count) { |
| // WORD32 err = 0; |
| WORD32 k, j, temp; |
| ia_filt_ele_struct* str_filter_element; |
| |
| for (j = 0; j < block_count; j++) { |
| str_filter_block->filter_element_count = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (str_filter_block->filter_element_count > FILTER_ELEMENT_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| str_filter_element = &str_filter_block->str_filter_element[0]; |
| for (k = 0; k < str_filter_block->filter_element_count; k++) { |
| temp = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| str_filter_element->filt_ele_idx = (temp & 0x7E) >> 1; |
| if (str_filter_element->filt_ele_idx >= FILTER_ELEMENT_COUNT_MAX) |
| return (UNEXPECTED_ERROR); |
| str_filter_element->filt_ele_gain_flag = temp & 1; |
| ; |
| |
| if (str_filter_element->filt_ele_gain_flag) { |
| WORD32 bs_filter_element_gain; |
| bs_filter_element_gain = impd_read_bits_buf(it_bit_buff, 10); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| str_filter_element->filt_ele_gain = |
| bs_filter_element_gain * 0.125f - 96.0f; |
| } |
| |
| str_filter_element++; |
| } |
| str_filter_block++; |
| } |
| return (0); |
| } |
| |
| WORD32 impd_parse_unique_td_filt_ele( |
| ia_bit_buf_struct* it_bit_buff, |
| ia_unique_td_filt_element* unique_td_filt_ele, |
| WORD32 td_filter_element_count) { |
| WORD32 m, sign, j, temp; |
| FLOAT32 tmp; |
| |
| for (j = 0; j < td_filter_element_count; j++) { |
| unique_td_filt_ele->eq_filter_format = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (unique_td_filt_ele->eq_filter_format == 0) { |
| WORD32 bs_real_zero_radius, bs_generic_zero_radius, bs_generic_zero_angle; |
| WORD32 bs_real_pole_radius, bs_cmplx_pole_radius, bs_cmplx_pole_angle; |
| WORD32 bs_real_zero_radius_one_count; |
| |
| temp = impd_read_bits_buf(it_bit_buff, 23); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| bs_real_zero_radius_one_count = (temp >> 20) & 7; |
| |
| unique_td_filt_ele->bs_real_zero_radius_one_count = |
| 2 * bs_real_zero_radius_one_count; |
| unique_td_filt_ele->real_zero_count = (temp & 0xFC000) >> 14; |
| |
| unique_td_filt_ele->generic_zero_count = (temp & 0x3F00) >> 8; |
| |
| unique_td_filt_ele->real_pole_count = (temp & 0xF0) >> 4; |
| |
| unique_td_filt_ele->cmplx_pole_count = temp & 0xF; |
| |
| temp = impd_read_bits_buf( |
| it_bit_buff, unique_td_filt_ele->bs_real_zero_radius_one_count); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| for (m = unique_td_filt_ele->bs_real_zero_radius_one_count - 1; m >= 0; |
| m--) { |
| unique_td_filt_ele->zero_sign[m] = (temp & 1); |
| temp = temp >> 1; |
| } |
| |
| for (m = 0; m < unique_td_filt_ele->real_zero_count; m++) { |
| temp = impd_read_bits_buf(it_bit_buff, 8); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| bs_real_zero_radius = (temp & 0xFE) >> 1; |
| |
| sign = temp & 0x01; |
| |
| tmp = 1.0f - zero_pole_radius_tbl[bs_real_zero_radius]; |
| |
| sign = sign << 1; |
| |
| unique_td_filt_ele->real_zero_radius[m] = (1 - sign) * tmp; |
| } |
| for (m = 0; m < unique_td_filt_ele->generic_zero_count; m++) { |
| temp = impd_read_bits_buf(it_bit_buff, 14); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| bs_generic_zero_radius = (temp & 0x3F80) >> 7; |
| |
| unique_td_filt_ele->generic_zero_radius[m] = |
| 1.0f - zero_pole_radius_tbl[bs_generic_zero_radius]; |
| |
| bs_generic_zero_angle = (temp & 0x7F); |
| |
| unique_td_filt_ele->generic_zero_angle[m] = |
| zero_pole_angle_tbl[bs_generic_zero_angle]; |
| } |
| for (m = 0; m < unique_td_filt_ele->real_pole_count; m++) { |
| temp = impd_read_bits_buf(it_bit_buff, 8); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| bs_real_pole_radius = (temp & 0xFE) >> 1; |
| |
| sign = temp & 0x01; |
| |
| tmp = 1.0f - zero_pole_radius_tbl[bs_real_pole_radius]; |
| |
| sign = sign << 1; |
| |
| unique_td_filt_ele->real_pole_radius[m] = (1 - sign) * tmp; |
| } |
| for (m = 0; m < unique_td_filt_ele->cmplx_pole_count; m++) { |
| temp = impd_read_bits_buf(it_bit_buff, 14); |
| |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| bs_cmplx_pole_radius = (temp & 0x3F80) >> 7; |
| |
| unique_td_filt_ele->complex_pole_radius[m] = |
| 1.0f - zero_pole_radius_tbl[bs_cmplx_pole_radius]; |
| |
| bs_cmplx_pole_angle = (temp & 0x7F); |
| |
| unique_td_filt_ele->complex_pole_angle[m] = |
| zero_pole_angle_tbl[bs_cmplx_pole_angle]; |
| } |
| } else { |
| temp = impd_read_bits_buf(it_bit_buff, 8); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| unique_td_filt_ele->fir_filt_order = (temp & 0xFE) >> 1; |
| |
| unique_td_filt_ele->fir_symmetry = temp & 0x01; |
| |
| for (m = 0; m < unique_td_filt_ele->fir_filt_order / 2 + 1; m++) { |
| WORD32 sign, bs_fir_coeff; |
| FLOAT32 tmp; |
| |
| temp = impd_read_bits_buf(it_bit_buff, 11); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| sign = (temp >> 10) & 0x01; |
| |
| bs_fir_coeff = temp & 0x03FF; |
| |
| tmp = (FLOAT32)pow(10.0f, -0.05f * bs_fir_coeff * 0.0625f); |
| |
| sign = sign << 1; |
| |
| unique_td_filt_ele->fir_coeff[m] = (1 - sign) * tmp; |
| } |
| } |
| unique_td_filt_ele++; |
| } |
| return (0); |
| } |
| |
| WORD32 impd_decode_eq_slope_code(ia_bit_buf_struct* it_bit_buff, |
| FLOAT32* eq_slope, WORD32 num_eq_nodes) { |
| WORD32 bits = 0; |
| WORD32 k; |
| |
| for (k = 0; k < num_eq_nodes; k++) { |
| bits = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (bits == 0x1) { |
| *eq_slope = 0.0f; |
| } else { |
| bits = impd_read_bits_buf(it_bit_buff, 4); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| *eq_slope = eq_slope_tbl[bits]; |
| } |
| eq_slope++; |
| } |
| return (0); |
| } |
| |
| WORD32 |
| impd_decode_gain_initial_code(ia_bit_buf_struct* it_bit_buff, |
| FLOAT32* eq_gain_initial) { |
| WORD32 bits, bits1; |
| |
| bits1 = impd_read_bits_buf(it_bit_buff, 2); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| switch (bits1) { |
| case 0x0: |
| bits = impd_read_bits_buf(it_bit_buff, 5); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| *eq_gain_initial = 0.5f * bits - 8.0f; |
| break; |
| case 0x1: |
| case 0x2: |
| |
| bits = impd_read_bits_buf(it_bit_buff, 4); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (bits < 8) { |
| *eq_gain_initial = bits1 * bits - bits1 * 16.0f; |
| } else { |
| *eq_gain_initial = (FLOAT32)bits1 * bits; |
| } |
| break; |
| |
| case 0x3: |
| bits = impd_read_bits_buf(it_bit_buff, 3); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| *eq_gain_initial = 4.0f * bits - 64.0f; |
| break; |
| |
| default: |
| break; |
| } |
| return (0); |
| } |
| |
| WORD32 impd_parse_eq_subband_gain_spline( |
| ia_bit_buf_struct* it_bit_buff, |
| ia_eq_subband_gain_spline_struct* str_eq_subband_gain_spline, |
| WORD32 eq_subband_gains_count) { |
| WORD32 err = 0, eq_nodes_cnt, j, k, bits, *eq_freq_delta; |
| FLOAT32* peq_gain_delta; |
| |
| for (j = 0; j < eq_subband_gains_count; j++) { |
| eq_nodes_cnt = impd_read_bits_buf(it_bit_buff, 5); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| str_eq_subband_gain_spline->num_eq_nodes = eq_nodes_cnt + 2; |
| |
| err = impd_decode_eq_slope_code(it_bit_buff, |
| &(str_eq_subband_gain_spline->eq_slope[0]), |
| str_eq_subband_gain_spline->num_eq_nodes); |
| if (err) return (err); |
| |
| eq_freq_delta = &(str_eq_subband_gain_spline->eq_freq_delta[1]); |
| for (k = 1; k < str_eq_subband_gain_spline->num_eq_nodes; k++) { |
| bits = impd_read_bits_buf(it_bit_buff, 4); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| *eq_freq_delta = bits + 1; |
| eq_freq_delta++; |
| } |
| |
| err = impd_decode_gain_initial_code( |
| it_bit_buff, &(str_eq_subband_gain_spline->eq_gain_initial)); |
| if (err) return (err); |
| |
| peq_gain_delta = &(str_eq_subband_gain_spline->eq_gain_delta[1]); |
| for (k = 1; k < str_eq_subband_gain_spline->num_eq_nodes; k++) { |
| bits = impd_read_bits_buf(it_bit_buff, 5); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| *peq_gain_delta = eq_gain_delta_tbl[bits]; |
| peq_gain_delta++; |
| } |
| str_eq_subband_gain_spline++; |
| } |
| return (0); |
| } |
| |
| WORD32 impd_parse_eq_subband_gain_vector( |
| ia_bit_buf_struct* it_bit_buff, const WORD32 eq_subband_gain_count, |
| ia_eq_subband_gain_vector* str_eq_subband_gain_vector, |
| WORD32 eq_subband_gains_count) { |
| WORD32 m, k, temp; |
| |
| for (k = 0; k < eq_subband_gains_count; k++) { |
| for (m = 0; m < eq_subband_gain_count; m++) { |
| WORD32 sign, bs_eq_subband_gain; |
| temp = impd_read_bits_buf(it_bit_buff, 9); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| sign = (temp >> 8) & 1; |
| bs_eq_subband_gain = temp & 0x7F; |
| |
| sign = sign << 1; |
| str_eq_subband_gain_vector->eq_subband_gain[m] = |
| ((1 - sign) * bs_eq_subband_gain) * 0.125f; |
| } |
| str_eq_subband_gain_vector++; |
| } |
| return (0); |
| } |
| |
| WORD32 impd_parse_eq_coefficients(ia_bit_buf_struct* it_bit_buff, |
| ia_eq_coeff_struct* str_eq_coeff) { |
| WORD32 err = 0; |
| WORD32 eq_gain_cnt, mu, nu, temp; |
| static const WORD32 subband_gain_len_tbl[7] = {0, 32, 39, 64, 71, 128, 135}; |
| |
| str_eq_coeff->eq_delay_max_present = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (str_eq_coeff->eq_delay_max_present) { |
| mu = impd_read_bits_buf(it_bit_buff, 5); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| nu = impd_read_bits_buf(it_bit_buff, 3); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| str_eq_coeff->eq_delay_max = 16 * mu * (1 << nu); |
| } |
| |
| str_eq_coeff->unique_filter_block_count = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (str_eq_coeff->unique_filter_block_count > FILTER_BLOCK_COUNT_MAX) { |
| return (UNEXPECTED_ERROR); |
| } |
| |
| err = impd_parse_filt_block(it_bit_buff, &(str_eq_coeff->str_filter_block[0]), |
| str_eq_coeff->unique_filter_block_count); |
| if (err) return (err); |
| |
| str_eq_coeff->unique_td_filter_element_count = |
| impd_read_bits_buf(it_bit_buff, 6); |
| if (str_eq_coeff->unique_td_filter_element_count > FILTER_ELEMENT_COUNT_MAX) |
| return (UNEXPECTED_ERROR); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| err = impd_parse_unique_td_filt_ele( |
| it_bit_buff, &(str_eq_coeff->unique_td_filt_ele[0]), |
| str_eq_coeff->unique_td_filter_element_count); |
| if (err) return (err); |
| |
| str_eq_coeff->unique_eq_subband_gains_count = |
| impd_read_bits_buf(it_bit_buff, 6); |
| if (str_eq_coeff->unique_eq_subband_gains_count > |
| UNIQUE_SUBBAND_GAIN_COUNT_MAX) |
| return (UNEXPECTED_ERROR); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (str_eq_coeff->unique_eq_subband_gains_count > 0) { |
| temp = impd_read_bits_buf(it_bit_buff, 5); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| str_eq_coeff->eq_subband_gain_representation = (temp >> 4) & 0x01; |
| |
| str_eq_coeff->eq_subband_gain_format = temp & 0x0F; |
| if ((str_eq_coeff->eq_subband_gain_format > 0) && |
| (str_eq_coeff->eq_subband_gain_format < GAINFORMAT_UNIFORM)) { |
| str_eq_coeff->eq_subband_gain_count = |
| subband_gain_len_tbl[str_eq_coeff->eq_subband_gain_format]; |
| } else { |
| /* Gain format 0 or any value between 7 to 15 is considered as default |
| * case */ |
| eq_gain_cnt = impd_read_bits_buf(it_bit_buff, 8); |
| |
| if (it_bit_buff->error) return it_bit_buff->error; |
| str_eq_coeff->eq_subband_gain_count = eq_gain_cnt + 1; |
| |
| if (str_eq_coeff->eq_subband_gain_count > EQ_SUBBAND_GAIN_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| |
| } |
| |
| if (str_eq_coeff->eq_subband_gain_representation == 1) { |
| err = impd_parse_eq_subband_gain_spline( |
| it_bit_buff, &(str_eq_coeff->str_eq_subband_gain_spline[0]), |
| str_eq_coeff->unique_eq_subband_gains_count); |
| if (err) return (err); |
| } else { |
| err = impd_parse_eq_subband_gain_vector( |
| it_bit_buff, str_eq_coeff->eq_subband_gain_count, |
| &(str_eq_coeff->str_eq_subband_gain_vector[0]), |
| str_eq_coeff->unique_eq_subband_gains_count); |
| if (err) return (err); |
| } |
| } |
| |
| return (0); |
| } |
| |
| WORD32 impd_parser_td_filter_cascade( |
| ia_bit_buf_struct* it_bit_buff, |
| ia_eq_instructions_struct* str_eq_instructions, |
| ia_td_filter_cascade_struct* str_td_filter_cascade) { |
| // WORD32 err=0, |
| WORD32 i, ii, k; |
| WORD32 eq_cascade_gain; |
| ia_filter_block_refs_struct* str_filter_block_refs = |
| &(str_td_filter_cascade->str_filter_block_refs[0]); |
| |
| for (i = 0; i < str_eq_instructions->eq_ch_group_count; i++) { |
| str_td_filter_cascade->eq_cascade_gain_present[i] = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (str_td_filter_cascade->eq_cascade_gain_present[i]) { |
| eq_cascade_gain = impd_read_bits_buf(it_bit_buff, 10); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| str_td_filter_cascade->eq_cascade_gain[i] = |
| 0.125f * eq_cascade_gain - 96.0f; |
| } else { |
| str_td_filter_cascade->eq_cascade_gain[i] = 0.0f; |
| } |
| |
| str_filter_block_refs->filter_block_count = |
| impd_read_bits_buf(it_bit_buff, 4); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (str_filter_block_refs->filter_block_count > EQ_FILTER_BLOCK_COUNT_MAX) { |
| return (UNEXPECTED_ERROR); |
| } |
| |
| for (ii = 0; ii < str_filter_block_refs->filter_block_count; ii++) { |
| str_filter_block_refs->filter_block_index[ii] = |
| impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (str_filter_block_refs->filter_block_index[ii] >= |
| FILTER_BLOCK_COUNT_MAX) |
| return (UNEXPECTED_ERROR); |
| } |
| str_filter_block_refs++; |
| } |
| |
| str_td_filter_cascade->eq_phase_alignment_present = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (str_td_filter_cascade->eq_phase_alignment_present) { |
| for (i = 0; i < str_eq_instructions->eq_ch_group_count; i++) { |
| for (k = i + 1; k < str_eq_instructions->eq_ch_group_count; k++) { |
| str_td_filter_cascade->eq_phase_alignment[i][k] = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| } |
| |
| } else { |
| for (i = 0; i < str_eq_instructions->eq_ch_group_count; i++) { |
| for (k = i + 1; k < str_eq_instructions->eq_ch_group_count; k++) |
| str_td_filter_cascade->eq_phase_alignment[i][k] = 1; |
| } |
| } |
| |
| return (0); |
| } |
| |
| WORD32 impd_parse_eq_instructions( |
| ia_bit_buf_struct* it_bit_buff, ia_drc_config* drc_config, |
| ia_eq_instructions_struct* str_eq_instructions) { |
| WORD32 i, channel_count, temp; |
| WORD32 dmix_id_present, additional_dmix_id_present, |
| additional_dmix_id_cnt = 0; |
| WORD32 additional_drc_set_id_present, additional_drc_set_id_cnt; |
| |
| temp = impd_read_bits_buf(it_bit_buff, 11); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| str_eq_instructions->eq_set_id = (temp >> 5) & 0x3F; |
| |
| if (str_eq_instructions->eq_set_id >= EQ_INSTRUCTIONS_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| |
| str_eq_instructions->eq_set_complexity_level = (temp >> 1) & 0x0F; |
| |
| dmix_id_present = temp & 0x01; |
| |
| if (dmix_id_present) { |
| temp = impd_read_bits_buf(it_bit_buff, 9); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| str_eq_instructions->downmix_id[0] = (temp >> 2) & 0x7F; |
| |
| str_eq_instructions->eq_apply_to_downmix = (temp >> 1) & 0x01; |
| |
| additional_dmix_id_present = temp & 0x01; |
| |
| if (additional_dmix_id_present) { |
| additional_dmix_id_cnt = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (additional_dmix_id_cnt >= DOWNMIX_ID_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| |
| for (i = 1; i < additional_dmix_id_cnt + 1; i++) { |
| str_eq_instructions->downmix_id[i] = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| } |
| } else { |
| str_eq_instructions->downmix_id[0] = 0; |
| } |
| |
| str_eq_instructions->dwnmix_id_count = 1 + additional_dmix_id_cnt; |
| |
| temp = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| str_eq_instructions->drc_set_id[0] = (temp >> 1) & 0x3F; |
| |
| additional_drc_set_id_present = temp & 0x01; |
| |
| if (additional_drc_set_id_present) { |
| additional_drc_set_id_cnt = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (additional_drc_set_id_cnt >= DRC_SET_ID_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| |
| for (i = 1; i < additional_drc_set_id_cnt + 1; i++) { |
| str_eq_instructions->drc_set_id[i] = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| } else { |
| additional_drc_set_id_cnt = 0; |
| } |
| str_eq_instructions->drc_set_id_count = 1 + additional_drc_set_id_cnt; |
| |
| temp = impd_read_bits_buf(it_bit_buff, 17); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| str_eq_instructions->eq_set_purpose = (temp >> 1) & 0xFFFF; |
| |
| str_eq_instructions->depends_on_eq_set_present = temp & 0x01; |
| |
| if (str_eq_instructions->depends_on_eq_set_present) { |
| str_eq_instructions->depends_on_eq_set = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } else { |
| str_eq_instructions->no_independent_eq_use = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| |
| str_eq_instructions->eq_channel_count = channel_count = |
| drc_config->channel_layout.base_channel_count; |
| |
| if ((dmix_id_present == 1) && |
| (str_eq_instructions->eq_apply_to_downmix == 1) && |
| (str_eq_instructions->downmix_id[0] != 0) && |
| (str_eq_instructions->downmix_id[0] != ID_FOR_ANY_DOWNMIX) && |
| (str_eq_instructions->dwnmix_id_count == 1)) { |
| for (i = 0; i < drc_config->dwnmix_instructions_count; i++) { |
| if (str_eq_instructions->downmix_id[0] == |
| drc_config->dwnmix_instructions[i].downmix_id) |
| break; |
| } |
| if (i == drc_config->dwnmix_instructions_count) { |
| return UNEXPECTED_ERROR; |
| } |
| |
| str_eq_instructions->eq_channel_count = channel_count = |
| drc_config->dwnmix_instructions[i].target_channel_count; |
| } else if ((str_eq_instructions->downmix_id[0] == ID_FOR_ANY_DOWNMIX) || |
| (str_eq_instructions->dwnmix_id_count > 1)) { |
| channel_count = 1; |
| } |
| |
| str_eq_instructions->eq_ch_group_count = 0; |
| |
| for (i = 0; i < channel_count; i++) { |
| WORD32 tmp = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (tmp >= EQ_CHANNEL_GROUP_COUNT_MAX) return UNEXPECTED_ERROR; |
| str_eq_instructions->eq_ch_group_of_channel[i] = tmp; |
| } |
| { |
| WORD32 total; |
| WORD32 groups_used[EQ_CHANNEL_GROUP_COUNT_MAX] = {0}; |
| for (i = 0; i < channel_count; i++) |
| groups_used[str_eq_instructions->eq_ch_group_of_channel[i]] = 1; |
| total = 0; |
| for (i = 0; i < EQ_CHANNEL_GROUP_COUNT_MAX; i++) |
| if (groups_used[i]) total++; |
| str_eq_instructions->eq_ch_group_count = total; |
| } |
| |
| if (str_eq_instructions->eq_ch_group_count > EQ_CHANNEL_GROUP_COUNT_MAX) |
| return (UNEXPECTED_ERROR); |
| |
| str_eq_instructions->td_filter_cascade_present = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (str_eq_instructions->td_filter_cascade_present) { |
| WORD32 err = impd_parser_td_filter_cascade( |
| it_bit_buff, str_eq_instructions, |
| &(str_eq_instructions->str_td_filter_cascade)); |
| if (err) return err; |
| } |
| |
| str_eq_instructions->subband_gains_present = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (str_eq_instructions->subband_gains_present) { |
| for (i = 0; i < str_eq_instructions->eq_ch_group_count; i++) { |
| WORD32 tmp = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (tmp >= UNIQUE_SUBBAND_GAIN_COUNT_MAX) return UNEXPECTED_ERROR; |
| str_eq_instructions->subband_gains_index[i] = tmp; |
| } |
| } |
| |
| str_eq_instructions->eq_transition_duration_present = |
| impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (str_eq_instructions->eq_transition_duration_present) { |
| WORD32 bs_eq_transition_duration; |
| bs_eq_transition_duration = impd_read_bits_buf(it_bit_buff, 5); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| str_eq_instructions->eq_transition_duration = (WORD32)( |
| 0.001f * |
| (FLOAT32)pow(2.0f, 2.0f + bs_eq_transition_duration * 0.0625f)); |
| } |
| return (0); |
| } |
| |
| WORD32 impd_parse_loud_eq_instructions( |
| ia_bit_buf_struct* it_bit_buff, |
| ia_loud_eq_instructions_struct* loud_eq_instructions) { |
| WORD32 i, bs_loud_eq_scaling, bs_loud_eq_offset, temp; |
| WORD32 dmix_id_present, additional_dmix_id_present, |
| additional_dmix_id_cnt = 0; |
| WORD32 drc_set_id_present, additional_drc_set_id_present, |
| additional_drc_set_id_cnt = 0; |
| WORD32 eq_set_id_present, additional_eq_set_id_present, |
| additional_eq_set_id_cnt = 0; |
| |
| temp = impd_read_bits_buf(it_bit_buff, 9); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| loud_eq_instructions->loud_eq_set_id = (temp >> 5) & 0x0F; |
| |
| loud_eq_instructions->drc_location = (temp >> 1) & 0x0F; |
| |
| dmix_id_present = temp & 0x01; |
| |
| if (dmix_id_present) { |
| temp = impd_read_bits_buf(it_bit_buff, 8); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| loud_eq_instructions->downmix_id[0] = (temp >> 1) & 0x7F; |
| |
| additional_dmix_id_present = temp & 0x01; |
| |
| if (additional_dmix_id_present) { |
| additional_dmix_id_cnt = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (additional_dmix_id_cnt >= DOWNMIX_ID_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| for (i = 1; i < additional_dmix_id_cnt + 1; i++) { |
| loud_eq_instructions->downmix_id[i] = |
| impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| } |
| } else { |
| loud_eq_instructions->downmix_id[0] = 0; |
| } |
| |
| loud_eq_instructions->dwnmix_id_count = 1 + additional_dmix_id_cnt; |
| |
| drc_set_id_present = impd_read_bits_buf(it_bit_buff, 1); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (drc_set_id_present) { |
| temp = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| loud_eq_instructions->drc_set_id[0] = (temp >> 1) & 0x3F; |
| |
| additional_drc_set_id_present = temp & 0x01; |
| |
| if (additional_drc_set_id_present) { |
| additional_drc_set_id_cnt = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if ((additional_drc_set_id_cnt >= DRC_SET_ID_COUNT_MAX)) |
| return UNEXPECTED_ERROR; |
| |
| for (i = 1; i < additional_drc_set_id_cnt + 1; i++) { |
| loud_eq_instructions->drc_set_id[i] = |
| impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| } |
| } else { |
| loud_eq_instructions->drc_set_id[0] = 0; |
| } |
| |
| loud_eq_instructions->drc_set_id_count = 1 + additional_drc_set_id_cnt; |
| |
| eq_set_id_present = impd_read_bits_buf(it_bit_buff, 1); |
| |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| if (eq_set_id_present) { |
| temp = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| loud_eq_instructions->eq_set_id[0] = (temp >> 1) & 0x3F; |
| |
| additional_eq_set_id_present = temp & 0x01; |
| |
| if (additional_eq_set_id_present) { |
| additional_eq_set_id_cnt = impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| if (additional_eq_set_id_cnt >= EQ_SET_ID_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| for (i = 0; i < additional_eq_set_id_cnt; i++) { |
| loud_eq_instructions->eq_set_id[i + 1] = |
| impd_read_bits_buf(it_bit_buff, 6); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } |
| } |
| } else { |
| loud_eq_instructions->eq_set_id[0] = 0; |
| } |
| loud_eq_instructions->eq_set_id_count = 1 + additional_eq_set_id_cnt; |
| |
| temp = impd_read_bits_buf(it_bit_buff, 8); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| /* Parsed but unused */ |
| loud_eq_instructions->loudness_after_drc = (temp >> 7) & 0x01; |
| |
| /* Parsed but unused */ |
| loud_eq_instructions->loudness_after_eq = (temp >> 6) & 0x01; |
| |
| /* Parsed but unused */ |
| loud_eq_instructions->loud_eq_gain_sequence_count = temp & 0x3F; |
| |
| if (loud_eq_instructions->loud_eq_gain_sequence_count > |
| LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX) |
| return UNEXPECTED_ERROR; |
| |
| /* Section under for loop, Parsed but unused */ |
| for (i = 0; i < loud_eq_instructions->loud_eq_gain_sequence_count; i++) { |
| temp = impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| loud_eq_instructions->gain_seq_idx[i] = (temp >> 1) & 0x3F; |
| |
| loud_eq_instructions->drc_characteristic_format_is_cicp[i] = temp & 0x01; |
| |
| if (loud_eq_instructions->drc_characteristic_format_is_cicp[i]) { |
| loud_eq_instructions->drc_characteristic[i] = |
| impd_read_bits_buf(it_bit_buff, 7); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| } else { |
| temp = impd_read_bits_buf(it_bit_buff, 8); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| loud_eq_instructions->drc_characteristic_left_index[i] = |
| (temp >> 4) & 0x0F; |
| |
| loud_eq_instructions->drc_characteristic_right_index[i] = temp & 0x0F; |
| } |
| |
| temp = impd_read_bits_buf(it_bit_buff, 9); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| loud_eq_instructions->frequency_range_index[i] = (temp >> 3) & 0x3F; |
| |
| bs_loud_eq_scaling = temp & 0x07; |
| |
| loud_eq_instructions->loud_eq_scaling[i] = |
| (FLOAT32)pow(2.0f, -0.5f * bs_loud_eq_scaling); |
| |
| bs_loud_eq_offset = impd_read_bits_buf(it_bit_buff, 5); |
| if (it_bit_buff->error) return it_bit_buff->error; |
| |
| loud_eq_instructions->loud_eq_offset[i] = 1.5f * bs_loud_eq_offset - 16.0f; |
| } |
| return (0); |
| } |