/****************************************************************************** * * * 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 #include "ixheaac_type_def.h" #include "ixheaac_constants.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_config.h" #include "ixheaacd_qmf_dec.h" #include "ixheaacd_audioobjtypes.h" #include "ixheaacd_mps_polyphase.h" #include "ixheaacd_mps_struct_def.h" #include "ixheaacd_mps_res_rom.h" #include "ixheaacd_mps_defines.h" #include "ixheaacd_mps_aac_struct.h" #include "ixheaacd_mps_dec.h" #include "ixheaacd_mps_nlc_dec.h" #include "ixheaac_error_standards.h" static const WORD32 ixheaacd_freq_res_table[] = {0, 28, 20, 14, 10, 7, 5, 4}; static const WORD32 ixheaacd_freq_res_table_ld[] = {0, 23, 15, 12, 9, 7, 5, 4}; static const WORD32 ixheaacd_hybrid_band_71_to_processing_band_4_map[MAX_HYBRID_BANDS_MPS] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; static const WORD32 ixheaacd_hybrid_band_71_to_processing_band_5_map[MAX_HYBRID_BANDS_MPS] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; static const WORD32 ixheaacd_hybrid_band_71_to_processing_band_7_map[MAX_HYBRID_BANDS_MPS] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}; static const WORD32 ixheaacd_hybrid_band_71_to_processing_band_10_map[MAX_HYBRID_BANDS_MPS] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; static const WORD32 ixheaacd_hybrid_band_71_to_processing_band_14_map[MAX_HYBRID_BANDS_MPS] = { 0, 0, 0, 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}; const WORD32 ixheaacd_hybrid_band_71_to_processing_band_20_map[MAX_HYBRID_BANDS_MPS] = { 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19}; const WORD32 ixheaacd_hybrid_band_71_to_processing_band_28_map[MAX_HYBRID_BANDS_MPS] = { 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27}; const WORD32 ixheaacd_hybrid_band_64_to_processing_band_4_map[MAX_HYBRID_BANDS_MPS] = {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; const WORD32 ixheaacd_hybrid_band_64_to_processing_band_5_map[MAX_HYBRID_BANDS_MPS] = {0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; const WORD32 ixheaacd_hybrid_band_64_to_processing_band_7_map[MAX_HYBRID_BANDS_MPS] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}; const WORD32 ixheaacd_hybrid_band_64_to_processing_band_9_map[MAX_HYBRID_BANDS_MPS] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; const WORD32 ixheaacd_hybrid_band_64_to_processing_band_12_map[MAX_HYBRID_BANDS_MPS] = {0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}; const WORD32 ixheaacd_hybrid_band_64_to_processing_band_15_map[MAX_HYBRID_BANDS_MPS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14}; const WORD32 ixheaacd_hybrid_band_64_to_processing_band_23_map[MAX_HYBRID_BANDS_MPS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22}; static const FLOAT32 ixheaacd_mps_clip_gain_table[] = { 1.000000f, 1.189207f, 1.414213f, 1.681792f, 2.000000f, 2.378414f, 2.828427f, 4.000000f}; static const WORD32 ixheaacd_mps_stride_table[] = {1, 2, 5, 28}; static const FLOAT32 ixheaacd_cld_de_quant_table[] = { -150.0, -45.0, -40.0, -35.0, -30.0, -25.0, -22.0, -19.0, -16.0, -13.0, -10.0, -8.0, -6.0, -4.0, -2.0, 0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 13.0, 16.0, 19.0, 22.0, 25.0, 30.0, 35.0, 40.0, 45.0, 150.0}; static const FLOAT32 ixheaacd_icc_de_quant_table[] = { 1.0000f, 0.9370f, 0.84118f, 0.60092f, 0.36764f, 0.0f, -0.5890f, -0.9900f}; const FLOAT32 ixheaacd_ipd_de_quant_table[] = { 0.f, 0.392699082f, 0.785398163f, 1.178097245f, 1.570796327f, 1.963495408f, 2.35619449f, 2.748893572f, 3.141592654f, 3.534291735f, 3.926990817f, 4.319689899f, 4.71238898f, 5.105088062f, 5.497787144f, 5.890486225f}; const WORD32 ixheaacd_ipd_de_quant_table_q28[] = { 0, 105414360, 210828720, 316243072, 421657440, 527071776, 632486144, 737900480, 843314880, 948729216, 1054143552, 1159557888, 1264972288, 1370386688, 1475800960, 1581215360}; static const WORD32 ixheaacd_smoothing_time_table[] = {64, 128, 256, 512}; static const FLOAT32 ixheaacd_inverse_smoothing_time_table[] = { 1.0f / 64.0f, 1.0f / 128.0f, 1.0f / 256.0f, 1.0f / 512.0f}; static WORD32 bound_check(WORD32 var, WORD32 lower_bound, WORD32 upper_bound) { var = min(var, upper_bound); var = max(var, lower_bound); return var; } static VOID ixheaacd_longmult1(UWORD16 a[], UWORD16 b, UWORD16 d[], WORD32 len) { WORD32 k; UWORD32 tmp; UWORD32 b0 = (UWORD32)b; tmp = ((UWORD32)a[0]) * b0; d[0] = (UWORD16)tmp; for (k = 1; k < len; k++) { tmp = (tmp >> 16) + ((UWORD32)a[k]) * b0; d[k] = (UWORD16)tmp; } } static VOID ixheaacd_longdiv(UWORD16 b[], UWORD16 a, UWORD16 d[], UWORD16 *pr, WORD32 len) { UWORD32 r; UWORD32 tmp; UWORD32 temp; WORD32 k; if (a == 0) return; r = 0; for (k = len - 1; k >= 0; k--) { tmp = ((UWORD32)b[k]) + (r << 16); if (tmp) { d[k] = (UWORD16)(tmp / a); temp = d[k] * a; r = tmp - temp; } else { d[k] = 0; } } *pr = (UWORD16)r; } static VOID ixheaacd_longsub(UWORD16 a[], UWORD16 b[], WORD32 lena, WORD32 lenb) { WORD32 h; WORD32 carry = 0; if (lenb > lena) return; for (h = 0; h < lenb; h++) { carry = carry + (WORD32)(a[h] - b[h]); a[h] = (UWORD16)carry; carry = carry >> 16; } for (; h < lena; h++) { carry = ((UWORD32)a[h]) + carry; a[h] = (UWORD16)carry; carry = carry >> 16; } if (carry != 0) return; return; } static WORD32 ixheaacd_longcompare(UWORD16 a[], UWORD16 b[], WORD32 len) { WORD32 i; for (i = len - 1; i > 0; i--) { if (a[i] != b[i]) break; } return (a[i] >= b[i]) ? 1 : 0; } static VOID ixheaacd_mps_coarse2fine(WORD32 *data, WORD32 data_type, WORD32 band_start, WORD32 ixheaacd_num_bands) { WORD32 i; for (i = band_start; i < band_start + ixheaacd_num_bands; i++) { data[i] <<= 1; } if (data_type == CLD) { for (i = band_start; i < band_start + ixheaacd_num_bands; i++) { if (data[i] == -14) data[i] = -15; else if (data[i] == 14) data[i] = 15; } } } static VOID ixheaacd_mps_fine2coarse(WORD32 *data, WORD32 ixheaacd_num_bands) { WORD32 i; for (i = 0; i < ixheaacd_num_bands; i++) { data[i] /= 2; } } static WORD32 ixheaacd_mps_getstridemap(WORD32 freq_res_stride, WORD32 band_start, WORD32 band_stop, WORD32 *strides) { WORD32 i, pb, ch_fac, data_bands, start_offset; ch_fac = ixheaacd_mps_stride_table[freq_res_stride]; data_bands = (band_stop - band_start - 1) / ch_fac + 1; strides[0] = band_start; for (pb = 1; pb <= data_bands; pb++) { strides[pb] = strides[pb - 1] + ch_fac; } start_offset = 0; while (strides[data_bands] > band_stop) { if (start_offset < data_bands) start_offset++; else start_offset = 1; for (i = start_offset; i <= data_bands; i++) { strides[i]--; } } return data_bands; } static IA_ERRORCODE ixheaacd_mps_ecdata_decoding( ia_mps_dec_state_struct *self, ia_bit_buf_struct *bitstream, WORD32 data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], WORD32 datatype) { WORD32 i, j, pb, set_index, bs_data_pair, data_bands, old_quant_coarse_xxx; WORD32 strides[MAX_PARAMETER_BANDS + 1] = {0}; WORD32 band_stop = 0; WORD32 *lastdata = NULL; ia_mps_data_struct *frame_xxx_data = NULL; WORD32 default_val = 0; IA_ERRORCODE err = IA_NO_ERROR; ia_mps_bs_frame *frame = &(self->bs_frame); if (datatype == 0) { frame_xxx_data = &frame->cld_data; lastdata = frame->cmp_cld_idx_prev; band_stop = self->bs_param_bands; } else if (datatype == 1) { frame_xxx_data = &frame->icc_data; lastdata = frame->cmp_icc_idx_prev; band_stop = self->bs_param_bands; } else if (datatype == 2) { frame_xxx_data = &frame->ipd_data; lastdata = frame->ipd_idx_data_prev; band_stop = self->num_bands_ipd; } else { frame_xxx_data = &frame->cld_data; lastdata = frame->cmp_cld_idx_prev; band_stop = self->bs_param_bands; } for (i = 0; i < self->num_parameter_sets; i++) { frame_xxx_data->bs_xxx_data_mode[i] = ixheaacd_read_bits_buf(bitstream, 2); } set_index = 0; bs_data_pair = 0; old_quant_coarse_xxx = frame_xxx_data->bs_quant_coarse_xxx_prev; for (i = 0; i < self->num_parameter_sets; i++) { if (frame_xxx_data->bs_xxx_data_mode[i] == 0) { for (pb = 0; pb < band_stop; pb++) { lastdata[pb] = default_val; } old_quant_coarse_xxx = 0; } if (frame_xxx_data->bs_xxx_data_mode[i] == 3) { if (bs_data_pair) { bs_data_pair = 0; } else { bs_data_pair = ixheaacd_read_bits_buf(bitstream, 1); frame_xxx_data->bs_quant_coarse_xxx[set_index] = ixheaacd_read_bits_buf(bitstream, 1); frame_xxx_data->bs_freq_res_stride_xxx[set_index] = ixheaacd_read_bits_buf(bitstream, 2); if (frame_xxx_data->bs_quant_coarse_xxx[set_index] != old_quant_coarse_xxx) { if (old_quant_coarse_xxx) { ixheaacd_mps_coarse2fine(lastdata, datatype, 0, band_stop - 0); } else { ixheaacd_mps_fine2coarse(lastdata, band_stop); } } data_bands = ixheaacd_mps_getstridemap( frame_xxx_data->bs_freq_res_stride_xxx[set_index], 0, band_stop, strides); for (pb = 0; pb < data_bands; pb++) { lastdata[pb] = lastdata[strides[pb]]; } err = ixheaacd_mps_ecdatapairdec( bitstream, data, lastdata, datatype, set_index, 0, data_bands, bs_data_pair, frame_xxx_data->bs_quant_coarse_xxx[set_index], !(frame->independency_flag && (i == 0)) || (set_index > 0), 0, 0, self->ec_flag); if (err) return err; for (pb = 0; pb < data_bands; pb++) { for (j = strides[pb]; j < strides[pb + 1]; j++) { if (datatype == IPD) { if (frame_xxx_data->bs_quant_coarse_xxx[set_index]) { lastdata[j] = data[set_index + bs_data_pair][pb] & 7; } else { lastdata[j] = data[set_index + bs_data_pair][pb] & 15; } } else { lastdata[j] = data[set_index + bs_data_pair][pb]; } } } old_quant_coarse_xxx = frame_xxx_data->bs_quant_coarse_xxx[set_index]; if (bs_data_pair) { frame_xxx_data->bs_quant_coarse_xxx[set_index + 1] = frame_xxx_data->bs_quant_coarse_xxx[set_index]; frame_xxx_data->bs_freq_res_stride_xxx[set_index + 1] = frame_xxx_data->bs_freq_res_stride_xxx[set_index]; } set_index += bs_data_pair + 1; } } } return err; } IA_ERRORCODE ixheaacd_mps_frame_parsing(ia_mps_dec_state_struct *self, WORD32 usac_independency_flag, ia_bit_buf_struct *bitstream) { WORD32 i, bs_frame_type, data_bands, bs_temp_shape_enable, num_of_temp_shape_ch; WORD32 ps, pg, ts, pb; WORD32 env_shape_data[MAX_TIME_SLOTS]; WORD32 bits_param_slot = 0; ia_mps_bs_frame *frame = &(self->bs_frame); IA_ERRORCODE err = IA_NO_ERROR; if (self->parse_nxt_frame == 0) return IA_NO_ERROR; self->num_parameter_sets_prev = self->num_parameter_sets; if (self->bs_high_rate_mode) { bs_frame_type = ixheaacd_read_bits_buf(bitstream, 1); self->num_parameter_sets = ixheaacd_read_bits_buf(bitstream, 3) + 1; } else { bs_frame_type = 0; self->num_parameter_sets = 1; } if (self->time_slots == 32) bits_param_slot = 5; else if (self->time_slots == 64) bits_param_slot = 6; if (bs_frame_type) { WORD32 prev_param_slot = -1; for (i = 0; i < self->num_parameter_sets; i++) { self->param_slots[i] = ixheaacd_read_bits_buf(bitstream, bits_param_slot); if (prev_param_slot >= self->param_slots[i] || self->param_slots[i] >= self->time_slots) { return IA_FATAL_ERROR; } prev_param_slot = self->param_slots[i]; } } else { for (i = 0; i < self->num_parameter_sets; i++) { self->param_slots[i] = (((self->time_slots * (i + 1)) + self->num_parameter_sets - 1) / self->num_parameter_sets) - 1; } } if (!usac_independency_flag) { frame->independency_flag = ixheaacd_read_bits_buf(bitstream, 1); } else { frame->independency_flag = 1; } err = ixheaacd_mps_ecdata_decoding(self, bitstream, frame->cmp_cld_idx, CLD); if (err) return err; err = ixheaacd_mps_ecdata_decoding(self, bitstream, frame->cmp_icc_idx, ICC); if (err) return err; if (self->config->bs_phase_coding) { self->bs_phase_mode = ixheaacd_read_bits_buf(bitstream, 1); if (!self->bs_phase_mode) { for (pb = 0; pb < self->num_bands_ipd; pb++) { frame->ipd_idx_data_prev[pb] = 0; for (i = 0; i < self->num_parameter_sets; i++) { frame->ipd_idx_data[i][pb] = 0; self->bs_frame.ipd_idx[i][pb] = 0; } self->bs_frame.ipd_idx_prev[pb] = 0; } self->opd_smoothing_mode = 0; } else { self->opd_smoothing_mode = ixheaacd_read_bits_buf(bitstream, 1); err = ixheaacd_mps_ecdata_decoding(self, bitstream, frame->ipd_idx_data, IPD); if (err) return err; } } else { self->bs_phase_mode = 0; for (pb = 0; pb < self->num_bands_ipd; pb++) { frame->ipd_idx_data_prev[pb] = 0; for (i = 0; i < self->num_parameter_sets; i++) { frame->ipd_idx_data[i][pb] = 0; self->bs_frame.ipd_idx[i][pb] = 0; } self->bs_frame.ipd_idx_prev[pb] = 0; } self->opd_smoothing_mode = 0; } if (self->bs_high_rate_mode) { for (ps = 0; ps < self->num_parameter_sets; ps++) { frame->bs_smooth_mode[ps] = ixheaacd_read_bits_buf(bitstream, 2); if (frame->bs_smooth_mode[ps] >= 2) { frame->bs_smooth_time[ps] = ixheaacd_read_bits_buf(bitstream, 2); } if (frame->bs_smooth_mode[ps] == 3) { frame->bs_freq_res_stride_smg[ps] = ixheaacd_read_bits_buf(bitstream, 2); data_bands = (self->bs_param_bands - 1) / ixheaacd_mps_stride_table[frame->bs_freq_res_stride_smg[ps]] + 1; for (pg = 0; pg < data_bands; pg++) { frame->bs_smg_data[ps][pg] = ixheaacd_read_bits_buf(bitstream, 1); } } } } else { for (ps = 0; ps < self->num_parameter_sets; ps++) { frame->bs_smooth_mode[ps] = 0; } } for (i = 0; i < 2; i++) { self->temp_shape_enable_ch_stp[i] = 0; self->temp_shape_enable_ch_ges[i] = 0; } self->bs_tsd_enable = 0; if (self->config->bs_temp_shape_config == 3) { self->bs_tsd_enable = ixheaacd_read_bits_buf(bitstream, 1); } else if (self->config->bs_temp_shape_config != 0) { bs_temp_shape_enable = ixheaacd_read_bits_buf(bitstream, 1); if (bs_temp_shape_enable) { num_of_temp_shape_ch = 2; switch (self->config->bs_temp_shape_config) { case 1: for (i = 0; i < num_of_temp_shape_ch; i++) { self->temp_shape_enable_ch_stp[i] = ixheaacd_read_bits_buf(bitstream, 1); } break; case 2: for (i = 0; i < num_of_temp_shape_ch; i++) { self->temp_shape_enable_ch_ges[i] = ixheaacd_read_bits_buf(bitstream, 1); } for (i = 0; i < num_of_temp_shape_ch; i++) { if (self->temp_shape_enable_ch_ges[i]) { ixheaacd_mps_huff_decode(bitstream, env_shape_data, self->time_slots); for (ts = 0; ts < self->time_slots; ts++) { self->env_shape_data[i][ts] = (FLOAT32)pow( 2, (FLOAT32)env_shape_data[ts] / (self->config->bs_env_quant_mode + 2) - 1); } } } break; default: return -1; } } } if (self->bs_tsd_enable) { UWORD16 s[4]; UWORD64 s_64; UWORD16 c[5]; UWORD64 c_64; UWORD16 b; UWORD16 r[1]; static const UWORD16 table_64[] = { 6, 11, 16, 20, 23, 27, 30, 33, 35, 38, 40, 42, 44, 46, 48, 49, 51, 52, 53, 55, 56, 57, 58, 58, 59, 60, 60, 60, 61, 61, 61, 61}; static const UWORD16 table_32[] = {5, 9, 13, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 29, 30, 30}; unsigned const short *tab = NULL; WORD32 k; UWORD16 h; WORD32 nbits_tr_slots = 0; if (self->time_slots == 32) { nbits_tr_slots = 4; tab = table_32; } else if (self->time_slots == 64) { nbits_tr_slots = 5; tab = table_64; } self->tsd_num_tr_slots = ixheaacd_read_bits_buf(bitstream, nbits_tr_slots); self->tsd_num_tr_slots++; self->tsd_codeword_len = tab[self->tsd_num_tr_slots - 1]; if (self->tsd_codeword_len > 48) { s[3] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len - 48); s_64 = s[3]; s[2] = ixheaacd_read_bits_buf(bitstream, 16); s_64 = (s_64 << 16) | s[2]; s[1] = ixheaacd_read_bits_buf(bitstream, 16); s_64 = (s_64 << 16) | s[1]; s[0] = ixheaacd_read_bits_buf(bitstream, 16); s_64 = (s_64 << 16) | s[0]; } else if (self->tsd_codeword_len > 32) { s[3] = 0; s_64 = s[3]; s[2] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len - 32); s_64 = (s_64 << 16) | s[2]; s[1] = ixheaacd_read_bits_buf(bitstream, 16); s_64 = (s_64 << 16) | s[1]; s[0] = ixheaacd_read_bits_buf(bitstream, 16); s_64 = (s_64 << 16) | s[0]; } else if (self->tsd_codeword_len > 16) { s[3] = 0; s_64 = s[3]; s[2] = 0; s_64 = (s_64 << 16) | s[2]; s[1] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len - 16); s_64 = (s_64 << 16) | s[1]; s[0] = ixheaacd_read_bits_buf(bitstream, 16); s_64 = (s_64 << 16) | s[0]; } else { s[3] = 0; s_64 = s[3]; s[2] = 0; s_64 = (s_64 << 16) | s[2]; s[1] = 0; s_64 = (s_64 << 16) | s[1]; s[0] = ixheaacd_read_bits_buf(bitstream, self->tsd_codeword_len); s_64 = (s_64 << 16) | s[0]; } { WORD32 p = self->tsd_num_tr_slots; for (i = 0; i < self->time_slots; i++) self->bs_tsd_sep_data[i] = 0; for (k = self->time_slots - 1; k >= 0; k--) { if (p > k) { for (; k >= 0; k--) self->bs_tsd_sep_data[k] = 1; break; } c[0] = k - p + 1; c_64 = c[0]; for (i = 1; i < 5; i++) c[i] = 0; for (h = 2; h <= p; h++) { b = k - p + h; c_64 = c_64 * (b / h); ixheaacd_longmult1(c, b, c, 5); b = h; ixheaacd_longdiv(c, b, c, r, 5); } if (ixheaacd_longcompare(s, c, 4)) { ixheaacd_longsub(s, c, 4, 4); self->bs_tsd_sep_data[k] = 1; p--; if (p == 0) break; } } } for (i = 0; i < self->time_slots; i++) { if (self->bs_tsd_sep_data[i]) self->bs_tsd_tr_phase_data[i] = ixheaacd_read_bits_buf(bitstream, 3); } } self->parse_nxt_frame = 0; return err; } static VOID ixheaacd_ld_mps_ecdata_decoding( ia_mps_dec_state_struct *self, ia_bit_buf_struct *it_bit_buff, WORD32 data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], WORD32 datatype, WORD32 start_band) { WORD32 i, j, pb, data_set, set_index, bs_data_pair, data_bands, old_quant_coarse_xxx; WORD32 strides[MAX_PARAMETER_BANDS + 1] = {0}; WORD32 band_stop = 0; WORD32 *lastdata = NULL; ia_mps_data_struct *frame_xxx_data = NULL; WORD32 default_val = 0; ia_mps_bs_frame *frame = &(self->bs_frame); if (datatype == CLD) { frame_xxx_data = &frame->cld_data; lastdata = frame->cmp_cld_idx_prev; band_stop = self->bs_param_bands; } else if (datatype == ICC) { frame_xxx_data = &frame->icc_data; lastdata = frame->cmp_icc_idx_prev; band_stop = self->bs_param_bands; } else if (datatype == IPD) { frame_xxx_data = &frame->ipd_data; lastdata = frame->ipd_idx_data_prev; band_stop = self->num_bands_ipd; } else { frame_xxx_data = &frame->cld_data; lastdata = frame->cmp_cld_idx_prev; band_stop = self->bs_param_bands; } data_set = 0; for (i = 0; i < self->num_parameter_sets; i++) { frame_xxx_data->bs_xxx_data_mode[i] = ixheaacd_read_bits_buf(it_bit_buff, 2); if (frame_xxx_data->bs_xxx_data_mode[i] == 3) { data_set++; } } set_index = 0; bs_data_pair = 0; old_quant_coarse_xxx = frame_xxx_data->bs_quant_coarse_xxx_prev; for (i = 0; i < self->num_parameter_sets; i++) { if (frame_xxx_data->bs_xxx_data_mode[i] == 0) { for (pb = 0; pb < band_stop; pb++) { lastdata[pb] = default_val; } old_quant_coarse_xxx = 0; } if (frame_xxx_data->bs_xxx_data_mode[i] == 3) { if (bs_data_pair) { bs_data_pair = 0; } else { bs_data_pair = ixheaacd_read_bits_buf(it_bit_buff, 1); frame_xxx_data->bs_quant_coarse_xxx[set_index] = ixheaacd_read_bits_buf(it_bit_buff, 1); frame_xxx_data->bs_freq_res_stride_xxx[set_index] = ixheaacd_read_bits_buf(it_bit_buff, 2); if (frame_xxx_data->bs_quant_coarse_xxx[set_index] != old_quant_coarse_xxx) { if (old_quant_coarse_xxx) { ixheaacd_mps_coarse2fine(lastdata, datatype, 0, band_stop - 0); } else { ixheaacd_mps_fine2coarse(lastdata, band_stop); } } data_bands = ixheaacd_mps_getstridemap( frame_xxx_data->bs_freq_res_stride_xxx[set_index], start_band, band_stop, strides); for (pb = 0; pb < data_bands; pb++) { lastdata[pb] = lastdata[strides[pb]]; } ixheaacd_mps_ecdatapairdec( it_bit_buff, data, lastdata, datatype, set_index, 0, data_bands, bs_data_pair, frame_xxx_data->bs_quant_coarse_xxx[set_index], !(frame->independency_flag && (i == 0)) || (set_index > 0), 1, 0, self->ec_flag); for (pb = 0; pb < data_bands; pb++) { for (j = strides[pb]; j < strides[pb + 1]; j++) { if (datatype == IPD) { if (frame_xxx_data->bs_quant_coarse_xxx[set_index]) { lastdata[j] = data[set_index + bs_data_pair][pb] & 7; } else { lastdata[j] = data[set_index + bs_data_pair][pb] & 15; } } else { lastdata[j] = data[set_index + bs_data_pair][pb]; } } } old_quant_coarse_xxx = frame_xxx_data->bs_quant_coarse_xxx[set_index]; if (bs_data_pair) { frame_xxx_data->bs_quant_coarse_xxx[set_index + 1] = frame_xxx_data->bs_quant_coarse_xxx[set_index]; frame_xxx_data->bs_freq_res_stride_xxx[set_index + 1] = frame_xxx_data->bs_freq_res_stride_xxx[set_index]; } set_index += bs_data_pair + 1; } } } } IA_ERRORCODE ixheaacd_ld_mps_frame_parsing( ia_mps_dec_state_struct *self, ia_bit_buf_struct *it_bit_buff) { WORD32 i, bs_frame_type, data_bands, bs_temp_shape_enable, num_of_temp_shape_ch; WORD32 ps, pg, ts, ic; WORD32 env_shape_data[MAX_TIME_SLOTS]; WORD32 alignment; WORD32 bits_param_slot = 0; ia_mps_bs_frame *frame = &(self->bs_frame); alignment = it_bit_buff->cnt_bits; if (self->parse_nxt_frame == 0) return IA_NO_ERROR; self->num_parameter_sets_prev = self->num_parameter_sets; bs_frame_type = ixheaacd_read_bits_buf(it_bit_buff, 1); self->num_parameter_sets = ixheaacd_read_bits_buf(it_bit_buff, 1) + 1; if (self->time_slots == 32) bits_param_slot = 5; else if (self->time_slots == 64) bits_param_slot = 6; else if (self->time_slots == 8) bits_param_slot = 3; else if (self->time_slots == 16 || self->time_slots == 15) bits_param_slot = 4; if (bs_frame_type) { WORD32 prev_param_slot = -1; for (i = 0; i < self->num_parameter_sets; i++) { self->param_slots[i] = ixheaacd_read_bits_buf(it_bit_buff, bits_param_slot); if (prev_param_slot >= self->param_slots[i] || self->param_slots[i] >= self->time_slots) { return IA_FATAL_ERROR; } prev_param_slot = self->param_slots[i]; } } else { for (i = 0; i < self->num_parameter_sets; i++) { self->param_slots[i] = (((self->time_slots * (i + 1)) + self->num_parameter_sets - 1) / self->num_parameter_sets) - 1; } } frame->independency_flag = ixheaacd_read_bits_buf(it_bit_buff, 1); for (i = 0; i < self->ldmps_config.num_ott_boxes; i++) { ixheaacd_ld_mps_ecdata_decoding(self, it_bit_buff, frame->cmp_cld_idx, CLD, 0); } if (self->ldmps_config.bs_one_icc) { ixheaacd_ld_mps_ecdata_decoding(self, it_bit_buff, frame->cmp_icc_idx, ICC, 0); } else { for (i = 0; i < self->ldmps_config.num_ott_boxes; i++) { if (!self->ldmps_config.ott_mode_lfe[i]) ixheaacd_ld_mps_ecdata_decoding(self, it_bit_buff, frame->cmp_icc_idx, ICC, 0); } } for (ps = 0; ps < self->num_parameter_sets; ps++) { frame->bs_smooth_mode[ps] = ixheaacd_read_bits_buf(it_bit_buff, 2); if (frame->bs_smooth_mode[ps] >= 2) { frame->bs_smooth_time[ps] = ixheaacd_read_bits_buf(it_bit_buff, 2); } if (frame->bs_smooth_mode[ps] == 3) { frame->bs_freq_res_stride_smg[ps] = ixheaacd_read_bits_buf(it_bit_buff, 2); data_bands = (ixheaacd_freq_res_table_ld[self->ldmps_config.bs_freq_res] - 1) / ixheaacd_mps_stride_table[frame->bs_freq_res_stride_smg[ps]] + 1; for (pg = 0; pg < data_bands; pg++) { frame->bs_smg_data[ps][pg] = ixheaacd_read_bits_buf(it_bit_buff, 1); } } } for (i = 0; i < 2; i++) { self->temp_shape_enable_ch_stp[i] = 0; self->temp_shape_enable_ch_ges[i] = 0; } if (self->ldmps_config.bs_temp_shape_config != 0) { bs_temp_shape_enable = ixheaacd_read_bits_buf(it_bit_buff, 1); if (bs_temp_shape_enable) { num_of_temp_shape_ch = 2; switch (self->ldmps_config.bs_temp_shape_config) { case 1: for (i = 0; i < num_of_temp_shape_ch; i++) { self->temp_shape_enable_ch_stp[i] = ixheaacd_read_bits_buf(it_bit_buff, 1); } break; case 2: for (i = 0; i < num_of_temp_shape_ch; i++) { self->temp_shape_enable_ch_ges[i] = ixheaacd_read_bits_buf(it_bit_buff, 1); } for (i = 0; i < num_of_temp_shape_ch; i++) { if (self->temp_shape_enable_ch_ges[i]) { ixheaacd_mps_huff_decode(it_bit_buff, env_shape_data, self->time_slots); for (ts = 0; ts < self->time_slots; ts++) { self->env_shape_data[i][ts] = (FLOAT32)pow( 2, (FLOAT32)env_shape_data[ts] / (self->ldmps_config.bs_env_quant_mode + 2) - 1); } } } break; default: if (self->ec_flag == 0) { return IA_FATAL_ERROR; } break; } } } if (self->ldmps_config.bs_arbitrary_downmix != 0) { for (ic = 0; ic < self->ldmps_config.num_input_channels; ic++) { ixheaacd_ld_mps_ecdata_decoding(self, it_bit_buff, frame->cmp_cld_idx, CLD, 0); } } ixheaacd_byte_align(it_bit_buff, &alignment); while (it_bit_buff->cnt_bits > 8) { ixheaacd_read_bits_buf(it_bit_buff, 8); } ixheaacd_read_bits_buf(it_bit_buff, it_bit_buff->cnt_bits); return IA_NO_ERROR; } static VOID ixheaacd_mps_createmapping(WORD32 map[MAX_PARAMETER_BANDS + 1], WORD32 band_start, WORD32 band_stop, WORD32 ch_fac) { WORD32 input_bands, out_bands, bands_achived, bands_diff, incr, k, i; WORD32 vdk[MAX_PARAMETER_BANDS + 1]; input_bands = band_stop - band_start; out_bands = (input_bands - 1) / ch_fac + 1; if (out_bands < 1) { out_bands = 1; } bands_achived = out_bands * ch_fac; bands_diff = input_bands - bands_achived; for (i = 0; i < out_bands; i++) { vdk[i] = ch_fac; } if (bands_diff > 0) { incr = -1; k = out_bands - 1; } else { incr = 1; k = 0; } while (bands_diff != 0) { vdk[k] = vdk[k] - incr; k = k + incr; bands_diff = bands_diff + incr; if (k >= out_bands) { if (bands_diff > 0) { k = out_bands - 1; } else if (bands_diff < 0) { k = 0; } } } map[0] = band_start; for (i = 0; i < out_bands; i++) { map[i + 1] = map[i] + vdk[i]; } } static VOID ixheaacd_mps_mapfrequency(WORD32 *in, WORD32 *out, WORD32 *map, WORD32 data_bands) { WORD32 i, j, band_start, band_stop, value; WORD32 start_band_0 = map[0]; for (i = 0; i < data_bands; i++) { value = in[i + start_band_0]; band_start = map[i]; band_stop = map[i + 1]; for (j = band_start; j < band_stop; j++) { out[j] = value; } } } static FLOAT32 ixheaacd_mps_de_quantize(WORD32 value, WORD32 param_type) { switch (param_type) { case CLD: return ixheaacd_cld_de_quant_table[(value + 15)]; case ICC: return ixheaacd_icc_de_quant_table[value]; case IPD: return ixheaacd_ipd_de_quant_table[(value & 15)]; default: return 0; return 0; } } static IA_ERRORCODE ixheaacd_mps_mapindexdata( ia_mps_dec_state_struct *self, ia_mps_data_struct *frame_xxx_data, FLOAT32 out_data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], WORD32 out_idx_data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], WORD32 cmp_idx_data[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS], WORD32 idx_prev[MAX_PARAMETER_BANDS], WORD32 param_type) { WORD32 interpolate_local[MAX_PARAMETER_SETS_MPS] = {0}; WORD32 map[MAX_PARAMETER_BANDS + 1]; WORD32 set_index, i, band, parm_slot; WORD32 data_bands, ch_fac; WORD32 ps; WORD32 i1, i2, x1, xi, x2; WORD32 band_start = 0; WORD32 ext_frame_flag = self->ext_frame_flag; WORD32 *param_slots = self->param_slots; WORD32 num_parameter_sets = self->num_parameter_sets; WORD32 band_stop = self->bs_param_bands; WORD32 default_val = 0; set_index = 0; for (i = 0; i < num_parameter_sets; i++) { if (frame_xxx_data->bs_xxx_data_mode[i] == 0) { frame_xxx_data->quant_coarse_xxx_flag[i] = 0; for (band = band_start; band < band_stop; band++) { out_idx_data[i][band] = default_val; } for (band = band_start; band < band_stop; band++) { idx_prev[band] = out_idx_data[i][band]; } frame_xxx_data->bs_quant_coarse_xxx_prev = 0; } if (frame_xxx_data->bs_xxx_data_mode[i] == 1) { for (band = band_start; band < band_stop; band++) { out_idx_data[i][band] = idx_prev[band]; } frame_xxx_data->quant_coarse_xxx_flag[i] = frame_xxx_data->bs_quant_coarse_xxx_prev; } if (frame_xxx_data->bs_xxx_data_mode[i] == 2) { for (band = band_start; band < band_stop; band++) { out_idx_data[i][band] = idx_prev[band]; } frame_xxx_data->quant_coarse_xxx_flag[i] = frame_xxx_data->bs_quant_coarse_xxx_prev; interpolate_local[i] = 1; } else { interpolate_local[i] = 0; } if (frame_xxx_data->bs_xxx_data_mode[i] == 3) { parm_slot = i; ch_fac = ixheaacd_mps_stride_table[frame_xxx_data ->bs_freq_res_stride_xxx[set_index]]; data_bands = (band_stop - band_start - 1) / ch_fac + 1; ixheaacd_mps_createmapping(map, band_start, band_stop, ch_fac); ixheaacd_mps_mapfrequency(&cmp_idx_data[set_index][0], &out_idx_data[parm_slot][0], map, data_bands); for (band = band_start; band < band_stop; band++) { idx_prev[band] = out_idx_data[parm_slot][band]; } frame_xxx_data->bs_quant_coarse_xxx_prev = frame_xxx_data->bs_quant_coarse_xxx[set_index]; frame_xxx_data->quant_coarse_xxx_flag[i] = frame_xxx_data->bs_quant_coarse_xxx[set_index]; set_index++; } } for (i = 0; i < num_parameter_sets; i++) { if (frame_xxx_data->quant_coarse_xxx_flag[i] == 1) { ixheaacd_mps_coarse2fine(out_idx_data[i], param_type, band_start, band_stop - band_start); frame_xxx_data->quant_coarse_xxx_flag[i] = 0; } } i1 = -1; x1 = 0; i2 = 0; for (i = 0; i < num_parameter_sets; i++) { if (interpolate_local[i] != 1) { i1 = i; } i2 = i; while (interpolate_local[i2] == 1) { i2++; } if (i1 == -1) { x1 = 0; i1 = 0; } else { x1 = param_slots[i1]; } xi = param_slots[i]; x2 = param_slots[i2]; if (interpolate_local[i] == 1) { if (i2 < num_parameter_sets) { if (self->ec_flag == 0) { return IA_FATAL_ERROR; } } for (band = band_start; band < band_stop; band++) { WORD32 yi, y1, y2; yi = 0; y1 = out_idx_data[i1][band]; y2 = out_idx_data[i2][band]; if (param_type == IPD) { if (y2 - y1 > 8) y1 += 16; if (y1 - y2 > 8) y2 += 16; if (x2 != x1) yi = (y1 + (xi - x1) * (y2 - y1) / (x2 - x1)) % 16; } else { if (x2 != x1) { yi = y1 + (xi - x1) * (y2 - y1) / (x2 - x1); } } out_idx_data[i][band] = yi; } } } for (ps = 0; ps < num_parameter_sets; ps++) { for (band = band_start; band < band_stop; band++) { if (param_type == CLD) { out_idx_data[ps][band] = bound_check(out_idx_data[ps][band], -15, 15); } else if (param_type == ICC) { out_idx_data[ps][band] = bound_check(out_idx_data[ps][band], 0, 7); } out_data[ps][band] = ixheaacd_mps_de_quantize(out_idx_data[ps][band], param_type); } } if (ext_frame_flag) { for (band = band_start; band < band_stop; band++) { out_data[num_parameter_sets][band] = out_data[num_parameter_sets - 1][band]; out_idx_data[num_parameter_sets][band] = out_idx_data[num_parameter_sets - 1][band]; } } return IA_NO_ERROR; } static IA_ERRORCODE ixheaacd_mps_dec_and_mapframeott( ia_mps_dec_state_struct *self) { ia_mps_bs_frame *cur_bit_stream_ptr = &(self->bs_frame); IA_ERRORCODE err_code = 0; err_code = ixheaacd_mps_mapindexdata( self, &cur_bit_stream_ptr->cld_data, self->cld_data, cur_bit_stream_ptr->cld_idx, cur_bit_stream_ptr->cmp_cld_idx, cur_bit_stream_ptr->cld_idx_pre, CLD); if (err_code != IA_NO_ERROR) return err_code; err_code = ixheaacd_mps_mapindexdata( self, &cur_bit_stream_ptr->icc_data, self->icc_data, cur_bit_stream_ptr->icc_idx, cur_bit_stream_ptr->cmp_icc_idx, cur_bit_stream_ptr->icc_idx_pre, ICC); if (err_code != IA_NO_ERROR) return err_code; if ((self->config->bs_phase_coding)) { err_code = ixheaacd_mps_mapindexdata( self, &cur_bit_stream_ptr->ipd_data, self->ipd_data, cur_bit_stream_ptr->ipd_idx, cur_bit_stream_ptr->ipd_idx_data, cur_bit_stream_ptr->ipd_idx_prev, IPD); if (err_code != IA_NO_ERROR) return err_code; } return IA_NO_ERROR; } static VOID ixheaacd_mps_dec_and_mapframesmg(ia_mps_dec_state_struct *self) { WORD32 ps, pb, pg, ch_fac, data_bands, param_band_start, param_band_stop, group_to_band[MAX_PARAMETER_BANDS + 1]; ia_mps_bs_frame *frame = &(self->bs_frame); for (ps = 0; ps < self->num_parameter_sets; ps++) { switch (frame->bs_smooth_mode[ps]) { case 0: self->smoothing_time[ps] = 256; self->inv_smoothing_time[ps] = (FLOAT32)(1.0f / 256.0f); for (pb = 0; pb < self->bs_param_bands; pb++) { self->smoothing_data[ps][pb] = 0; } break; case 1: if (ps > 0) { self->smoothing_time[ps] = self->smoothing_time[ps - 1]; self->inv_smoothing_time[ps] = self->inv_smoothing_time[ps - 1]; } else { self->smoothing_time[ps] = self->smoothing_filt_state.prev_smg_time; self->inv_smoothing_time[ps] = self->smoothing_filt_state.inv_prev_smg_time; } for (pb = 0; pb < self->bs_param_bands; pb++) { if (ps > 0) self->smoothing_data[ps][pb] = self->smoothing_data[ps - 1][pb]; else self->smoothing_data[ps][pb] = self->smoothing_filt_state.prev_smg_data[pb]; } break; case 2: self->smoothing_time[ps] = ixheaacd_smoothing_time_table[frame->bs_smooth_time[ps]]; self->inv_smoothing_time[ps] = ixheaacd_inverse_smoothing_time_table[frame->bs_smooth_time[ps]]; for (pb = 0; pb < self->bs_param_bands; pb++) { self->smoothing_data[ps][pb] = 1; } break; case 3: self->smoothing_time[ps] = ixheaacd_smoothing_time_table[frame->bs_smooth_time[ps]]; self->inv_smoothing_time[ps] = ixheaacd_inverse_smoothing_time_table[frame->bs_smooth_time[ps]]; ch_fac = ixheaacd_mps_stride_table[frame->bs_freq_res_stride_smg[ps]]; data_bands = (self->bs_param_bands - 1) / ch_fac + 1; ixheaacd_mps_createmapping(group_to_band, 0, self->bs_param_bands, ch_fac); for (pg = 0; pg < data_bands; pg++) { param_band_start = group_to_band[pg]; param_band_stop = group_to_band[pg + 1]; for (pb = param_band_start; pb < param_band_stop; pb++) { self->smoothing_data[ps][pb] = frame->bs_smg_data[ps][pg]; } } break; } } self->smoothing_filt_state.prev_smg_time = self->smoothing_time[self->num_parameter_sets - 1]; self->smoothing_filt_state.inv_prev_smg_time = self->inv_smoothing_time[self->num_parameter_sets - 1]; for (pb = 0; pb < self->bs_param_bands; pb++) { self->smoothing_filt_state.prev_smg_data[pb] = self->smoothing_data[self->num_parameter_sets - 1][pb]; } if (self->ext_frame_flag) { self->smoothing_time[self->num_parameter_sets] = self->smoothing_time[self->num_parameter_sets - 1]; self->inv_smoothing_time[self->num_parameter_sets] = self->inv_smoothing_time[self->num_parameter_sets - 1]; for (pb = 0; pb < self->bs_param_bands; pb++) { self->smoothing_data[self->num_parameter_sets][pb] = self->smoothing_data[self->num_parameter_sets - 1][pb]; } } } IA_ERRORCODE ixheaacd_mps_frame_decode(ia_mps_dec_state_struct *self) { WORD32 i; IA_ERRORCODE err_code = 0; if (self->ldmps_config.ldmps_present_flag != 1) if (self->parse_nxt_frame == 1) return err_code; self->ext_frame_flag = 0; if (self->param_slots[self->num_parameter_sets - 1] != self->time_slots - 1) { self->ext_frame_flag = 1; } err_code = ixheaacd_mps_dec_and_mapframeott(self); if (err_code != IA_NO_ERROR) return err_code; ixheaacd_mps_dec_and_mapframesmg(self); if (self->ext_frame_flag) { self->num_parameter_sets++; self->param_slots[self->num_parameter_sets - 1] = self->time_slots - 1; } self->param_slot_diff[0] = self->param_slots[0] + 1; if (MAX_TIME_SLOTS < (self->param_slot_diff[0])) { if (self->ec_flag == 0) { return -1; } else { self->param_slot_diff[0] = MAX_TIME_SLOTS; } } self->inv_param_slot_diff[0] = (FLOAT32)1 / self->param_slot_diff[0]; self->inv_param_slot_diff_Q30[0] = (WORD32)floor(self->inv_param_slot_diff[0] * 1073741824 + 0.5); for (i = 1; i < self->num_parameter_sets; i++) { self->param_slot_diff[i] = self->param_slots[i] - self->param_slots[i - 1]; if ((MAX_TIME_SLOTS < (self->param_slot_diff[0] + self->param_slot_diff[i])) || (self->param_slot_diff[i] == 0)) { if (self->ec_flag == 0) { return -1; } else { self->param_slot_diff[i] = 1; self->inv_param_slot_diff[i] = 1; } } self->inv_param_slot_diff[i] = (FLOAT32)1 / self->param_slot_diff[i]; self->inv_param_slot_diff_Q30[i] = (WORD32)floor(self->inv_param_slot_diff[i] * 1073741824 + 0.5); } return IA_NO_ERROR; } WORD32 ixheaacd_mps_header_decode(ia_mps_dec_state_struct *self) { WORD32 samp_freq; WORD32 sampling_rate_tbl[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0}; if (self->ldmps_config.ldmps_present_flag == 1) self->time_slots = self->frame_length + 1; else self->time_slots = self->frame_length; self->bs_param_bands = ixheaacd_freq_res_table[self->config->bs_freq_res]; if (self->ldmps_config.ldmps_present_flag == 1) { if (self->ldmps_config.bs_sampling_freq_index == 15) { samp_freq = self->ldmps_config.bs_fampling_frequency; } else { samp_freq = sampling_rate_tbl[self->ldmps_config.bs_sampling_freq_index]; } if (samp_freq < 27713.0) { self->qmf_band_count = 32; } else if (samp_freq >= 55426.0) { self->qmf_band_count = 128; } else { self->qmf_band_count = 64; } } if (self->object_type == AOT_ER_AAC_ELD || self->object_type == AOT_ER_AAC_LD) { self->bs_param_bands = ixheaacd_freq_res_table_ld[self->config->bs_freq_res]; self->hyb_band_count_max = self->qmf_band_count; } else self->hyb_band_count_max = self->qmf_band_count - QMF_BANDS_TO_HYBRID + 10; if (self->object_type == AOT_ER_AAC_ELD || self->object_type == AOT_ER_AAC_LD) { switch (self->bs_param_bands) { case 4: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_64_to_processing_band_4_map; break; case 5: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_64_to_processing_band_5_map; break; case 7: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_64_to_processing_band_7_map; break; case 9: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_64_to_processing_band_9_map; break; case 12: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_64_to_processing_band_12_map; break; case 15: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_64_to_processing_band_15_map; break; case 23: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_64_to_processing_band_23_map; break; default: self->hyb_band_to_processing_band_table = NULL; return -1; break; } } else { switch (self->bs_param_bands) { case 4: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_71_to_processing_band_4_map; break; case 5: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_71_to_processing_band_5_map; break; case 7: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_71_to_processing_band_7_map; break; case 10: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_71_to_processing_band_10_map; break; case 14: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_71_to_processing_band_14_map; break; case 20: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_71_to_processing_band_20_map; break; case 28: self->hyb_band_to_processing_band_table = ixheaacd_hybrid_band_71_to_processing_band_28_map; break; default: self->hyb_band_to_processing_band_table = NULL; return -1; break; } } self->in_ch_count = 1; self->out_ch_count = 2; self->input_gain = ixheaacd_mps_clip_gain_table[self->config->bs_fixed_gain_dmx]; if (self->config->bs_ott_bands_phase_present) { self->num_bands_ipd = self->config->bs_ott_bands_phase; } else { if (!(self->object_type == AOT_ER_AAC_ELD || self->object_type == AOT_ER_AAC_LD)) { switch (self->bs_param_bands) { case 4: case 5: self->num_bands_ipd = 2; break; case 7: self->num_bands_ipd = 3; break; case 10: self->num_bands_ipd = 5; break; case 14: self->num_bands_ipd = 7; break; case 20: case 28: self->num_bands_ipd = 10; break; default: return -1; break; } } } if (self->residual_coding) { self->num_bands_ipd = max(self->bs_residual_bands, self->num_bands_ipd); self->max_res_bands = 0; if (self->bs_residual_present) { self->res_bands = self->bs_residual_bands; if (self->res_bands > self->max_res_bands) { self->max_res_bands = self->res_bands; } } else { self->res_bands = 0; } } if (self->num_bands_ipd > MAX_PARAMETER_BANDS) return -1; self->dir_sig_count = 1; self->decor_sig_count = 1; self->bs_high_rate_mode = self->config->bs_high_rate_mode; self->pre_mix_req = 1; return 0; }