176 lines
5.8 KiB
C
176 lines
5.8 KiB
C
/******************************************************************************
|
|
*
|
|
* 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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|