215 lines
7.9 KiB
C
215 lines
7.9 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 <string.h>
|
|
#include "iusace_type_def.h"
|
|
|
|
#include "ixheaace_mps_common_define.h"
|
|
#include "iusace_cnst.h"
|
|
#include "iusace_bitbuffer.h"
|
|
#include "impd_drc_common_enc.h"
|
|
#include "impd_drc_uni_drc.h"
|
|
#include "impd_drc_api.h"
|
|
#include "impd_drc_uni_drc_eq.h"
|
|
#include "impd_drc_uni_drc_filter_bank.h"
|
|
#include "impd_drc_gain_enc.h"
|
|
#include "impd_drc_struct_def.h"
|
|
|
|
#include "iusace_cnst.h"
|
|
#include "iusace_tns_usac.h"
|
|
#include "iusace_psy_mod.h"
|
|
#include "iusace_ms.h"
|
|
|
|
#include "ixheaace_adjust_threshold_data.h"
|
|
#include "iusace_fd_qc_util.h"
|
|
#include "ixheaace_memory_standards.h"
|
|
#include "iusace_config.h"
|
|
#include "iusace_fft.h"
|
|
#include "iusace_arith_enc.h"
|
|
#include "iusace_fd_quant.h"
|
|
#include "iusace_signal_classifier.h"
|
|
#include "iusace_block_switch_const.h"
|
|
#include "iusace_block_switch_struct_def.h"
|
|
#include "ixheaace_sbr_header.h"
|
|
#include "ixheaace_config.h"
|
|
#include "ixheaace_asc_write.h"
|
|
#include "iusace_main.h"
|
|
#include "iusace_windowing.h"
|
|
#include "ixheaac_error_standards.h"
|
|
|
|
static IA_ERRORCODE iusace_fd_mdct_short(ia_usac_data_struct *pstr_usac_data,
|
|
ia_usac_encoder_config_struct *pstr_usac_config,
|
|
WORD32 ch_idx) {
|
|
IA_ERRORCODE err_code = 0;
|
|
iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch;
|
|
IA_ERRORCODE err_code_2 = 0;
|
|
FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_short_buf;
|
|
WORD32 n_long = pstr_usac_config->ccfl;
|
|
WORD32 n_short = pstr_usac_config->ccfl >> 3;
|
|
FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx];
|
|
FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx];
|
|
FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx];
|
|
WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx];
|
|
FLOAT64 *ptr_win_gen_medium = NULL, *ptr_win_gen_short = NULL;
|
|
FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
|
|
WORD32 nflat_ls;
|
|
WORD32 i, k;
|
|
WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME;
|
|
|
|
memset(ptr_windowed_buf, 0, 2 * n_short * sizeof(FLOAT64));
|
|
nflat_ls = (n_long - n_short) >> 1;
|
|
err_code = iusace_calc_window(&ptr_win_gen_short, n_short, window_shape);
|
|
if (err_code) return err_code;
|
|
err_code = iusace_calc_window(&ptr_win_gen_medium, n_short, 0);
|
|
if (err_code) return err_code;
|
|
ptr_overlap += nflat_ls;
|
|
|
|
for (k = MAX_SHORT_WINDOWS - 1; k-- >= 0;) {
|
|
for (i = 0; i < n_short; i++) {
|
|
ptr_windowed_buf[i] = ptr_win_gen_short[i] * ptr_overlap[i];
|
|
}
|
|
for (i = 0; i < n_short; i++) {
|
|
ptr_windowed_buf[i + n_short] =
|
|
ptr_win_gen_medium[n_short - 1 - i] * ptr_overlap[i + n_short];
|
|
}
|
|
|
|
ptr_win_gen_medium = ptr_win_gen_short;
|
|
|
|
// Compute MDCT
|
|
err_code = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_short, MDCT_TX_FLAG,
|
|
pstr_scratch);
|
|
|
|
if (err_code) {
|
|
return err_code;
|
|
}
|
|
|
|
// Compute MDST
|
|
err_code_2 = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_short, MDST_TX_FLAG,
|
|
pstr_scratch);
|
|
|
|
if (err_code_2) {
|
|
return err_code_2;
|
|
}
|
|
|
|
ptr_out_mdct += n_short;
|
|
ptr_out_mdst += n_short;
|
|
ptr_overlap += n_short;
|
|
}
|
|
|
|
ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
|
|
memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(*ptr_overlap));
|
|
memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(*ptr_overlap));
|
|
|
|
return err_code;
|
|
}
|
|
|
|
static IA_ERRORCODE iusace_fd_mdct_long(ia_usac_data_struct *pstr_usac_data,
|
|
ia_usac_encoder_config_struct *pstr_usac_config,
|
|
WORD32 ch_idx, WORD32 window_sequence) {
|
|
IA_ERRORCODE err_code = 0;
|
|
iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch;
|
|
IA_ERRORCODE err_code_2 = 0;
|
|
FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_long_buf;
|
|
WORD32 n_long = pstr_usac_config->ccfl;
|
|
WORD32 n_short = pstr_usac_config->ccfl >> 3;
|
|
WORD32 prev_mode = (pstr_usac_data->core_mode_prev[ch_idx] == CORE_MODE_TD);
|
|
WORD32 next_mode = (pstr_usac_data->core_mode_next[ch_idx] == CORE_MODE_TD);
|
|
FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx];
|
|
FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx];
|
|
FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx];
|
|
WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx];
|
|
FLOAT64 *ptr_win_long = NULL, *ptr_win_med = NULL;
|
|
WORD32 win_len;
|
|
FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
|
|
|
|
WORD32 nflat_ls;
|
|
|
|
memset(ptr_windowed_buf, 0, 2 * n_long * sizeof(*ptr_windowed_buf));
|
|
|
|
switch (window_sequence) {
|
|
case ONLY_LONG_SEQUENCE:
|
|
err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
|
|
if (err_code) return err_code;
|
|
iusace_windowing_long(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long);
|
|
break;
|
|
|
|
case LONG_START_SEQUENCE:
|
|
win_len = n_short << next_mode;
|
|
nflat_ls = (n_long - win_len) >> 1;
|
|
err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
|
|
if (err_code) return err_code;
|
|
err_code = iusace_calc_window(&ptr_win_med, win_len, 0);
|
|
if (err_code) return err_code;
|
|
|
|
iusace_windowing_long_start(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data,
|
|
n_long, nflat_ls, ptr_win_med, win_len);
|
|
break;
|
|
|
|
case LONG_STOP_SEQUENCE:
|
|
win_len = n_short << prev_mode;
|
|
nflat_ls = (n_long - win_len) >> 1;
|
|
err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
|
|
if (err_code) return err_code;
|
|
err_code = iusace_calc_window(&ptr_win_med, win_len, 1);
|
|
if (err_code) return err_code;
|
|
iusace_windowing_long_stop(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long,
|
|
nflat_ls, ptr_win_med, win_len);
|
|
break;
|
|
|
|
case STOP_START_SEQUENCE:
|
|
win_len = n_short << (prev_mode | next_mode);
|
|
err_code = iusace_calc_window(&ptr_win_med, win_len, window_shape);
|
|
if (err_code) return err_code;
|
|
|
|
iusace_windowing_stop_start(ptr_overlap, ptr_windowed_buf, ptr_win_med, win_len, n_long);
|
|
break;
|
|
}
|
|
|
|
// Compute MDCT
|
|
err_code =
|
|
iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_long, MDCT_TX_FLAG, pstr_scratch);
|
|
if (err_code) {
|
|
return err_code;
|
|
}
|
|
|
|
// Compute MDST
|
|
err_code_2 =
|
|
iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_long, MDST_TX_FLAG, pstr_scratch);
|
|
|
|
if (err_code_2) {
|
|
return err_code_2;
|
|
}
|
|
|
|
return IA_NO_ERROR;
|
|
}
|
|
|
|
WORD32 iusace_fd_mdct(ia_usac_data_struct *pstr_usac_data,
|
|
ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx) {
|
|
IA_ERRORCODE err_code = 0;
|
|
WORD32 window_sequence = pstr_usac_config->window_sequence[ch_idx];
|
|
|
|
if (window_sequence != EIGHT_SHORT_SEQUENCE) {
|
|
err_code = iusace_fd_mdct_long(pstr_usac_data, pstr_usac_config, ch_idx, window_sequence);
|
|
} else {
|
|
err_code = iusace_fd_mdct_short(pstr_usac_data, pstr_usac_config, ch_idx);
|
|
}
|
|
|
|
return err_code;
|
|
}
|