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

176 lines
5.8 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 "ixheaacd_type_def.h"
#include "ixheaacd_constants.h"
#include "ixheaacd_cnst.h"
#include "ixheaacd_basic_ops32.h"
#include "ixheaacd_basic_ops16.h"
#include "ixheaacd_bitbuffer.h"
#include "ixheaacd_mps_aac_struct.h"
#include "ixheaacd_mps_res_rom.h"
#include "ixheaacd_mps_res_channelinfo.h"
#include "ixheaacd_mps_res_tns.h"
static PLATFORM_INLINE WORD16 ixheaacd_res_get_maximum_tns_bands(
ia_mps_dec_residual_ics_info_struct *p_ics_info,
ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr, WORD32 *win_len) {
WORD32 i = 0;
*win_len = 1;
if (p_ics_info->window_sequence == EIGHT_SHORT_SEQUENCE) {
*win_len = 8;
i = 1;
}
return aac_tables_ptr->res_block_tables_ptr
->tns_max_bands_tbl[p_ics_info->sampling_rate_index][i];
}
VOID ixheaacd_res_tns_decode_coeffs_32x16(const ia_mps_dec_residual_filter_struct *filter,
WORD16 *a,
ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr) {
WORD tmp;
WORD16 *aptr = a;
WORD16 *tns_coeff_ptr;
WORD8 offset = 4;
WORD8 *p_coeff = (WORD8 *)&filter->coeff[0];
WORD32 tmp1;
tmp = filter->resolution;
tns_coeff_ptr = aac_tables_ptr->res_block_tables_ptr->tns_coeff3_16;
if (tmp) {
tns_coeff_ptr = aac_tables_ptr->res_block_tables_ptr->tns_coeff4_16;
offset = offset << 1;
}
tmp1 = filter->order;
do {
WORD8 temp = *p_coeff++;
*aptr++ = tns_coeff_ptr[temp + offset];
tmp1--;
} while (tmp1 != 0);
}
VOID ixheaacd_res_ctns_apply(ia_mps_dec_residual_channel_info_struct *p_aac_decoder_channel_info,
WORD16 max_sfb,
ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr) {
WORD i;
WORD16 scale_lpc;
ia_mps_dec_residual_tns_data *p_tns_data = &p_aac_decoder_channel_info->tns_data;
WORD32 *p_spectrum = p_aac_decoder_channel_info->p_spectral_coefficient;
WORD window, index, start, stop, size, scale_spec;
ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_decoder_channel_info->ics_info;
WORD win_len, tns_max_bands;
WORD16 maximum_bins_short = ixheaacd_shr16_dir_sat(p_ics_info->frame_length, 3);
WORD32 coeff_parc[MAX_ORDER + 1];
WORD32 lpc[MAX_ORDER + 1];
const WORD16 *scale_factor_bands_tbl;
if (!p_tns_data->tns_data_present) return;
tns_max_bands = ixheaacd_res_get_maximum_tns_bands(p_ics_info, aac_tables_ptr, &win_len);
scale_factor_bands_tbl =
ixheaacd_res_get_sfb_offsets(&p_aac_decoder_channel_info->ics_info, aac_tables_ptr);
for (window = 0; window < win_len; window++) {
WORD ind_len = p_tns_data->number_of_filters[window];
for (index = 0; index < ind_len; index++) {
ia_mps_dec_residual_filter_struct *filter = &p_tns_data->filter[window][index];
if (filter->order <= 0) continue;
ixheaacd_res_tns_decode_coeffs_32x16(filter, (WORD16 *)coeff_parc, aac_tables_ptr);
start = ixheaacd_min32(ixheaacd_min32(filter->start_band, tns_max_bands), max_sfb);
start = scale_factor_bands_tbl[start];
stop = ixheaacd_min32(ixheaacd_min32(filter->stop_band, tns_max_bands), max_sfb);
stop = scale_factor_bands_tbl[stop];
size = (stop - start);
if (size <= 0) continue;
ixheaacd_res_tns_parcor_2_lpc_32x16((WORD16 *)coeff_parc, (WORD16 *)lpc, &scale_lpc,
filter->order);
{
WORD32 *p_tmp = p_spectrum + (window * maximum_bins_short) + start;
scale_spec = ixheaacd_res_calc_max_spectral_line(p_tmp, size);
}
scale_spec = ((scale_spec - 4) - scale_lpc);
if (scale_spec > 0) {
WORD shift;
scale_spec = ixheaacd_min32(scale_spec, 31);
if (filter->direction == -1)
shift = stop - 1;
else
shift = start;
ixheaacd_res_tns_ar_filter_fixed_32x16(&p_spectrum[(window * maximum_bins_short) + shift],
size, filter->direction, (WORD16 *)lpc,
filter->order, (WORD32)scale_lpc, scale_spec);
} else {
WORD shift;
WORD32 *p_tmp = p_spectrum + (window * maximum_bins_short) + start;
scale_spec = -scale_spec;
scale_spec = ixheaacd_min32(scale_spec, 31);
for (i = size; i != 0; i--) {
*p_tmp = (*p_tmp >> scale_spec);
p_tmp++;
}
if (filter->direction == -1)
shift = stop - 1;
else
shift = start;
{
WORD32 shift_val = scale_lpc;
ixheaacd_res_tns_ar_filter_fixed_32x16(
&p_spectrum[(window * maximum_bins_short) + shift], size, filter->direction,
(WORD16 *)lpc, filter->order, shift_val, 0);
}
{
p_tmp = p_spectrum + (window * maximum_bins_short) + start;
i = size;
do {
*p_tmp = (*p_tmp << scale_spec);
p_tmp++;
i--;
} while (i != 0);
}
}
}
}
}