unplugged-system/external/libxaac/decoder/ixheaacd_mps_blind.c

428 lines
17 KiB
C
Raw Permalink Normal View History

/******************************************************************************
*
* Copyright (C) 2023 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_type_def.h"
#include "ixheaacd_mps_struct_def.h"
#include "ixheaacd_error_codes.h"
#include "ixheaacd_mps_res_rom.h"
#include "ixheaacd_mps_aac_struct.h"
#include "ixheaacd_constants.h"
#include "ixheaacd_basic_ops32.h"
#include "ixheaacd_basic_ops40.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_error_standards.h"
#include "ixheaacd_mps_polyphase.h"
#include "ixheaacd_config.h"
#include "ixheaacd_qmf_dec.h"
#include "ixheaacd_mps_dec.h"
#include "ixheaacd_mps_bitdec.h"
#include "ixheaacd_mps_macro_def.h"
#include "ixheaacd_mps_basic_op.h"
#include "ixheaacd_mps_blind.h"
static IA_ERRORCODE ixheaacd_get_sampling_freq_idx(
WORD32 sampling_freq, ia_mps_dec_bitdec_tables_struct *ixheaacd_mps_dec_bitdec_tables,
WORD32 *idx) {
WORD32 i;
for (i = 0; i < 13; i++) {
if (ixheaacd_mps_dec_bitdec_tables->sampling_freq_table[i] == sampling_freq) {
*idx = i;
return IA_NO_ERROR;
}
}
*idx = 3;
return IA_XHEAAC_DEC_CONFIG_FATAL_INVALID_SAMPLE_RATE;
}
VOID ixheaacd_init_blind(ia_heaac_mps_state_struct *pstr_mps_state) {
ia_mps_dec_blind_decoder_struct *blind = pstr_mps_state->mps_persistent_mem.blind_decoder;
ia_mps_dec_blind_tables_struct *p_blind_table =
pstr_mps_state->ia_mps_dec_mps_table.blind_table_ptr;
ia_mps_dec_auxilary_struct *p_aux_struct = pstr_mps_state->aux_struct;
WORD32 temp_1, temp_2;
WORD32 q_64, q_32, q_16, q_8, q_4, q_2;
WORD32 r_64, r_32, r_16, r_8, r_4, r_2;
WORD32 i;
WORD32 qmf_bands = pstr_mps_state->qmf_bands;
ixheaacd_get_sampling_freq_idx(pstr_mps_state->sampling_freq,
pstr_mps_state->ia_mps_dec_mps_table.bitdec_table_ptr, &temp_1);
if (pstr_mps_state->qmf_bands == 128)
blind->filter_coeff = p_blind_table->exp_128[temp_1];
else {
q_64 = (WORD32)(qmf_bands >> 6) ? p_blind_table->exp_64[temp_1] : ONE_IN_Q15;
r_64 = (WORD32)(qmf_bands & SIX_BIT_MASK);
q_32 = (WORD32)(r_64 >> 5) ? p_blind_table->exp_32[temp_1] : ONE_IN_Q15;
r_32 = (WORD32)(r_64 & FIVE_BIT_MASK);
q_16 = (WORD32)(r_32 >> 4) ? p_blind_table->exp_16[temp_1] : ONE_IN_Q15;
r_16 = (WORD32)(r_32 & FOUR_BIT_MASK);
q_8 = (WORD32)(r_16 >> 3) ? p_blind_table->exp_8[temp_1] : ONE_IN_Q15;
r_8 = (WORD32)(r_16 & THREE_BIT_MASK);
q_4 = (WORD32)(r_8 >> 2) ? p_blind_table->exp_4[temp_1] : ONE_IN_Q15;
r_4 = (WORD32)(r_8 & TWO_BIT_MASK);
q_2 = (WORD32)(r_4 >> 1) ? p_blind_table->exp_2[temp_1] : ONE_IN_Q15;
r_2 = (WORD32)(r_4 & ONE_BIT_MASK) ? p_blind_table->exp_1[temp_1] : ONE_IN_Q15;
temp_1 = ixheaacd_mps_mult32_shr_15(ixheaacd_mps_mult32_shr_15(q_64, q_32), q_16);
temp_2 = ixheaacd_mps_mult32_shr_15(ixheaacd_mps_mult32_shr_15(q_8, q_4), q_2);
blind->filter_coeff =
ixheaacd_mps_mult32_shr_15(ixheaacd_mps_mult32_shr_15(temp_1, temp_2), r_2);
}
for (i = 0; i < MAX_PARAMETER_BANDS; i++) {
blind->excitation[0][i] = ABS_THR_FIX;
blind->excitation[1][i] = ABS_THR_FIX;
blind->excitation[2][i] = ABS_THR_FIX;
blind->q_excitation[0][i] = 15;
blind->q_excitation[1][i] = 15;
blind->q_excitation[2][i] = 15;
}
memset(p_aux_struct->temp_shape_enable_channel_stp, 0,
MAX_OUTPUT_CHANNELS_MPS * sizeof(p_aux_struct->temp_shape_enable_channel_stp[0]));
memset(p_aux_struct->temp_shape_enable_channel_ges, 0,
MAX_OUTPUT_CHANNELS_MPS * sizeof(p_aux_struct->temp_shape_enable_channel_ges[0]));
}
static VOID ixheaacd_signal_2_parameters(ia_heaac_mps_state_struct *pstr_mps_state, WORD32 ps) {
ia_mps_dec_blind_decoder_struct *blind = pstr_mps_state->mps_persistent_mem.blind_decoder;
ia_mps_dec_blind_tables_struct *p_blind_table =
pstr_mps_state->ia_mps_dec_mps_table.blind_table_ptr;
ia_mps_dec_auxilary_struct *p_aux_struct = pstr_mps_state->aux_struct;
WORD32 cld_index;
WORD32 icc_index;
WORD32 mesh[2][2];
WORD32 pb;
WORD32 *dequant_cld;
WORD32 *dequant_icc;
WORD32 *dequant_cpc;
WORD32 cld;
WORD32 icc;
WORD16 q_icc;
WORD32 cld_delta;
WORD32 icc_delta;
WORD16 q_icc_delta;
WORD32 temp_1;
WORD16 qtemp1, qtemp;
const WORD32 *sqrt_tab = pstr_mps_state->ia_mps_dec_mps_table.common_table_ptr->sqrt_tab;
WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
ixheaacd_get_dequant_tables(&dequant_cld, &dequant_icc, &dequant_cpc,
pstr_mps_state->ia_mps_dec_mps_table.bitdec_table_ptr);
for (pb = 0; pb < num_parameter_bands; pb++) {
temp_1 = ixheaacd_mps_div_32(blind->excitation[0][pb], blind->excitation[1][pb], &qtemp1);
qtemp1 = qtemp1 + blind->q_excitation[0][pb] - blind->q_excitation[1][pb];
cld = 10 * ixheaacd_mps_log10(temp_1, qtemp1);
qtemp1 = blind->q_excitation[0][pb];
temp_1 = ixheaacd_mps_mult32(blind->excitation[0][pb], blind->excitation[1][pb], &qtemp1,
blind->q_excitation[1][pb]);
temp_1 = ixheaacd_mps_sqrt(temp_1, &qtemp1, sqrt_tab);
icc = ixheaacd_mps_div_32(blind->excitation[2][pb], temp_1, &q_icc);
q_icc = q_icc + blind->q_excitation[2][pb] - qtemp1;
if (abs(cld) > THIRTY_IN_Q16)
cld_delta = THIRTY_IN_Q16;
else
cld_delta = ixheaacd_abs32(cld);
q_icc_delta = q_icc;
icc_delta = ixheaacd_mps_add32(icc, ONE_IN_Q15, &q_icc_delta, 15);
icc_delta = ixheaacd_mps_mult32(icc_delta, 10, &q_icc_delta, 0);
temp_1 = cld_delta >> 16;
if (temp_1 > 29)
cld_index = 29;
else
cld_index = temp_1;
temp_1 = icc_delta >> q_icc_delta;
if (temp_1 > 19)
icc_index = 19;
else
icc_index = temp_1;
cld_delta -= (cld_index << 16);
icc_delta -= (icc_index << q_icc_delta);
mesh[0][0] = p_blind_table->mesh_table.blind_cld_mesh[cld_index][icc_index] + 15;
mesh[0][1] = p_blind_table->mesh_table.blind_cld_mesh[cld_index][icc_index + 1] + 15;
mesh[1][0] = p_blind_table->mesh_table.blind_cld_mesh[cld_index + 1][icc_index] + 15;
mesh[1][1] = p_blind_table->mesh_table.blind_cld_mesh[cld_index + 1][icc_index + 1] + 15;
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, (mesh[0][1] - mesh[0][0]), &qtemp1, 0);
qtemp = 15;
p_aux_struct->ott_cld[0][ps][pb] =
ixheaacd_mps_add32((mesh[0][0] << 15), temp_1, &qtemp, qtemp1);
qtemp1 = 16;
temp_1 = ixheaacd_mps_mult32(cld_delta, (mesh[1][0] - mesh[0][0]), &qtemp1, 0);
p_aux_struct->ott_cld[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ott_cld[0][ps][pb], temp_1, &qtemp, qtemp1);
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, cld_delta, &qtemp1, 16);
temp_1 = ixheaacd_mps_mult32(temp_1, (mesh[1][1] - mesh[0][1] - mesh[1][0] + mesh[0][0]),
&qtemp1, 0);
p_aux_struct->ott_cld[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ott_cld[0][ps][pb], temp_1, &qtemp, qtemp1);
p_aux_struct->ott_cld[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ott_cld[0][ps][pb], ONE_IN_Q14, &qtemp, 15);
p_aux_struct->ott_cld[0][ps][pb] = dequant_cld[((p_aux_struct->ott_cld[0][ps][pb]) >> qtemp)];
mesh[0][0] = p_blind_table->mesh_table.blind_icc_mesh[cld_index][icc_index];
mesh[0][1] = p_blind_table->mesh_table.blind_icc_mesh[cld_index][icc_index + 1];
mesh[1][0] = p_blind_table->mesh_table.blind_icc_mesh[cld_index + 1][icc_index];
mesh[1][1] = p_blind_table->mesh_table.blind_icc_mesh[cld_index + 1][icc_index + 1];
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, (mesh[0][1] - mesh[0][0]), &qtemp1, 0);
qtemp = 15;
p_aux_struct->ott_icc[0][ps][pb] =
ixheaacd_mps_add32((mesh[0][0] << 15), temp_1, &qtemp, qtemp1);
qtemp1 = 16;
temp_1 = ixheaacd_mps_mult32(cld_delta, (mesh[1][0] - mesh[0][0]), &qtemp1, 0);
p_aux_struct->ott_icc[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ott_icc[0][ps][pb], temp_1, &qtemp, qtemp1);
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, cld_delta, &qtemp1, 16);
temp_1 = ixheaacd_mps_mult32(temp_1, (mesh[1][1] - mesh[0][1] - mesh[1][0] + mesh[0][0]),
&qtemp1, 0);
p_aux_struct->ott_icc[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ott_icc[0][ps][pb], temp_1, &qtemp, qtemp1);
p_aux_struct->ott_icc[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ott_icc[0][ps][pb], ONE_IN_Q14, &qtemp, 15);
p_aux_struct->ott_icc[0][ps][pb] = dequant_icc[((p_aux_struct->ott_icc[0][ps][pb]) >> qtemp)];
mesh[0][0] = p_blind_table->mesh_table.blind_cpc_1_mesh[cld_index][icc_index] + 20;
mesh[0][1] = p_blind_table->mesh_table.blind_cpc_1_mesh[cld_index][icc_index + 1] + 20;
mesh[1][0] = p_blind_table->mesh_table.blind_cpc_1_mesh[cld_index + 1][icc_index] + 20;
mesh[1][1] = p_blind_table->mesh_table.blind_cpc_1_mesh[cld_index + 1][icc_index + 1] + 20;
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, (mesh[0][1] - mesh[0][0]), &qtemp1, 0);
qtemp = 15;
p_aux_struct->ttt_cpc_1[0][ps][pb] =
ixheaacd_mps_add32((mesh[0][0] << 15), temp_1, &qtemp, qtemp1);
qtemp1 = 16;
temp_1 = ixheaacd_mps_mult32(cld_delta, (mesh[1][0] - mesh[0][0]), &qtemp1, 0);
p_aux_struct->ttt_cpc_1[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ttt_cpc_1[0][ps][pb], temp_1, &qtemp, qtemp1);
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, cld_delta, &qtemp1, 16);
temp_1 = ixheaacd_mps_mult32(temp_1, (mesh[1][1] - mesh[0][1] - mesh[1][0] + mesh[0][0]),
&qtemp1, 0);
p_aux_struct->ttt_cpc_1[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ttt_cpc_1[0][ps][pb], temp_1, &qtemp, qtemp1);
p_aux_struct->ttt_cpc_1[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ttt_cpc_1[0][ps][pb], ONE_IN_Q14, &qtemp, 15);
p_aux_struct->ttt_cpc_1[0][ps][pb] =
dequant_cpc[((p_aux_struct->ttt_cpc_1[0][ps][pb]) >> qtemp)];
mesh[0][0] = p_blind_table->mesh_table.blind_cpc_2_mesh[cld_index][icc_index] + 20;
mesh[0][1] = p_blind_table->mesh_table.blind_cpc_2_mesh[cld_index][icc_index + 1] + 20;
mesh[1][0] = p_blind_table->mesh_table.blind_cpc_2_mesh[cld_index + 1][icc_index] + 20;
mesh[1][1] = p_blind_table->mesh_table.blind_cpc_2_mesh[cld_index + 1][icc_index + 1] + 20;
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, (mesh[0][1] - mesh[0][0]), &qtemp1, 0);
qtemp = 15;
p_aux_struct->ttt_cpc_2[0][ps][pb] =
ixheaacd_mps_add32((mesh[0][0] < 15), temp_1, &qtemp, qtemp1);
qtemp1 = 16;
temp_1 = ixheaacd_mps_mult32(cld_delta, (mesh[1][0] - mesh[0][0]), &qtemp1, 0);
p_aux_struct->ttt_cpc_2[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ttt_cpc_2[0][ps][pb], temp_1, &qtemp, qtemp1);
qtemp1 = q_icc_delta;
temp_1 = ixheaacd_mps_mult32(icc_delta, cld_delta, &qtemp1, 16);
temp_1 = ixheaacd_mps_mult32(temp_1, (mesh[1][1] - mesh[0][1] - mesh[1][0] + mesh[0][0]),
&qtemp1, 0);
p_aux_struct->ttt_cpc_2[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ttt_cpc_2[0][ps][pb], temp_1, &qtemp, qtemp1);
p_aux_struct->ttt_cpc_2[0][ps][pb] =
ixheaacd_mps_add32(p_aux_struct->ttt_cpc_2[0][ps][pb], ONE_IN_Q14, &qtemp, 15);
p_aux_struct->ttt_cpc_2[0][ps][pb] =
dequant_cpc[((p_aux_struct->ttt_cpc_2[0][ps][pb]) >> qtemp)];
if (cld < 0) {
cld = p_aux_struct->ttt_cpc_2[0][ps][pb];
p_aux_struct->ttt_cpc_2[0][ps][pb] = p_aux_struct->ttt_cpc_1[0][ps][pb];
p_aux_struct->ttt_cpc_1[0][ps][pb] = cld;
}
}
}
static VOID ixheaacd_update_down_mix_state(ia_heaac_mps_state_struct *pstr_mps_state,
WORD32 offset) {
ia_mps_dec_blind_decoder_struct *blind = pstr_mps_state->mps_persistent_mem.blind_decoder;
WORD32 ts;
WORD32 hb;
WORD32 pb;
WORD32 *excitation_0, *excitation_1, *excitation_2;
WORD16 *q_excitation_0, *q_excitation_1, *q_excitation_2;
WORD32 temp_1, temp_2;
WORD16 qtemp1, qtemp2;
WORD32 *p_x_real, *p_x_imag;
WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
excitation_0 = pstr_mps_state->mps_scratch_mem_v;
q_excitation_0 = (WORD16 *)pstr_mps_state->mps_scratch_mem_v + PARAMETER_BANDSX2;
excitation_1 = excitation_0 + PARAMETER_BANDSX1_5;
q_excitation_1 = q_excitation_0 + PARAMETER_BANDSX3;
excitation_2 = excitation_1 + PARAMETER_BANDSX1_5;
q_excitation_2 = q_excitation_1 + PARAMETER_BANDSX3;
p_x_real = &pstr_mps_state->array_struct->x_real[offset * MAX_HYBRID_BANDS];
p_x_imag = &pstr_mps_state->array_struct->x_imag[offset * MAX_HYBRID_BANDS];
for (ts = 0; ts < HOP_SLOTS; ts++) {
WORD32 *x_real_0 = p_x_real;
WORD32 *x_imag_0 = p_x_imag;
WORD32 *x_real_1 = p_x_real + TSXHB;
WORD32 *x_imag_1 = p_x_imag + TSXHB;
for (pb = 0; pb < num_parameter_bands; pb++) {
excitation_0[pb] = ABS_THR_FIX;
excitation_1[pb] = ABS_THR_FIX;
excitation_2[pb] = ABS_THR_FIX;
q_excitation_0[pb] = 15;
q_excitation_1[pb] = 15;
q_excitation_2[pb] = 15;
}
for (hb = 0; hb < hybrid_bands; hb++) {
WORD64 temp;
pb = (WORD32)pstr_mps_state->kernels[hb];
temp =
(WORD64)((WORD64)*x_real_0 * (WORD64)*x_real_0 + (WORD64)*x_imag_0 * (WORD64)*x_imag_0);
temp >>= 10;
temp_1 = (WORD32)temp;
qtemp1 = 10;
excitation_0[pb] =
ixheaacd_mps_add32(excitation_0[pb], temp_1, &(q_excitation_0[pb]), qtemp1);
temp =
(WORD64)((WORD64)*x_real_1 * (WORD64)*x_real_1 + (WORD64)*x_imag_1 * (WORD64)*x_imag_1);
temp >>= 10;
temp_1 = (WORD32)temp;
qtemp1 = 10;
excitation_1[pb] =
ixheaacd_mps_add32(excitation_1[pb], temp_1, &(q_excitation_1[pb]), qtemp1);
temp =
(WORD64)((WORD64)*x_real_0 * (WORD64)*x_real_1 + (WORD64)*x_imag_0 * (WORD64)*x_imag_1);
temp >>= 10;
temp_1 = (WORD32)temp;
qtemp1 = 10;
excitation_2[pb] =
ixheaacd_mps_add32(excitation_2[pb], temp_1, &(q_excitation_2[pb]), qtemp1);
x_real_0++;
x_imag_0++;
x_real_1++;
x_imag_1++;
}
for (pb = 0; pb < num_parameter_bands; pb++) {
blind->excitation[0][pb] =
ixheaacd_mps_mult32_shr_15(blind->excitation[0][pb], blind->filter_coeff);
blind->excitation[1][pb] =
ixheaacd_mps_mult32_shr_15(blind->excitation[1][pb], blind->filter_coeff);
blind->excitation[2][pb] =
ixheaacd_mps_mult32_shr_15(blind->excitation[2][pb], blind->filter_coeff);
temp_1 = ONE_IN_Q15 - blind->filter_coeff;
qtemp2 = *q_excitation_0++;
temp_2 = ixheaacd_mps_mult32_shr_15(temp_1, *excitation_0);
excitation_0++;
blind->excitation[0][pb] = ixheaacd_mps_add32(blind->excitation[0][pb], temp_2,
&(blind->q_excitation[0][pb]), qtemp2);
qtemp2 = *q_excitation_1++;
temp_2 = ixheaacd_mps_mult32_shr_15(temp_1, *excitation_1);
excitation_1++;
blind->excitation[1][pb] = ixheaacd_mps_add32(blind->excitation[1][pb], temp_2,
&(blind->q_excitation[1][pb]), qtemp2);
qtemp2 = *q_excitation_2++;
temp_2 = ixheaacd_mps_mult32_shr_15(temp_1, *excitation_2);
excitation_2++;
blind->excitation[2][pb] = ixheaacd_mps_add32(blind->excitation[2][pb], temp_2,
&(blind->q_excitation[2][pb]), qtemp2);
}
excitation_0[pb] -= num_parameter_bands;
excitation_1[pb] -= num_parameter_bands;
excitation_2[pb] -= num_parameter_bands;
q_excitation_0[pb] -= num_parameter_bands;
q_excitation_1[pb] -= num_parameter_bands;
q_excitation_2[pb] -= num_parameter_bands;
p_x_real += MAX_HYBRID_BANDS;
p_x_imag += MAX_HYBRID_BANDS;
}
}
VOID ixheaacd_apply_blind(ia_heaac_mps_state_struct *pstr_mps_state) {
ia_mps_dec_spatial_bs_frame_struct *frame = pstr_mps_state->bs_frame;
WORD32 ts;
WORD32 ps;
WORD32 time_slots = pstr_mps_state->time_slots;
WORD32 *param_slot = pstr_mps_state->aux_struct->param_slot;
for (ts = 0, ps = 0; ts < time_slots; ts += HOP_SLOTS, ps++) {
param_slot[ps] = ts + HOP_SLOTS - 1;
ixheaacd_signal_2_parameters(pstr_mps_state, ps);
ixheaacd_update_down_mix_state(pstr_mps_state, ts);
}
pstr_mps_state->num_parameter_sets_prev = ps;
pstr_mps_state->num_parameter_sets = ps;
frame->bs_independency_flag = 0;
pstr_mps_state->aux_struct->num_ott_bands[0] = pstr_mps_state->num_parameter_bands;
return;
}