| /****************************************************************************** |
| * * |
| * 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 <string.h> |
| #include "ixheaacd_sbr_common.h" |
| #include <ixheaacd_type_def.h> |
| |
| #include "ixheaacd_constants.h" |
| #include <ixheaacd_basic_ops32.h> |
| #include <ixheaacd_basic_ops16.h> |
| #include <ixheaacd_basic_ops40.h> |
| #include "ixheaacd_basic_ops.h" |
| #include "ixheaacd_defines.h" |
| |
| #include "ixheaacd_intrinsics.h" |
| #include "ixheaacd_sbr_const.h" |
| #include <ixheaacd_basic_op.h> |
| #include "ixheaacd_defines.h" |
| #include "ixheaacd_bitbuffer.h" |
| #include "ixheaacd_pns.h" |
| |
| #include <ixheaacd_aac_rom.h> |
| #include "ixheaacd_pulsedata.h" |
| |
| #include "ixheaacd_drc_data_struct.h" |
| #include "ixheaacd_lt_predict.h" |
| #include "ixheaacd_channelinfo.h" |
| #include "ixheaacd_drc_dec.h" |
| |
| #include "ixheaacd_sbrdecoder.h" |
| |
| #include "ixheaacd_sbrdecsettings.h" |
| #include "ixheaacd_sbr_scale.h" |
| #include "ixheaacd_lpp_tran.h" |
| #include "ixheaacd_env_extr_part.h" |
| #include <ixheaacd_sbr_rom.h> |
| #include "ixheaacd_hybrid.h" |
| #include "ixheaacd_ps_dec.h" |
| #include "ixheaacd_ps_bitdec.h" |
| #include "ixheaacd_env_extr.h" |
| #include "ixheaacd_common_rom.h" |
| #include "ixheaacd_freq_sca.h" |
| |
| #include "ixheaacd_qmf_dec.h" |
| |
| #include "ixheaacd_env_calc.h" |
| |
| #include "ixheaacd_pvc_dec.h" |
| #include "ixheaacd_sbr_dec.h" |
| #include "ixheaacd_env_dec.h" |
| #include "ixheaacd_basic_funcs.h" |
| #include "ixheaacd_sbr_crc.h" |
| #include "ixheaacd_error_standards.h" |
| #include "ixheaacd_sbrqmftrans.h" |
| |
| #include "ixheaacd_audioobjtypes.h" |
| |
| #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3) |
| |
| WORD32 ixheaacd_getsize_sbr_persistent() { |
| return (ALIGN_SIZE64(sizeof(ia_sbr_pers_struct))); |
| } |
| |
| WORD32 ixheaacd_esbr_hbe_data_init( |
| ia_esbr_hbe_txposer_struct *pstr_esbr_hbe_txposer, |
| const WORD32 num_aac_samples, WORD32 samp_fac_4_flag, |
| const WORD32 num_out_samples, VOID *persistent_hbe_mem) { |
| WORD32 i; |
| WORD32 used_persistent = 0; |
| |
| if (pstr_esbr_hbe_txposer) { |
| memset(pstr_esbr_hbe_txposer, 0, sizeof(ia_esbr_hbe_txposer_struct)); |
| |
| pstr_esbr_hbe_txposer->core_frame_length = num_aac_samples; |
| |
| pstr_esbr_hbe_txposer->no_bins = num_out_samples / NO_QMF_SYNTH_CHANNELS; |
| |
| pstr_esbr_hbe_txposer->hbe_qmf_in_len = |
| pstr_esbr_hbe_txposer->no_bins / 2 + HBE_OPER_WIN_LEN - 1; |
| pstr_esbr_hbe_txposer->hbe_qmf_out_len = |
| 2 * pstr_esbr_hbe_txposer->hbe_qmf_in_len; |
| |
| pstr_esbr_hbe_txposer->ptr_input_buf = |
| (FLOAT32 *)((WORD8 *)persistent_hbe_mem); |
| used_persistent += |
| (num_aac_samples + NO_QMF_SYNTH_CHANNELS) * sizeof(FLOAT32); |
| |
| pstr_esbr_hbe_txposer->qmf_in_buf = |
| (FLOAT32 **)((WORD8 *)persistent_hbe_mem + used_persistent); |
| used_persistent += |
| pstr_esbr_hbe_txposer->hbe_qmf_in_len * sizeof(FLOAT32 *); |
| |
| for (i = 0; i < pstr_esbr_hbe_txposer->hbe_qmf_in_len; i++) { |
| pstr_esbr_hbe_txposer->qmf_in_buf[i] = |
| (FLOAT32 *)((WORD8 *)persistent_hbe_mem + used_persistent); |
| |
| used_persistent += (TWICE_QMF_SYNTH_CHANNELS_NUM * sizeof(FLOAT32)); |
| } |
| |
| pstr_esbr_hbe_txposer->qmf_out_buf = |
| (FLOAT32 **)((WORD8 *)persistent_hbe_mem + used_persistent); |
| used_persistent += |
| (pstr_esbr_hbe_txposer->hbe_qmf_out_len * sizeof(FLOAT32 *)); |
| |
| for (i = 0; i < pstr_esbr_hbe_txposer->hbe_qmf_out_len; i++) { |
| pstr_esbr_hbe_txposer->qmf_out_buf[i] = |
| (FLOAT32 *)((WORD8 *)persistent_hbe_mem + used_persistent); |
| used_persistent += (TWICE_QMF_SYNTH_CHANNELS_NUM * sizeof(FLOAT32)); |
| } |
| pstr_esbr_hbe_txposer->upsamp_4_flag = samp_fac_4_flag; |
| } |
| |
| return 0; |
| } |
| |
| VOID ixheaacd_set_sbr_persistent_table_pointer( |
| VOID *sbr_persistent_mem_v, ia_sbr_tables_struct *sbr_tables_ptr, |
| ixheaacd_misc_tables *pstr_common_tables) { |
| ia_sbr_pers_struct *sbr_persistent_mem = |
| (ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables = sbr_tables_ptr; |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_common_tables = pstr_common_tables; |
| } |
| |
| VOID ixheaacd_set_sbr_persistent_buffers(VOID *sbr_persistent_mem_v, |
| WORD32 *persistent_used, |
| WORD32 num_channel, WORD ps_enable) { |
| WORD32 i = 0; |
| WORD32 used_persistent = *persistent_used; |
| WORD32 temp, temp1, temp2, temp3; |
| struct ia_sbr_pers_struct *sbr_persistent_mem = |
| (struct ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| |
| struct ia_sbr_dec_inst_struct *p_str_sbr_dec_inst = |
| &sbr_persistent_mem->str_sbr_dec_inst; |
| |
| memset(sbr_persistent_mem, 0, sizeof(struct ia_sbr_pers_struct)); |
| |
| sbr_persistent_mem->sbr_qmf_analy_states = |
| (WORD16 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| temp = num_channel * ((QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) * |
| sizeof(WORD16)); |
| used_persistent += temp; |
| |
| sbr_persistent_mem->sbr_qmf_analy_states_32 = |
| (WORD32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| temp1 = |
| num_channel * |
| ((QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) * sizeof(WORD32)); |
| used_persistent += temp1; |
| |
| sbr_persistent_mem->sbr_qmf_synth_states = |
| (WORD16 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| |
| temp2 = |
| (num_channel * ((QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) * |
| sizeof(WORD16))); |
| used_persistent += temp2; |
| |
| sbr_persistent_mem->sbr_qmf_synth_states_32 = |
| (WORD32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| |
| temp3 = |
| (num_channel * ((QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) * |
| sizeof(WORD32))); |
| used_persistent += temp3; |
| |
| memset(sbr_persistent_mem->sbr_qmf_analy_states, 0, |
| (temp + temp1 + temp2 + temp3)); |
| |
| for (i = 0; i < num_channel; i++) { |
| sbr_persistent_mem->ptr_sbr_overlap_buf[i] = |
| (WORD32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| |
| if (ps_enable) { |
| memset(sbr_persistent_mem->ptr_sbr_overlap_buf[i], 0, |
| 2 * MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32)); |
| used_persistent += |
| 2 * MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32); |
| } else { |
| memset(sbr_persistent_mem->ptr_sbr_overlap_buf[i], 0, |
| MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32)); |
| used_persistent += MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32); |
| } |
| } |
| |
| for (i = 0; i < num_channel; i++) { |
| WORD32 j; |
| sbr_persistent_mem->sbr_lpc_filter_states_real[i] = |
| (WORD32 **)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| used_persistent += LPC_ORDER * sizeof(WORD32 *); |
| for (j = 0; j < LPC_ORDER; j++) { |
| sbr_persistent_mem->sbr_lpc_filter_states_real[i][j] = |
| (WORD32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| |
| used_persistent += NO_ANALYSIS_CHANNELS * sizeof(WORD32); |
| |
| memset(sbr_persistent_mem->sbr_lpc_filter_states_real[i][j], 0, |
| NO_ANALYSIS_CHANNELS * sizeof(WORD32)); |
| } |
| } |
| |
| if (ps_enable) { |
| for (i = 0; i < num_channel; i++) { |
| WORD32 j; |
| |
| sbr_persistent_mem->sbr_lpc_filter_states_imag[i] = |
| (WORD32 **)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| used_persistent += LPC_ORDER * sizeof(WORD32 *); |
| for (j = 0; j < LPC_ORDER; j++) { |
| sbr_persistent_mem->sbr_lpc_filter_states_imag[i][j] = |
| (WORD32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| |
| used_persistent += NO_ANALYSIS_CHANNELS * sizeof(WORD32); |
| |
| memset(sbr_persistent_mem->sbr_lpc_filter_states_imag[i][j], 0, |
| NO_ANALYSIS_CHANNELS * sizeof(WORD32)); |
| } |
| } |
| } |
| for (i = 0; i < num_channel; i++) { |
| WORD32 initial_used = used_persistent; |
| WORD32 temp_used = used_persistent; |
| |
| sbr_persistent_mem->sbr_smooth_gain_buf[i] = |
| (WORD16 *)((WORD8 *)sbr_persistent_mem_v + temp_used); |
| temp_used += 2 * MAX_FREQ_COEFFS * sizeof(WORD16); |
| |
| sbr_persistent_mem->sbr_smooth_noise_buf[i] = |
| (WORD16 *)((WORD8 *)sbr_persistent_mem_v + temp_used); |
| |
| temp_used += MAX_FREQ_COEFFS * sizeof(WORD16); |
| |
| p_str_sbr_dec_inst->pstr_freq_band_data[i] = |
| (VOID *)((WORD8 *)sbr_persistent_mem_v + temp_used); |
| |
| temp_used += ALIGN_SIZE64(sizeof(ia_freq_band_data_struct)); |
| |
| sbr_persistent_mem->pstr_prev_frame_data[i] = |
| (VOID *)((WORD8 *)sbr_persistent_mem_v + temp_used); |
| |
| temp_used += ALIGN_SIZE64(sizeof(ia_sbr_prev_frame_data_struct)); |
| |
| p_str_sbr_dec_inst->pstr_sbr_channel[i] = |
| (VOID *)((WORD8 *)sbr_persistent_mem_v + temp_used); |
| |
| temp_used += ALIGN_SIZE64(sizeof(ia_sbr_channel_struct)); |
| |
| p_str_sbr_dec_inst->pstr_sbr_header[i] = |
| (VOID *)((WORD8 *)sbr_persistent_mem_v + temp_used); |
| |
| temp_used += ALIGN_SIZE64(sizeof(ia_sbr_header_data_struct)); |
| |
| memset(sbr_persistent_mem->sbr_smooth_gain_buf[i], 0, |
| temp_used - initial_used); |
| |
| used_persistent = temp_used; |
| } |
| |
| if (ps_enable) { |
| p_str_sbr_dec_inst->pstr_ps_stereo_dec = |
| (ia_ps_dec_struct *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| |
| memset(p_str_sbr_dec_inst->pstr_ps_stereo_dec, 0, sizeof(ia_ps_dec_struct)); |
| |
| used_persistent += sizeof(ia_ps_dec_struct); |
| } |
| |
| p_str_sbr_dec_inst->frame_buffer[0] = |
| (VOID *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset(p_str_sbr_dec_inst->frame_buffer[0], 0, |
| (sizeof(ia_sbr_frame_info_data_struct) + |
| MAX_FREQ_COEFFS * sizeof(WORD32) * 2 + 8)); |
| used_persistent = used_persistent + (sizeof(ia_sbr_frame_info_data_struct) + |
| MAX_FREQ_COEFFS * sizeof(WORD32) + 8); |
| |
| p_str_sbr_dec_inst->frame_buffer[1] = |
| (VOID *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset(p_str_sbr_dec_inst->frame_buffer[1], 0, |
| (sizeof(ia_sbr_frame_info_data_struct) + |
| MAX_FREQ_COEFFS * sizeof(WORD32) * 2 + 8)); |
| used_persistent = used_persistent + (sizeof(ia_sbr_frame_info_data_struct) + |
| MAX_FREQ_COEFFS * sizeof(WORD32) + 8); |
| |
| { |
| WORD32 index = 0; |
| p_str_sbr_dec_inst->ptr_pvc_data_str = |
| (ia_pvc_data_struct *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset(p_str_sbr_dec_inst->ptr_pvc_data_str, 0, sizeof(ia_pvc_data_struct)); |
| used_persistent += sizeof(ia_pvc_data_struct); |
| |
| p_str_sbr_dec_inst->pstr_sbr_channel[0]->str_sbr_dec.p_hbe_txposer = |
| (ia_esbr_hbe_txposer_struct *)((WORD8 *)sbr_persistent_mem_v + |
| used_persistent); |
| memset(p_str_sbr_dec_inst->pstr_sbr_channel[0]->str_sbr_dec.p_hbe_txposer, |
| 0, sizeof(ia_esbr_hbe_txposer_struct)); |
| used_persistent += sizeof(ia_esbr_hbe_txposer_struct); |
| |
| if (num_channel == 2) { |
| p_str_sbr_dec_inst->pstr_sbr_channel[1]->str_sbr_dec.p_hbe_txposer = |
| (ia_esbr_hbe_txposer_struct *)((WORD8 *)sbr_persistent_mem_v + |
| used_persistent); |
| memset(p_str_sbr_dec_inst->pstr_sbr_channel[1]->str_sbr_dec.p_hbe_txposer, |
| 0, sizeof(ia_esbr_hbe_txposer_struct)); |
| used_persistent += sizeof(ia_esbr_hbe_txposer_struct); |
| } |
| |
| p_str_sbr_dec_inst->hbe_txposer_buffers = |
| (VOID *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset(p_str_sbr_dec_inst->hbe_txposer_buffers, 0, |
| num_channel * MAX_HBE_PERSISTENT_SIZE); |
| used_persistent += num_channel * MAX_HBE_PERSISTENT_SIZE; |
| |
| p_str_sbr_dec_inst->pstr_sbr_channel[0]->str_sbr_dec.pp_qmf_buf_real = |
| (FLOAT32 **)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset(p_str_sbr_dec_inst->pstr_sbr_channel[0]->str_sbr_dec.pp_qmf_buf_real, |
| 0, MAX_QMF_BUF_LEN * sizeof(FLOAT32 *)); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32 *); |
| |
| p_str_sbr_dec_inst->pstr_sbr_channel[0]->str_sbr_dec.pp_qmf_buf_imag = |
| (FLOAT32 **)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset(p_str_sbr_dec_inst->pstr_sbr_channel[0]->str_sbr_dec.pp_qmf_buf_imag, |
| 0, MAX_QMF_BUF_LEN); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32 *); |
| |
| if (num_channel == 2) { |
| p_str_sbr_dec_inst->pstr_sbr_channel[1]->str_sbr_dec.pp_qmf_buf_real = |
| (FLOAT32 **)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset( |
| p_str_sbr_dec_inst->pstr_sbr_channel[1]->str_sbr_dec.pp_qmf_buf_real, |
| 0, MAX_QMF_BUF_LEN * sizeof(FLOAT32 *)); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32 *); |
| |
| p_str_sbr_dec_inst->pstr_sbr_channel[1]->str_sbr_dec.pp_qmf_buf_imag = |
| (FLOAT32 **)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| memset( |
| p_str_sbr_dec_inst->pstr_sbr_channel[1]->str_sbr_dec.pp_qmf_buf_imag, |
| 0, MAX_QMF_BUF_LEN * sizeof(FLOAT32 *)); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32 *); |
| } |
| |
| for (index = 0; index < MAX_QMF_BUF_LEN; index++) { |
| p_str_sbr_dec_inst->pstr_sbr_channel[0] |
| ->str_sbr_dec.pp_qmf_buf_real[index] = |
| (FLOAT32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32); |
| } |
| |
| for (index = 0; index < MAX_QMF_BUF_LEN; index++) { |
| p_str_sbr_dec_inst->pstr_sbr_channel[0] |
| ->str_sbr_dec.pp_qmf_buf_imag[index] = |
| (FLOAT32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32); |
| } |
| |
| if (num_channel == 2) { |
| for (index = 0; index < MAX_QMF_BUF_LEN; index++) { |
| p_str_sbr_dec_inst->pstr_sbr_channel[1] |
| ->str_sbr_dec.pp_qmf_buf_real[index] = |
| (FLOAT32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32); |
| } |
| |
| for (index = 0; index < MAX_QMF_BUF_LEN; index++) { |
| p_str_sbr_dec_inst->pstr_sbr_channel[1] |
| ->str_sbr_dec.pp_qmf_buf_imag[index] = |
| (FLOAT32 *)((WORD8 *)sbr_persistent_mem_v + used_persistent); |
| used_persistent += MAX_QMF_BUF_LEN * sizeof(FLOAT32); |
| } |
| } |
| } |
| |
| *persistent_used = used_persistent; |
| } |
| |
| WORD32 ia_enhaacplus_dec_get_sbr_buffers_size(WORD32 channels) { |
| WORD32 sbr_buffers_size = 0; |
| WORD32 temp, temp2; |
| WORD32 num_channel = channels; |
| WORD32 i; |
| |
| temp = num_channel * ((QMF_FILTER_STATE_ANA_SIZE + 2 * NO_ANALYSIS_CHANNELS) * |
| sizeof(WORD16)); |
| sbr_buffers_size += temp; |
| |
| temp2 = |
| (num_channel * ((QMF_FILTER_STATE_SYN_SIZE + 2 * NO_SYNTHESIS_CHANNELS) * |
| sizeof(WORD16))); |
| sbr_buffers_size += temp2; |
| |
| for (i = 0; i < num_channel; i++) { |
| sbr_buffers_size += |
| 2 * MAX_OV_COLS * NO_SYNTHESIS_CHANNELS * sizeof(WORD32); |
| } |
| |
| for (i = 0; i < num_channel; i++) { |
| int j; |
| sbr_buffers_size += LPC_ORDER * sizeof(VOID *); |
| |
| for (j = 0; j < LPC_ORDER; j++) { |
| sbr_buffers_size += NO_ANALYSIS_CHANNELS * sizeof(WORD32); |
| } |
| } |
| |
| for (i = 0; i < num_channel; i++) { |
| int j; |
| sbr_buffers_size += LPC_ORDER * sizeof(WORD32); |
| for (j = 0; j < LPC_ORDER; j++) { |
| sbr_buffers_size += NO_ANALYSIS_CHANNELS * sizeof(WORD32); |
| } |
| } |
| |
| for (i = 0; i < num_channel; i++) { |
| WORD32 temp_used = sbr_buffers_size; |
| |
| temp_used += 2 * MAX_FREQ_COEFFS * sizeof(WORD16); |
| temp_used += MAX_FREQ_COEFFS * sizeof(WORD16); |
| temp_used += ALIGN_SIZE64(sizeof(ia_freq_band_data_struct)); |
| temp_used += ALIGN_SIZE64(sizeof(ia_sbr_prev_frame_data_struct)); |
| temp_used += ALIGN_SIZE64(sizeof(ia_sbr_channel_struct)); |
| temp_used += ALIGN_SIZE64(sizeof(ia_sbr_header_data_struct)); |
| |
| sbr_buffers_size = temp_used; |
| } |
| |
| sbr_buffers_size += sizeof(ia_ps_dec_struct); |
| |
| return sbr_buffers_size; |
| } |
| |
| static PLATFORM_INLINE VOID ixheaacd_init_headerdata( |
| ia_sbr_header_data_struct *ptr_header_data, WORD32 sample_rate_dec, |
| WORD32 samp_per_frame, ia_freq_band_data_struct *freq_band_data, |
| ia_sbr_tables_struct *sbr_tables, WORD audio_obj_type) { |
| ia_freq_band_data_struct *pstr_freq_band_data = freq_band_data; |
| WORD32 tmp; |
| |
| if (audio_obj_type != AOT_ER_AAC_ELD) { |
| memcpy(ptr_header_data, |
| &sbr_tables->env_extr_tables_ptr->str_sbr_default_header, |
| sizeof(ia_sbr_header_data_struct)); |
| } |
| |
| if (audio_obj_type == AOT_ER_AAC_ELD) ptr_header_data->time_step -= 1; |
| |
| pstr_freq_band_data->freq_band_table[LOW] = |
| pstr_freq_band_data->freq_band_tbl_lo; |
| pstr_freq_band_data->freq_band_table[HIGH] = |
| pstr_freq_band_data->freq_band_tbl_hi; |
| ptr_header_data->pstr_freq_band_data = pstr_freq_band_data; |
| |
| ptr_header_data->core_frame_size = samp_per_frame; |
| ptr_header_data->out_sampling_freq = sample_rate_dec << 1; |
| |
| if (audio_obj_type != AOT_ER_AAC_ELD) { |
| tmp = ptr_header_data->time_step + 4; |
| |
| if (tmp < 0) |
| ptr_header_data->num_time_slots = |
| ixheaacd_extract16l(samp_per_frame << (-tmp)); |
| else |
| ptr_header_data->num_time_slots = |
| ixheaacd_extract16l(samp_per_frame >> tmp); |
| } else { |
| ptr_header_data->time_step = 1; |
| |
| ptr_header_data->num_time_slots = |
| (samp_per_frame / 32 >> (ptr_header_data->time_step - 1)); |
| } |
| } |
| |
| VOID ixheaacd_setesbr_flags(VOID *sbr_persistent_mem_v, FLAG pvc_flag, |
| FLAG hbe_flag, FLAG inter_tes_flag) { |
| ia_sbr_pers_struct *sbr_persistent_mem; |
| sbr_persistent_mem = (ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| sbr_persistent_mem->str_sbr_dec_inst.hbe_flag = hbe_flag; |
| sbr_persistent_mem->str_sbr_dec_inst.pvc_flag = pvc_flag; |
| sbr_persistent_mem->str_sbr_dec_inst.inter_tes_flag = inter_tes_flag; |
| return; |
| } |
| |
| ia_handle_sbr_dec_inst_struct ixheaacd_init_sbr( |
| WORD32 sample_rate_dec, WORD32 samp_per_frame, FLAG *down_sample_flag, |
| VOID *sbr_persistent_mem_v, WORD32 *ptr_overlap_buf, WORD32 channel, |
| WORD32 ps_enable, WORD32 sbr_ratio_idx, WORD32 output_frame_size, |
| WORD32 *use_hbe, VOID *p_usac_dflt_header, |
| ia_sbr_header_data_struct str_sbr_config, WORD32 audio_object_type) { |
| WORD16 i; |
| WORD16 err; |
| ia_sbr_header_data_struct *ptr_header_data[MAXNRSBRCHANNELS]; |
| ia_sbr_dec_struct *ptr_sbr_dec[2]; |
| ia_qmf_dec_tables_struct *qmf_dec_tables_ptr; |
| ia_sbr_pers_struct *sbr_persistent_mem; |
| |
| sbr_persistent_mem = (ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| ptr_sbr_dec[0] = |
| &sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_channel[0]->str_sbr_dec; |
| ptr_sbr_dec[1] = |
| &sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_channel[1]->str_sbr_dec; |
| |
| qmf_dec_tables_ptr = |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables->qmf_dec_tables_ptr; |
| |
| if (sample_rate_dec > 48000) { |
| *down_sample_flag = 1; |
| } |
| |
| for (i = 0; i < channel; i++) { |
| if (audio_object_type == AOT_ER_AAC_ELD) { |
| memcpy(sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[i], |
| &str_sbr_config, sizeof(ia_sbr_header_data_struct)); |
| } |
| ptr_header_data[i] = |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_header[i]; |
| |
| ixheaacd_init_headerdata( |
| ptr_header_data[i], sample_rate_dec, samp_per_frame, |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_freq_band_data[i], |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables, |
| audio_object_type); |
| |
| err = ixheaacd_create_sbrdec( |
| |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_common_tables, |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_channel[i], |
| ptr_header_data[i], i, *down_sample_flag, sbr_persistent_mem, ps_enable, |
| audio_object_type); |
| |
| ptr_header_data[i]->status = 1; |
| |
| if (err) { |
| return NULL; |
| } |
| } |
| |
| if (channel != 1) { |
| if (ps_enable) { |
| if (audio_object_type == AOT_ER_AAC_ELD) |
| err = (WORD16)ixheaacd_create_psdec( |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_ps_stereo_dec, |
| sbr_persistent_mem, &ptr_overlap_buf[512 * 4]); |
| else |
| err = (WORD16)ixheaacd_create_psdec( |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_ps_stereo_dec, |
| sbr_persistent_mem, ptr_overlap_buf); |
| if (err) { |
| return NULL; |
| } |
| } |
| } |
| |
| if (use_hbe != NULL) { |
| ia_sbr_header_data_struct *ptr_sbr_dflt_header = |
| &sbr_persistent_mem->str_sbr_dec_inst.str_sbr_dflt_header; |
| ia_sbr_header_data_struct *ptr_usac_dflt_header = |
| (ia_sbr_header_data_struct *)p_usac_dflt_header; |
| struct ia_sbr_dec_inst_struct *p_str_sbr_dec_inst = |
| &sbr_persistent_mem->str_sbr_dec_inst; |
| VOID *hbe_txposer_buffers = p_str_sbr_dec_inst->hbe_txposer_buffers; |
| |
| ptr_header_data[0] = p_str_sbr_dec_inst->pstr_sbr_header[0]; |
| ptr_header_data[1] = p_str_sbr_dec_inst->pstr_sbr_header[1]; |
| |
| ptr_header_data[0]->sbr_ratio_idx = sbr_ratio_idx; |
| ptr_header_data[0]->output_framesize = output_frame_size; |
| ptr_header_data[0]->pstr_freq_band_data->sub_band_start = 64; |
| ptr_header_data[0]->esbr_start_up = 1; |
| ptr_header_data[0]->esbr_start_up_pvc = 1; |
| |
| if (channel > 1) { |
| ptr_header_data[1]->sbr_ratio_idx = sbr_ratio_idx; |
| ptr_header_data[1]->output_framesize = output_frame_size; |
| ptr_header_data[1]->pstr_freq_band_data->sub_band_start = 64; |
| ptr_header_data[1]->esbr_start_up = 1; |
| ptr_header_data[1]->esbr_start_up_pvc = 1; |
| } |
| if (hbe_txposer_buffers != NULL && (use_hbe[0] == 1)) { |
| ixheaacd_esbr_hbe_data_init(ptr_sbr_dec[0]->p_hbe_txposer, samp_per_frame, |
| sbr_ratio_idx == SBR_UPSAMPLE_IDX_4_1 ? 1 : 0, |
| output_frame_size, hbe_txposer_buffers); |
| |
| hbe_txposer_buffers = |
| (WORD8 *)hbe_txposer_buffers + MAX_HBE_PERSISTENT_SIZE; |
| |
| ixheaacd_esbr_hbe_data_init(ptr_sbr_dec[1]->p_hbe_txposer, samp_per_frame, |
| sbr_ratio_idx == SBR_UPSAMPLE_IDX_4_1 ? 1 : 0, |
| output_frame_size, hbe_txposer_buffers); |
| } |
| |
| p_str_sbr_dec_inst->ptr_pvc_data_str->prev_first_bnd_idx = -1; |
| p_str_sbr_dec_inst->ptr_pvc_data_str->prev_pvc_rate = -1; |
| p_str_sbr_dec_inst->ptr_pvc_data_str->prev_sbr_mode = UNKNOWN_SBR; |
| |
| p_str_sbr_dec_inst->pstr_sbr_channel[0] |
| ->str_sbr_dec.str_codec_qmf_bank.num_time_slots = |
| output_frame_size / 64; |
| p_str_sbr_dec_inst->pstr_sbr_channel[1] |
| ->str_sbr_dec.str_codec_qmf_bank.num_time_slots = |
| output_frame_size / 64; |
| |
| ptr_header_data[0]->core_frame_size = samp_per_frame; |
| ptr_header_data[1]->core_frame_size = samp_per_frame; |
| |
| switch (sbr_ratio_idx) { |
| case SBR_UPSAMPLE_IDX_0_0: |
| ptr_sbr_dec[0]->str_codec_qmf_bank.no_channels = 32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l32; |
| ptr_header_data[0]->is_usf_4 = 0; |
| ptr_header_data[0]->upsamp_fac = 1; |
| |
| ptr_sbr_dec[1]->str_codec_qmf_bank.no_channels = 32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l32; |
| ptr_header_data[1]->is_usf_4 = 0; |
| ptr_header_data[1]->upsamp_fac = 1; |
| break; |
| case SBR_UPSAMPLE_IDX_2_1: |
| ptr_sbr_dec[0]->str_codec_qmf_bank.no_channels = 32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l32; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l32; |
| ptr_header_data[0]->is_usf_4 = 0; |
| ptr_header_data[0]->upsamp_fac = 2; |
| |
| ptr_sbr_dec[1]->str_codec_qmf_bank.no_channels = 32; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l32; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l32; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l32; |
| ptr_header_data[1]->is_usf_4 = 0; |
| ptr_header_data[1]->upsamp_fac = 2; |
| break; |
| case SBR_UPSAMPLE_IDX_8_3: |
| ptr_sbr_dec[0]->str_codec_qmf_bank.no_channels = 24; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.filter_pos_32 = |
| qmf_dec_tables_ptr->esbr_qmf_c_24; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.analy_win_coeff_32 = |
| qmf_dec_tables_ptr->esbr_qmf_c_24; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l24; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l24; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l24; |
| |
| ptr_header_data[0]->is_usf_4 = 0; |
| ptr_header_data[0]->upsamp_fac = 2; |
| |
| ptr_sbr_dec[1]->str_codec_qmf_bank.no_channels = 24; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.filter_pos_32 = |
| qmf_dec_tables_ptr->esbr_qmf_c_24; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.analy_win_coeff_32 = |
| qmf_dec_tables_ptr->esbr_qmf_c_24; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l24; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l24; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l24; |
| |
| ptr_header_data[1]->is_usf_4 = 0; |
| ptr_header_data[1]->upsamp_fac = 2; |
| break; |
| case SBR_UPSAMPLE_IDX_4_1: |
| ptr_sbr_dec[0]->str_codec_qmf_bank.no_channels = 16; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l16; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l16; |
| ptr_sbr_dec[0]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l16; |
| ptr_header_data[0]->is_usf_4 = 1; |
| ptr_header_data[0]->upsamp_fac = 4; |
| ptr_header_data[0]->out_sampling_freq = |
| ptr_header_data[0]->out_sampling_freq * 2; |
| |
| ptr_sbr_dec[1]->str_codec_qmf_bank.no_channels = 16; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_cos_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_sin_cos_twiddle_l16; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_alt_sin_twiddle = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_alt_sin_twiddle_l16; |
| ptr_sbr_dec[1]->str_codec_qmf_bank.esbr_t_cos = |
| (WORD32 *)qmf_dec_tables_ptr->esbr_t_cos_sin_l16; |
| ptr_header_data[1]->is_usf_4 = 1; |
| ptr_header_data[1]->upsamp_fac = 4; |
| ptr_header_data[1]->out_sampling_freq = |
| ptr_header_data[1]->out_sampling_freq * 2; |
| break; |
| } |
| |
| ptr_sbr_dflt_header->start_freq = ptr_usac_dflt_header->start_freq; |
| ptr_sbr_dflt_header->stop_freq = ptr_usac_dflt_header->stop_freq; |
| |
| if (ptr_usac_dflt_header->header_extra_1) { |
| ptr_sbr_dflt_header->freq_scale = ptr_usac_dflt_header->freq_scale; |
| ptr_sbr_dflt_header->alter_scale = ptr_usac_dflt_header->alter_scale; |
| ptr_sbr_dflt_header->noise_bands = ptr_usac_dflt_header->noise_bands; |
| } else { |
| ptr_sbr_dflt_header->freq_scale = SBR_FREQ_SCALE_DEFAULT; |
| ptr_sbr_dflt_header->alter_scale = SBR_ALTER_SCALE_DEFAULT; |
| ptr_sbr_dflt_header->noise_bands = SBR_NOISE_BANDS_DEFAULT; |
| } |
| |
| if (ptr_usac_dflt_header->header_extra_2) { |
| ptr_sbr_dflt_header->limiter_bands = ptr_usac_dflt_header->limiter_bands; |
| ptr_sbr_dflt_header->limiter_gains = ptr_usac_dflt_header->limiter_gains; |
| ptr_sbr_dflt_header->interpol_freq = ptr_usac_dflt_header->interpol_freq; |
| ptr_sbr_dflt_header->smoothing_mode = |
| ptr_usac_dflt_header->smoothing_mode; |
| } else { |
| ptr_sbr_dflt_header->limiter_bands = SBR_LIMITER_BANDS_DEFAULT; |
| ptr_sbr_dflt_header->limiter_gains = SBR_LIMITER_GAINS_DEFAULT; |
| ptr_sbr_dflt_header->interpol_freq = SBR_INTERPOL_FREQ_DEFAULT; |
| ptr_sbr_dflt_header->smoothing_mode = SBR_SMOOTHING_LENGTH_DEFAULT; |
| } |
| } |
| return &(sbr_persistent_mem->str_sbr_dec_inst); |
| } |
| |
| static PLATFORM_INLINE WORD16 ixheaacd_create_sbr_env_calc( |
| |
| ixheaacd_misc_tables *pstr_common_table, ia_sbr_calc_env_struct *hs, |
| WORD16 chan, VOID *sbr_persistent_mem_v, |
| ia_sbr_header_data_struct *ptr_header_data, WORD audio_object_type) { |
| WORD16 err; |
| ia_sbr_pers_struct *sbr_persistent_mem = |
| (ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| |
| err = 0; |
| memset(&hs->harm_flags_prev[0], 0, sizeof(WORD8) * MAX_FREQ_COEFFS); |
| |
| hs->harm_index = 0; |
| |
| hs->filt_buf_me = sbr_persistent_mem->sbr_smooth_gain_buf[chan]; |
| hs->filt_buf_noise_m = sbr_persistent_mem->sbr_smooth_noise_buf[chan]; |
| hs->tansient_env_prev = -1; |
| |
| ixheaacd_reset_sbrenvelope_calc(hs); |
| |
| if ((chan == 0) && (audio_object_type == AOT_ER_AAC_ELD)) { |
| err = ixheaacd_calc_frq_bnd_tbls(ptr_header_data, pstr_common_table); |
| } |
| |
| return err; |
| } |
| |
| static PLATFORM_INLINE VOID ixheaacd_init_sbr_prev_framedata( |
| ia_sbr_prev_frame_data_struct *ptr_prev_data, WORD16 time_slots) { |
| WORD16 *psfb_nrg_prev = ptr_prev_data->sfb_nrg_prev; |
| WORD16 *psfb_noise_level = ptr_prev_data->prev_noise_level; |
| WORD32 *ppsbr_invf_mode = ptr_prev_data->sbr_invf_mode; |
| |
| memset(psfb_nrg_prev, 0, sizeof(WORD16) * (MAX_FREQ_COEFFS)); |
| memset(psfb_noise_level, 0, sizeof(WORD16) * (MAX_NOISE_COEFFS)); |
| |
| memset(ppsbr_invf_mode, 0, sizeof(WORD32) * MAX_INVF_BANDS); |
| |
| ptr_prev_data->end_position = time_slots; |
| ptr_prev_data->coupling_mode = COUPLING_OFF; |
| ptr_prev_data->amp_res = 0; |
| ptr_prev_data->max_qmf_subband_aac = 0; |
| } |
| |
| static PLATFORM_INLINE WORD32 |
| ixheaacd_create_hyb_filterbank(ia_hybrid_struct *ptr_hybrid, WORD32 **p_ptr, |
| ia_sbr_tables_struct *sbr_tables_ptr) { |
| WORD16 i, ptr_step; |
| WORD32 *ptr = (WORD32 *)*p_ptr; |
| |
| ptr_hybrid->ptr_resol = sbr_tables_ptr->ps_tables_ptr->hyb_resol; |
| ptr_hybrid->ptr_qmf_buf = HYBRID_FILTER_LENGTH - 1; |
| |
| ptr_hybrid->ptr_temp_re = ptr; |
| ptr += NO_HYBRID_CHANNELS_HIGH; |
| ptr_hybrid->ptr_temp_im = ptr; |
| ptr += NO_HYBRID_CHANNELS_HIGH; |
| |
| memset(ptr_hybrid->ptr_temp_re, 0, |
| 2 * NO_HYBRID_CHANNELS_HIGH * sizeof(WORD32)); |
| |
| ptr_step = ixheaacd_add16(1, ptr_hybrid->ptr_qmf_buf); |
| ptr_hybrid->ptr_work_re = ptr; |
| ptr += 16; |
| ptr_hybrid->ptr_work_im = ptr; |
| ptr += 16; |
| |
| for (i = 0; i < NO_QMF_CHANNELS_IN_HYBRID; i++) { |
| ptr_hybrid->ptr_qmf_buf_re[i] = ptr; |
| ptr += ptr_hybrid->ptr_qmf_buf; |
| |
| ptr_hybrid->ptr_qmf_buf_im[i] = ptr; |
| ptr += ptr_hybrid->ptr_qmf_buf; |
| |
| memset(ptr_hybrid->ptr_qmf_buf_re[i], 0, |
| 2 * ptr_hybrid->ptr_qmf_buf * sizeof(WORD32)); |
| } |
| |
| *p_ptr = ptr; |
| |
| return 0; |
| } |
| |
| static PLATFORM_INLINE WORD16 ixheaacd_create_hf_generator( |
| ia_sbr_hf_generator_struct *ptr_hf_gen_str, WORD16 num_columns, WORD16 chan, |
| VOID *sbr_persistent_mem_v, WORD32 ps_enable) { |
| WORD16 i; |
| ia_sbr_pers_struct *sbr_persistent_mem = |
| (ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| |
| ptr_hf_gen_str->pstr_settings = &sbr_persistent_mem->str_sbr_tran_settings; |
| |
| ptr_hf_gen_str->lpc_filt_states_real[0] = |
| sbr_persistent_mem->sbr_lpc_filter_states_real[chan][0]; |
| ptr_hf_gen_str->lpc_filt_states_real[1] = |
| sbr_persistent_mem->sbr_lpc_filter_states_real[chan][1]; |
| |
| if (ps_enable) { |
| ptr_hf_gen_str->lpc_filt_states_imag[0] = |
| sbr_persistent_mem->sbr_lpc_filter_states_imag[chan][0]; |
| ptr_hf_gen_str->lpc_filt_states_imag[1] = |
| sbr_persistent_mem->sbr_lpc_filter_states_imag[chan][1]; |
| } |
| |
| for (i = 0; i < LPC_ORDER; i++) { |
| memset(ptr_hf_gen_str->lpc_filt_states_real[i], 0, |
| NO_ANALYSIS_CHANNELS * sizeof(WORD32)); |
| |
| if (ps_enable) |
| memset(ptr_hf_gen_str->lpc_filt_states_imag[i], 0, |
| NO_ANALYSIS_CHANNELS * sizeof(WORD32)); |
| } |
| |
| if (chan == 0) { |
| ptr_hf_gen_str->pstr_settings->num_columns = num_columns; |
| } |
| return 0; |
| } |
| |
| WORD32 ixheaacd_create_psdec(ia_ps_dec_struct *ptr_ps_dec, |
| VOID *sbr_persistent_mem_v, |
| WORD32 *ptr_overlap_buf) { |
| ia_sbr_pers_struct *sbr_persistent_mem = |
| (ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| |
| WORD16 *ptr1 = (WORD16 *)&( |
| sbr_persistent_mem->ptr_sbr_overlap_buf[MAXNRSBRCHANNELS - 1][0]); |
| WORD32 *ptr2 = (WORD32 *)&ptr_overlap_buf[512]; |
| WORD16 *initial_ptr; |
| WORD16 delay; |
| WORD32 temp; |
| |
| ia_sbr_tables_struct *sbr_tables_ptr = |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables; |
| |
| memset(ptr_ps_dec, 0, sizeof(ia_ps_dec_struct)); |
| |
| ptr_ps_dec->ps_data_present = 0; |
| ptr_ps_dec->enable_iid = 0; |
| ptr_ps_dec->enable_icc = 0; |
| ptr_ps_dec->enable_ext = 0; |
| ptr_ps_dec->iid_mode = 0; |
| ptr_ps_dec->icc_mode = 0; |
| |
| ptr_ps_dec->ptr_hyb_left_re = ptr2; |
| ptr2 += 16; |
| ptr_ps_dec->ptr_hyb_left_im = ptr2; |
| ptr2 += 16; |
| ptr_ps_dec->ptr_hyb_right_re = ptr2; |
| ptr2 += 16; |
| ptr_ps_dec->ptr_hyb_right_im = ptr2; |
| ptr2 += 16; |
| |
| memset(ptr_ps_dec->ptr_hyb_left_re, 0, sizeof(WORD32) * 16 * 4); |
| |
| ixheaacd_create_hyb_filterbank(&ptr_ps_dec->str_hybrid, &ptr2, |
| sbr_tables_ptr); |
| |
| ptr_ps_dec->peak_decay_diff = ptr2; |
| ptr2 += NUM_OF_BINS; |
| ptr_ps_dec->energy_prev = ptr2; |
| ptr2 += NUM_OF_BINS; |
| ptr_ps_dec->peak_decay_diff_prev = ptr2; |
| ptr2 += NUM_OF_BINS; |
| |
| memset(ptr_ps_dec->peak_decay_diff, 0, 3 * sizeof(WORD32) * NUM_OF_BINS); |
| |
| ptr_ps_dec->delay_buf_idx = 0; |
| ptr_ps_dec->delay_buf_idx_long = 0; |
| |
| memset(ptr_ps_dec->delay_buf_qmf_sub_re_im, 0, |
| 2 * 16 * DEL_ALL_PASS * sizeof(WORD16)); |
| memset(ptr_ps_dec->delay_buf_qmf_sub_ser_re_im, 0, |
| 2 * 16 * NUM_SER_AP_LINKS * 5 * sizeof(WORD16)); |
| |
| initial_ptr = ptr1; |
| ptr_ps_dec->delay_buf_qmf_ser_re_im = (VOID *)ptr1; |
| ptr1 += 2 * NUM_SER_AP_LINKS * 32 * 5; |
| |
| delay = 2; |
| ptr_ps_dec->delay_buf_qmf_ap_re_im = (VOID *)ptr1; |
| ptr1 += 2 * delay * 32; |
| |
| delay = HIGH_DEL; |
| ptr_ps_dec->delay_buf_qmf_ld_re_im = (VOID *)ptr1; |
| ptr1 += 2 * delay * SMALL_DEL_STRT; |
| |
| delay = SMALL_DEL; |
| ptr_ps_dec->delay_buf_qmf_sd_re_im = (VOID *)ptr1; |
| ptr1 += |
| 2 * delay * (NUM_OF_QUAD_MIRROR_FILTER_ICC_CHNLS - |
| (NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS + SMALL_DEL_STRT)); |
| |
| temp = ptr1 - initial_ptr; |
| memset(ptr_ps_dec->delay_buf_qmf_ser_re_im, 0, temp * sizeof(WORD16)); |
| |
| memset(ptr_ps_dec->delay_buf_idx_ser, 0, NUM_SER_AP_LINKS * sizeof(WORD16)); |
| memcpy(ptr_ps_dec->delay_sample_ser, |
| sbr_tables_ptr->ps_tables_ptr->rev_link_delay_ser, |
| NUM_SER_AP_LINKS * sizeof(WORD16)); |
| |
| memset(ptr_ps_dec->h11_h12_vec, 0xff, |
| (NO_IID_GROUPS + 2) * 2 * sizeof(WORD16)); |
| memset(ptr_ps_dec->h21_h22_vec, 0, sizeof(ptr_ps_dec->h21_h22_vec)); |
| |
| return 0; |
| } |
| |
| static PLATFORM_INLINE WORD32 ixheaacd_create_cplx_anal_qmfbank( |
| ia_sbr_qmf_filter_bank_struct *ptr_sbr_qmf, |
| ia_sbr_scale_fact_struct *sbr_scale_factor, WORD16 no_bins, WORD16 usb, |
| WORD16 chan, WORD16 *sbr_qmf_analy_states, WORD32 *sbr_qmf_analy_states_32, |
| ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, WORD32 audio_object_type) { |
| memset(ptr_sbr_qmf, 0, sizeof(ia_sbr_qmf_filter_bank_struct)); |
| |
| if (audio_object_type != AOT_ER_AAC_ELD && |
| audio_object_type != AOT_ER_AAC_LD) { |
| ptr_sbr_qmf->analy_win_coeff = qmf_dec_tables_ptr->qmf_c; |
| } else { |
| ptr_sbr_qmf->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3; |
| } |
| |
| ptr_sbr_qmf->analy_win_coeff_32 = qmf_dec_tables_ptr->esbr_qmf_c; |
| |
| ptr_sbr_qmf->no_channels = NO_ANALYSIS_CHANNELS; |
| ptr_sbr_qmf->num_time_slots = no_bins; |
| |
| ptr_sbr_qmf->lsb = 0; |
| ptr_sbr_qmf->usb = usb; |
| |
| ptr_sbr_qmf->anal_filter_states = |
| &(sbr_qmf_analy_states[chan ? QMF_FILTER_STATE_ANA_SIZE : 0]); |
| |
| memset(ptr_sbr_qmf->anal_filter_states, 0, |
| sizeof(WORD16) * QMF_FILTER_STATE_ANA_SIZE); |
| |
| ptr_sbr_qmf->anal_filter_states_32 = |
| &(sbr_qmf_analy_states_32[chan ? QMF_FILTER_STATE_ANA_SIZE : 0]); |
| |
| memset(ptr_sbr_qmf->anal_filter_states_32, 0, |
| sizeof(WORD32) * QMF_FILTER_STATE_ANA_SIZE); |
| |
| ptr_sbr_qmf->core_samples_buffer = ptr_sbr_qmf->anal_filter_states; |
| |
| ptr_sbr_qmf->state_new_samples_pos_low_32 = |
| ptr_sbr_qmf->anal_filter_states_32; |
| if (audio_object_type != AOT_ER_AAC_ELD && |
| audio_object_type != AOT_ER_AAC_LD) { |
| ptr_sbr_qmf->filter_pos = (WORD16 *)qmf_dec_tables_ptr->qmf_c; |
| } else { |
| ptr_sbr_qmf->filter_pos = (WORD16 *)qmf_dec_tables_ptr->qmf_c_eld3; |
| } |
| |
| ptr_sbr_qmf->filter_pos_32 = (WORD32 *)qmf_dec_tables_ptr->esbr_qmf_c; |
| |
| sbr_scale_factor->st_lb_scale = 0; |
| |
| sbr_scale_factor->st_syn_scale = -6; |
| |
| if (audio_object_type == AOT_ER_AAC_ELD || |
| audio_object_type == AOT_ER_AAC_LD) { |
| ptr_sbr_qmf->filter_2 = ptr_sbr_qmf->filter_pos + 32; |
| ptr_sbr_qmf->fp1_anal = ptr_sbr_qmf->anal_filter_states; |
| ptr_sbr_qmf->fp2_anal = |
| ptr_sbr_qmf->anal_filter_states + NO_ANALYSIS_CHANNELS; |
| } |
| |
| return 0; |
| } |
| |
| static PLATFORM_INLINE WORD32 ixheaacd_create_cplx_synt_qmfbank( |
| ia_sbr_qmf_filter_bank_struct *ptr_sbr_qmf, WORD16 no_bins, WORD16 lsb, |
| WORD16 usb, WORD16 chan, FLAG down_sample_flag, |
| WORD16 *sbr_qmf_synth_states, WORD32 *sbr_qmf_synth_states_32, |
| ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, WORD32 audio_object_type) { |
| WORD32 L; |
| |
| WORD32 qmf_filter_state_size; |
| |
| memset(ptr_sbr_qmf, 0, sizeof(ia_sbr_qmf_filter_bank_struct)); |
| |
| if (down_sample_flag) { |
| L = NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED; |
| qmf_filter_state_size = QMF_FILTER_STATE_SYN_SIZE_DOWN_SAMPLED; |
| ptr_sbr_qmf->usb = NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED; |
| } else { |
| L = NO_SYNTHESIS_CHANNELS; |
| qmf_filter_state_size = QMF_FILTER_STATE_SYN_SIZE; |
| ptr_sbr_qmf->usb = usb; |
| } |
| |
| ptr_sbr_qmf->ixheaacd_drc_offset = 0; |
| if (audio_object_type != AOT_ER_AAC_ELD && |
| audio_object_type != AOT_ER_AAC_LD) { |
| ptr_sbr_qmf->filter_pos_syn = (WORD16 *)qmf_dec_tables_ptr->qmf_c; |
| ptr_sbr_qmf->p_filter = qmf_dec_tables_ptr->qmf_c; |
| } else { |
| ptr_sbr_qmf->filter_pos_syn = (WORD16 *)qmf_dec_tables_ptr->qmf_c_eld; |
| ptr_sbr_qmf->p_filter = qmf_dec_tables_ptr->qmf_c_eld; |
| } |
| |
| ptr_sbr_qmf->filter_pos_syn_32 = (WORD32 *)qmf_dec_tables_ptr->esbr_qmf_c; |
| ptr_sbr_qmf->p_filter_32 = qmf_dec_tables_ptr->esbr_qmf_c; |
| |
| ptr_sbr_qmf->no_channels = L; |
| ptr_sbr_qmf->qmf_filter_state_size = qmf_filter_state_size; |
| ptr_sbr_qmf->num_time_slots = no_bins; |
| ptr_sbr_qmf->lsb = lsb; |
| |
| ptr_sbr_qmf->filter_states = |
| &sbr_qmf_synth_states[chan ? qmf_filter_state_size : 0]; |
| |
| memset(ptr_sbr_qmf->filter_states, 0, sizeof(WORD16) * qmf_filter_state_size); |
| |
| ptr_sbr_qmf->filter_states_32 = |
| &sbr_qmf_synth_states_32[chan ? qmf_filter_state_size : 0]; |
| |
| memset(ptr_sbr_qmf->filter_states_32, 0, |
| sizeof(WORD32) * qmf_filter_state_size); |
| |
| if (audio_object_type == AOT_ER_AAC_ELD || |
| audio_object_type == AOT_ER_AAC_LD) { |
| ptr_sbr_qmf->fp1_syn = ptr_sbr_qmf->filter_states; |
| ptr_sbr_qmf->fp2_syn = |
| ptr_sbr_qmf->filter_states + ptr_sbr_qmf->no_channels; |
| ptr_sbr_qmf->sixty4 = NO_SYNTHESIS_CHANNELS; |
| } |
| |
| return 0; |
| } |
| |
| WORD16 ixheaacd_create_sbrdec(ixheaacd_misc_tables *pstr_common_table, |
| ia_sbr_channel_struct *ptr_sbr_channel, |
| ia_sbr_header_data_struct *ptr_header_data, |
| WORD16 chan, FLAG down_sample_flag, |
| VOID *sbr_persistent_mem_v, WORD ps_enable, |
| WORD audio_object_type) |
| |
| { |
| WORD16 err; |
| WORD16 time_slots; |
| WORD16 no_bins; |
| ia_sbr_pers_struct *sbr_persistent_mem = |
| (ia_sbr_pers_struct *)sbr_persistent_mem_v; |
| ia_sbr_dec_struct *hs = &(ptr_sbr_channel->str_sbr_dec); |
| |
| time_slots = ptr_header_data->num_time_slots; |
| |
| no_bins = (WORD16)(time_slots * ptr_header_data->time_step); |
| |
| hs->str_sbr_scale_fact.ov_lb_scale = INT_BITS - 1; |
| hs->str_sbr_scale_fact.hb_scale = INT_BITS - 1; |
| hs->str_sbr_scale_fact.ov_hb_scale = INT_BITS - 1; |
| hs->str_sbr_scale_fact.st_syn_scale = INT_BITS - 1; |
| |
| ptr_sbr_channel->pstr_prev_frame_data = |
| sbr_persistent_mem->pstr_prev_frame_data[chan]; |
| |
| err = ixheaacd_create_sbr_env_calc(pstr_common_table, &hs->str_sbr_calc_env, |
| chan, sbr_persistent_mem, ptr_header_data, |
| audio_object_type); |
| |
| if (err) { |
| return (-1); |
| } |
| |
| ixheaacd_create_cplx_anal_qmfbank( |
| &hs->str_codec_qmf_bank, &hs->str_sbr_scale_fact, no_bins, |
| ptr_header_data->pstr_freq_band_data->sub_band_start, chan, |
| sbr_persistent_mem->sbr_qmf_analy_states, |
| sbr_persistent_mem->sbr_qmf_analy_states_32, |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables->qmf_dec_tables_ptr, |
| audio_object_type); |
| |
| ixheaacd_create_cplx_synt_qmfbank( |
| &hs->str_synthesis_qmf_bank, no_bins, |
| ptr_header_data->pstr_freq_band_data->sub_band_start, |
| ptr_header_data->pstr_freq_band_data->sub_band_end, chan, |
| down_sample_flag, sbr_persistent_mem->sbr_qmf_synth_states, |
| sbr_persistent_mem->sbr_qmf_synth_states_32, |
| sbr_persistent_mem->str_sbr_dec_inst.pstr_sbr_tables->qmf_dec_tables_ptr, |
| audio_object_type); |
| |
| ixheaacd_init_sbr_prev_framedata(ptr_sbr_channel->pstr_prev_frame_data, |
| time_slots); |
| |
| err = ixheaacd_create_hf_generator(&hs->str_hf_generator, |
| hs->str_codec_qmf_bank.num_time_slots, |
| chan, sbr_persistent_mem, ps_enable); |
| |
| if (err) { |
| return (-1); |
| } |
| |
| hs->ptr_sbr_overlap_buf = sbr_persistent_mem->ptr_sbr_overlap_buf[chan]; |
| |
| return 0; |
| } |