Optimisation changes in mps dec module
Added changes to reduce processing loops in cases of residual bands, pre mix req and phase coding in mps module.
This commit is contained in:
parent
ec016c95b1
commit
3551482d1d
10 changed files with 759 additions and 128 deletions
|
|
@ -69,9 +69,14 @@
|
|||
#include "ixheaacd_mps_hybfilter.h"
|
||||
#include "ixheaacd_mps_nlc_dec.h"
|
||||
#include "ixheaacd_mps_huff_tab.h"
|
||||
|
||||
#include "math.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "ixheaacd_error_standards.h"
|
||||
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
extern const ia_huff_pt0_nodes_struct ixheaacd_huff_part0_nodes;
|
||||
extern const ia_huff_ipd_nodes_struct ixheaacd_huff_ipd_nodes;
|
||||
|
|
@ -211,7 +216,7 @@ VOID ixheaacd_mps_decor(ia_mps_dec_state_struct* self) {
|
|||
}
|
||||
|
||||
ixheaacd_mps_decor_apply(&self->mps_decor, self->v[k], self->w_diff[k],
|
||||
self->time_slots);
|
||||
self->time_slots, NO_RES_BANDS);
|
||||
|
||||
if (self->bs_tsd_enable) {
|
||||
for (sb_sample = 0; sb_sample < self->time_slots; sb_sample++) {
|
||||
|
|
@ -248,8 +253,8 @@ VOID ixheaacd_mps_mix_res_decor(ia_mps_dec_state_struct* self) {
|
|||
for (row = self->dir_sig_count;
|
||||
row < (self->dir_sig_count + self->decor_sig_count); row++) {
|
||||
if (indx < self->res_bands) {
|
||||
self->w_dir[row][ts][qs].re = self->hyb_res[ts][qs].re;
|
||||
self->w_dir[row][ts][qs].im = self->hyb_res[ts][qs].im;
|
||||
self->w_dir[row][ts][qs].re = self->hyb_res[qs][ts].re;
|
||||
self->w_dir[row][ts][qs].im = self->hyb_res[qs][ts].im;
|
||||
} else {
|
||||
self->w_dir[row][ts][qs].re = 0.0f;
|
||||
self->w_dir[row][ts][qs].im = 0.0f;
|
||||
|
|
@ -272,10 +277,54 @@ VOID ixheaacd_mps_mix_res_decor(ia_mps_dec_state_struct* self) {
|
|||
}
|
||||
}
|
||||
|
||||
VOID ixheaacd_mps_mix_res_decor_residual_band(ia_mps_dec_state_struct* self) {
|
||||
WORD32 ts, qs, indx;
|
||||
for (qs = 0; qs < self->hyb_band_count_max; qs++) {
|
||||
indx = self->hyb_band_to_processing_band_table[qs];
|
||||
if (indx >= self->res_bands) {
|
||||
if (qs < self->hyb_band_count[1]) {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
self->w_dir[1][ts][qs].re = 0.0f;
|
||||
self->w_dir[1][ts][qs].im = 0.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
self->w_diff[1][ts][qs].re = 0.0f;
|
||||
self->w_diff[1][ts][qs].im = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID ixheaacd_mps_create_w(ia_mps_dec_state_struct* self) {
|
||||
ixheaacd_mps_decor(self);
|
||||
ixheaacd_mps_mix_res_decor(self);
|
||||
}
|
||||
|
||||
VOID ixheaacd_mps_qmf_hyb_analysis_no_pre_mix(ia_mps_dec_state_struct* self) {
|
||||
ixheaacd_mps_qmf_hybrid_analysis_no_pre_mix(
|
||||
&self->hyb_filt_state[0], self->qmf_in[0], self->band_count[0],
|
||||
self->time_slots, self->w_dir[0]);
|
||||
|
||||
if (self->res_bands) {
|
||||
ixheaacd_mps_qmf_hybrid_analysis_no_pre_mix(
|
||||
&self->hyb_filt_state[1], self->qmf_in[1], self->band_count[1],
|
||||
self->time_slots, self->w_dir[1]);
|
||||
|
||||
if (self->res_bands != 28) {
|
||||
ixheaacd_mps_decor_apply(&self->mps_decor, self->w_dir[0],
|
||||
self->w_diff[1], self->time_slots,
|
||||
self->res_bands);
|
||||
|
||||
ixheaacd_mps_mix_res_decor_residual_band(self);
|
||||
}
|
||||
} else {
|
||||
ixheaacd_mps_decor_apply(&self->mps_decor, self->w_dir[0], self->w_diff[1],
|
||||
self->time_slots, NO_RES_BANDS);
|
||||
}
|
||||
}
|
||||
|
||||
WORD32 ixheaacd_mps_apply(ia_mps_dec_state_struct* self,
|
||||
FLOAT32** input_buffer[4],
|
||||
FLOAT32 (*output_buffer)[4096]) {
|
||||
|
|
@ -291,25 +340,6 @@ WORD32 ixheaacd_mps_apply(ia_mps_dec_state_struct* self,
|
|||
self->mps_decor.num_bins = self->hyb_band_count_max;
|
||||
self->output_buffer = output_buffer;
|
||||
|
||||
assert(self->present_time_slot + time_slots <= self->time_slots);
|
||||
|
||||
for (ts = 0; ts < time_slots; ts++) {
|
||||
for (ch = 0; ch < in_ch_count; ch++) {
|
||||
for (qs = 0; qs < self->band_count[ch]; qs++) {
|
||||
self->qmf_in[ch][self->present_time_slot + ts][qs].re =
|
||||
self->input_gain * input_buffer[2 * ch][ts][qs];
|
||||
self->qmf_in[ch][self->present_time_slot + ts][qs].im =
|
||||
self->input_gain * input_buffer[2 * ch + 1][ts][qs];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->present_time_slot += time_slots;
|
||||
|
||||
if (self->present_time_slot < self->time_slots) return 0;
|
||||
|
||||
self->present_time_slot = 0;
|
||||
|
||||
err = ixheaacd_mps_frame_decode(self);
|
||||
|
||||
if (err != 0) return err;
|
||||
|
|
@ -318,14 +348,40 @@ WORD32 ixheaacd_mps_apply(ia_mps_dec_state_struct* self,
|
|||
|
||||
ixheaacd_mps_pre_matrix_mix_matrix_smoothing(self);
|
||||
|
||||
ixheaacd_mps_qmf_hyb_analysis(self);
|
||||
for (ch = 0; ch < in_ch_count; ch++) {
|
||||
for (ts = 0; ts < time_slots; ts++) {
|
||||
for (qs = 0; qs < self->band_count[ch]; qs++) {
|
||||
self->qmf_in[ch][qs][ts].re =
|
||||
self->input_gain * input_buffer[2 * ch][ts][qs];
|
||||
self->qmf_in[ch][qs][ts].im =
|
||||
self->input_gain * input_buffer[2 * ch + 1][ts][qs];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = ixheaacd_mps_apply_pre_matrix(self);
|
||||
if (err < 0) return err;
|
||||
if (!(self->pre_mix_req | self->bs_tsd_enable)) {
|
||||
ixheaacd_mps_qmf_hyb_analysis_no_pre_mix(self);
|
||||
} else {
|
||||
ixheaacd_mps_qmf_hyb_analysis(self);
|
||||
|
||||
ixheaacd_mps_create_w(self);
|
||||
err = ixheaacd_mps_apply_pre_matrix(self);
|
||||
|
||||
if (err < 0) return err;
|
||||
|
||||
ixheaacd_mps_create_w(self);
|
||||
}
|
||||
|
||||
if ((!(self->res_bands | self->pre_mix_req)) &&
|
||||
(self->config->bs_phase_coding == 0)) {
|
||||
err = ixheaacd_mps_apply_mix_matrix_type1(self);
|
||||
|
||||
} else if (self->pre_mix_req) {
|
||||
err = ixheaacd_mps_apply_mix_matrix_type2(self);
|
||||
|
||||
} else {
|
||||
err = ixheaacd_mps_apply_mix_matrix_type3(self);
|
||||
}
|
||||
|
||||
err = ixheaacd_mps_apply_mix_matrix(self);
|
||||
if (err < 0) return err;
|
||||
|
||||
if (self->config->bs_temp_shape_config == 2) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
#define MAX_DECORR_FIL_ORDER (DECORR_FILT_0_ORD)
|
||||
|
||||
#define NO_RES_BANDS -1
|
||||
|
||||
typedef struct {
|
||||
FLOAT32 re;
|
||||
FLOAT32 im;
|
||||
|
|
@ -188,8 +190,7 @@ typedef struct ia_mps_dec_state_struct {
|
|||
WORD32 decor_sig_count;
|
||||
|
||||
WORD32 time_slots;
|
||||
WORD32 present_time_slot;
|
||||
|
||||
WORD32 pre_mix_req;
|
||||
WORD32 temp_shape_enable_ch_stp[2];
|
||||
WORD32 temp_shape_enable_ch_ges[2];
|
||||
|
||||
|
|
@ -269,9 +270,9 @@ typedef struct ia_mps_dec_state_struct {
|
|||
FLOAT32 m2_resid_re_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT];
|
||||
FLOAT32 m2_resid_im_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT];
|
||||
|
||||
ia_cmplx_flt_struct qmf_in[2][MAX_TIME_SLOTS][MAX_NUM_QMF_BANDS_MPS_NEW];
|
||||
ia_cmplx_flt_struct hyb_in[2][MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS];
|
||||
ia_cmplx_flt_struct hyb_res[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS];
|
||||
ia_cmplx_flt_struct qmf_in[2][MAX_NUM_QMF_BANDS_MPS_NEW][MAX_TIME_SLOTS];
|
||||
ia_cmplx_flt_struct hyb_in[2][MAX_HYBRID_BANDS_MPS][MAX_TIME_SLOTS];
|
||||
ia_cmplx_flt_struct hyb_res[MAX_HYBRID_BANDS_MPS][MAX_TIME_SLOTS];
|
||||
ia_cmplx_flt_struct v[MAX_M1_OUTPUT][MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS];
|
||||
ia_cmplx_flt_struct w_diff[MAX_M2_INPUT][MAX_TIME_SLOTS]
|
||||
[MAX_HYBRID_BANDS_MPS];
|
||||
|
|
@ -338,7 +339,9 @@ typedef struct ia_mps_dec_state_struct {
|
|||
VOID ixheaacd_mps_init_pre_and_post_matrix(ia_mps_dec_state_struct *self);
|
||||
VOID ixheaacd_pre_and_mix_matrix_calculation(ia_mps_dec_state_struct *self);
|
||||
WORD32 ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self);
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self);
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix_type1(ia_mps_dec_state_struct *self);
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix_type2(ia_mps_dec_state_struct *self);
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix_type3(ia_mps_dec_state_struct *self);
|
||||
|
||||
WORD32 ixheaacd_mps_frame_decode(ia_mps_dec_state_struct *self);
|
||||
|
||||
|
|
@ -364,7 +367,7 @@ VOID ixheaacd_mps_par2umx_pred(ia_mps_dec_state_struct *self,
|
|||
FLOAT32 *h_imag, FLOAT32 *h_real,
|
||||
WORD32 param_set_idx, WORD32 res_bands);
|
||||
|
||||
WORD32 ixheaacd_mps_upmix_interp(
|
||||
WORD32 ixheaacd_mps_upmix_interp_type1(
|
||||
FLOAT32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
[MAX_M_INPUT],
|
||||
FLOAT32 r_matrix[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
|
|
@ -373,6 +376,14 @@ WORD32 ixheaacd_mps_upmix_interp(
|
|||
WORD32 num_rows, WORD32 num_cols, ia_mps_dec_state_struct *self,
|
||||
WORD32 bs_high_rate_mode);
|
||||
|
||||
WORD32 ixheaacd_mps_upmix_interp_type2(
|
||||
FLOAT32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
[MAX_M_INPUT],
|
||||
FLOAT32 r_matrix[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
[MAX_M_INPUT],
|
||||
FLOAT32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
|
||||
WORD32 num_rows, ia_mps_dec_state_struct *self, WORD32 col);
|
||||
|
||||
VOID ixheaacd_mps_phase_interpolation(
|
||||
FLOAT32 pl[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
|
||||
FLOAT32 pr[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS],
|
||||
|
|
|
|||
|
|
@ -30,6 +30,6 @@ VOID ixheaacd_mps_decor_apply(
|
|||
ia_mps_decor_struct_handle self,
|
||||
ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
WORD32 length);
|
||||
WORD32 length, WORD32 res_bands);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ static const WORD32 ixheaacd_qmf_split_freq_0[] = {3, 15, 24, 65};
|
|||
static const WORD32 ixheaacd_qmf_split_freq_1[] = {3, 50, 65, 65};
|
||||
static const WORD32 ixheaacd_qmf_split_freq_2[] = {0, 15, 65, 65};
|
||||
|
||||
extern const WORD32 ixheaacd_mps_gain_set_indx[29];
|
||||
|
||||
static const FLOAT32
|
||||
ixheaacd_lattice_coeff_0_filt_den_coeff[DECORR_FILT_0_ORD + 1] = {
|
||||
1.000000f, -0.314818f, -0.256828f, -0.173641f, -0.115077f, 0.000599f,
|
||||
|
|
@ -141,19 +143,25 @@ static VOID ixheaacd_mps_decor_energy_adjustment(
|
|||
ixheaacd_mps_decor_energy_adjust_filt_struct *handle,
|
||||
ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
WORD32 time_slots) {
|
||||
WORD32 time_slots, WORD32 res_bands) {
|
||||
ixheaacd_mps_decor_energy_adjust_filt_struct *self =
|
||||
(ixheaacd_mps_decor_energy_adjust_filt_struct *)handle;
|
||||
FLOAT32 in_energy[MAX_PARAMETER_BANDS] = {0};
|
||||
FLOAT32 out_energy[MAX_PARAMETER_BANDS] = {0};
|
||||
FLOAT32 gain[MAX_PARAMETER_BANDS];
|
||||
WORD32 i, j, k;
|
||||
WORD32 start_param_band = 0, start_bin = 0;
|
||||
|
||||
if (res_bands != NO_RES_BANDS) {
|
||||
start_bin = ixheaacd_mps_gain_set_indx[res_bands];
|
||||
start_param_band = res_bands;
|
||||
}
|
||||
|
||||
for (i = 0; i < time_slots; i++) {
|
||||
memset(in_energy, 0, sizeof(FLOAT32) * MAX_PARAMETER_BANDS);
|
||||
memset(out_energy, 0, sizeof(FLOAT32) * MAX_PARAMETER_BANDS);
|
||||
|
||||
for (j = 0; j < self->num_bins; j++) {
|
||||
for (j = start_bin; j < self->num_bins; j++) {
|
||||
k = ixheaacd_hybrid_band_71_to_processing_band_28_map[j];
|
||||
|
||||
in_energy[k] += in[i][j].re * in[i][j].re + in[i][j].im * in[i][j].im;
|
||||
|
|
@ -161,7 +169,7 @@ static VOID ixheaacd_mps_decor_energy_adjustment(
|
|||
out[i][j].re * out[i][j].re + out[i][j].im * out[i][j].im;
|
||||
}
|
||||
|
||||
for (k = 0; k < MAX_PARAMETER_BANDS; k++) {
|
||||
for (k = start_param_band; k < MAX_PARAMETER_BANDS; k++) {
|
||||
self->smooth_in_energy[k] = self->smooth_in_energy[k] * DECOR_ALPHA +
|
||||
in_energy[k] * ONE_MINUS_DECOR_ALPHA;
|
||||
self->smooth_out_energy[k] = self->smooth_out_energy[k] * DECOR_ALPHA +
|
||||
|
|
@ -184,7 +192,7 @@ static VOID ixheaacd_mps_decor_energy_adjustment(
|
|||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < self->num_bins; j++) {
|
||||
for (j = start_bin; j < self->num_bins; j++) {
|
||||
k = ixheaacd_hybrid_band_71_to_processing_band_28_map[j];
|
||||
|
||||
out[i][j].re *= gain[k];
|
||||
|
|
@ -233,12 +241,14 @@ VOID ixheaacd_mps_decor_apply(
|
|||
ia_mps_decor_struct_handle self,
|
||||
ia_cmplx_flt_struct in[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
ia_cmplx_flt_struct out[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
WORD32 length) {
|
||||
WORD32 idx, sb_sample;
|
||||
WORD32 length, WORD32 res_bands) {
|
||||
WORD32 idx, sb_sample, index = 0;
|
||||
|
||||
ia_cmplx_flt_struct scratch[MAX_TIME_SLOTS];
|
||||
|
||||
for (idx = 0; idx < self->num_bins; idx++) {
|
||||
if (res_bands != NO_RES_BANDS) index = ixheaacd_mps_gain_set_indx[res_bands];
|
||||
|
||||
for (idx = index; idx < self->num_bins; idx++) {
|
||||
for (sb_sample = 0; sb_sample < length; sb_sample++) {
|
||||
self->decor_delay_buffer[idx][self->delay_sample_count[idx] + sb_sample]
|
||||
.re = in[sb_sample][idx].re;
|
||||
|
|
@ -262,6 +272,6 @@ VOID ixheaacd_mps_decor_apply(
|
|||
}
|
||||
}
|
||||
|
||||
ixheaacd_mps_decor_energy_adjustment(&self->decor_nrg_smooth, in, out,
|
||||
length);
|
||||
ixheaacd_mps_decor_energy_adjustment(&self->decor_nrg_smooth, in, out, length,
|
||||
res_bands);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,15 @@ VOID ixheaacd_mps_qmf_hybrid_analysis_init(ia_mps_hybrid_filt_struct *handle);
|
|||
|
||||
VOID ixheaacd_mps_qmf_hybrid_analysis(
|
||||
ia_mps_hybrid_filt_struct *handle,
|
||||
ia_cmplx_flt_struct in_qmf[MAX_TIME_SLOTS][MAX_NUM_QMF_BANDS_MPS_NEW],
|
||||
ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS_NEW][MAX_TIME_SLOTS],
|
||||
WORD32 num_bands, WORD32 num_samples,
|
||||
ia_cmplx_flt_struct out_hyb[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS]);
|
||||
ia_cmplx_flt_struct out_hyb[MAX_HYBRID_BANDS_MPS][MAX_TIME_SLOTS]);
|
||||
|
||||
VOID ixheaacd_mps_qmf_hybrid_analysis_no_pre_mix(
|
||||
ia_mps_hybrid_filt_struct *handle,
|
||||
ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS_NEW][MAX_TIME_SLOTS],
|
||||
WORD32 num_bands, WORD32 num_samples,
|
||||
ia_cmplx_flt_struct v[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS]);
|
||||
|
||||
VOID ixheaacd_mps_qmf_hybrid_synthesis(
|
||||
ia_cmplx_flt_struct in_hyb[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
|
|
|
|||
|
|
@ -214,11 +214,11 @@ VOID ixheaacd_mps_qmf_hybrid_analysis_init(ia_mps_hybrid_filt_struct *handle) {
|
|||
sizeof(ia_cmplx_flt_struct));
|
||||
}
|
||||
|
||||
VOID ixheaacd_mps_qmf_hybrid_analysis(
|
||||
VOID ixheaacd_mps_qmf_hybrid_analysis_no_pre_mix(
|
||||
ia_mps_hybrid_filt_struct *handle,
|
||||
ia_cmplx_flt_struct in_qmf[MAX_TIME_SLOTS][MAX_NUM_QMF_BANDS_MPS_NEW],
|
||||
ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS_NEW][MAX_TIME_SLOTS],
|
||||
WORD32 num_bands, WORD32 num_samples,
|
||||
ia_cmplx_flt_struct hyb[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS]) {
|
||||
ia_cmplx_flt_struct v[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS]) {
|
||||
WORD32 lf_samples_shift;
|
||||
WORD32 hf_samples_shift;
|
||||
WORD32 lf_qmf_bands;
|
||||
|
|
@ -237,26 +237,18 @@ VOID ixheaacd_mps_qmf_hybrid_analysis(
|
|||
}
|
||||
|
||||
for (k = 0; k < lf_qmf_bands; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
handle->lf_buffer[k][n + lf_samples_shift].re = (in_qmf[n][k].re);
|
||||
handle->lf_buffer[k][n + lf_samples_shift].im = (in_qmf[n][k].im);
|
||||
}
|
||||
memcpy(&handle->lf_buffer[k][lf_samples_shift].re, &in_qmf[k][0].re,
|
||||
2 * num_samples * sizeof(FLOAT32));
|
||||
}
|
||||
|
||||
for (k = 0; k < MAX_NUM_QMF_BANDS_SAC / 2 - lf_qmf_bands; k++) {
|
||||
for (n = 0; n < hf_samples_shift; n++) {
|
||||
handle->hf_buffer[k][n].re = handle->hf_buffer[k][n + num_samples].re;
|
||||
handle->hf_buffer[k][n].im = handle->hf_buffer[k][n + num_samples].im;
|
||||
}
|
||||
memmove(&handle->hf_buffer[k][0].re, &handle->hf_buffer[k][num_samples].re,
|
||||
2 * hf_samples_shift * sizeof(FLOAT32));
|
||||
}
|
||||
|
||||
for (k = 0; k < num_bands - lf_qmf_bands; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
handle->hf_buffer[k][n + hf_samples_shift].re =
|
||||
(in_qmf[n][k + lf_qmf_bands].re);
|
||||
handle->hf_buffer[k][n + hf_samples_shift].im =
|
||||
(in_qmf[n][k + lf_qmf_bands].im);
|
||||
}
|
||||
memcpy(&handle->hf_buffer[k][hf_samples_shift].re,
|
||||
&in_qmf[k + lf_qmf_bands][0].re, 2 * num_samples * sizeof(FLOAT32));
|
||||
}
|
||||
|
||||
ixheaacd_mps_hyb_filt_type1(
|
||||
|
|
@ -265,15 +257,15 @@ VOID ixheaacd_mps_qmf_hybrid_analysis(
|
|||
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
hyb[n][k].re = scratch[k + 6][n].re;
|
||||
hyb[n][k + 2].re = scratch[k][n].re;
|
||||
hyb[n][k + 4].re = scratch[k + 2][n].re;
|
||||
hyb[n][k + 4].re += scratch[5 - k][n].re;
|
||||
v[n][k].re = scratch[k + 6][n].re;
|
||||
v[n][k + 2].re = scratch[k][n].re;
|
||||
v[n][k + 4].re = scratch[k + 2][n].re;
|
||||
v[n][k + 4].re += scratch[5 - k][n].re;
|
||||
|
||||
hyb[n][k].im = scratch[k + 6][n].im;
|
||||
hyb[n][k + 2].im = scratch[k][n].im;
|
||||
hyb[n][k + 4].im = scratch[k + 2][n].im;
|
||||
hyb[n][k + 4].im += scratch[5 - k][n].im;
|
||||
v[n][k].im = scratch[k + 6][n].im;
|
||||
v[n][k + 2].im = scratch[k][n].im;
|
||||
v[n][k + 4].im = scratch[k + 2][n].im;
|
||||
v[n][k + 4].im += scratch[5 - k][n].im;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -283,8 +275,8 @@ VOID ixheaacd_mps_qmf_hybrid_analysis(
|
|||
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
hyb[n][k + 6].re = scratch[1 - k][n].re;
|
||||
hyb[n][k + 6].im = scratch[1 - k][n].im;
|
||||
v[n][k + 6].re = scratch[1 - k][n].re;
|
||||
v[n][k + 6].im = scratch[1 - k][n].im;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -294,19 +286,102 @@ VOID ixheaacd_mps_qmf_hybrid_analysis(
|
|||
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
hyb[n][k + 8].re = scratch[k][n].re;
|
||||
hyb[n][k + 8].im = scratch[k][n].im;
|
||||
v[n][k + 8].re = scratch[k][n].re;
|
||||
v[n][k + 8].im = scratch[k][n].im;
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < num_bands - lf_qmf_bands; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
hyb[n][k + 10].re = (handle->hf_buffer[k][n + hf_samples_shift].re);
|
||||
hyb[n][k + 10].im = (handle->hf_buffer[k][n + hf_samples_shift].im);
|
||||
v[n][k + 10].re = (handle->hf_buffer[k][n + hf_samples_shift].re);
|
||||
v[n][k + 10].im = (handle->hf_buffer[k][n + hf_samples_shift].im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID ixheaacd_mps_qmf_hybrid_analysis(
|
||||
ia_mps_hybrid_filt_struct *handle,
|
||||
ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS_NEW][MAX_TIME_SLOTS],
|
||||
WORD32 num_bands, WORD32 num_samples,
|
||||
ia_cmplx_flt_struct hyb[MAX_HYBRID_BANDS_MPS][MAX_TIME_SLOTS]) {
|
||||
WORD32 lf_samples_shift;
|
||||
WORD32 hf_samples_shift;
|
||||
WORD32 lf_qmf_bands;
|
||||
WORD32 k, n;
|
||||
|
||||
ia_cmplx_flt_struct scratch[MAX_HYBRID_ONLY_BANDS_PER_QMF][MAX_TIME_SLOTS];
|
||||
|
||||
lf_samples_shift = BUFFER_LEN_LF_MPS - num_samples;
|
||||
hf_samples_shift = BUFFER_LEN_HF_MPS - num_samples;
|
||||
|
||||
lf_qmf_bands = QMF_BANDS_TO_HYBRID;
|
||||
|
||||
for (k = 0; k < lf_qmf_bands; k++) {
|
||||
memmove(&handle->lf_buffer[k][0].re, &handle->lf_buffer[k][num_samples].re,
|
||||
2 * lf_samples_shift * sizeof(FLOAT32));
|
||||
}
|
||||
|
||||
for (k = 0; k < lf_qmf_bands; k++) {
|
||||
memcpy(&handle->lf_buffer[k][lf_samples_shift].re, &in_qmf[k][0].re,
|
||||
2 * num_samples * sizeof(FLOAT32));
|
||||
}
|
||||
|
||||
for (k = 0; k < MAX_NUM_QMF_BANDS_SAC / 2 - lf_qmf_bands; k++) {
|
||||
memmove(&handle->hf_buffer[k][0].re, &handle->hf_buffer[k][num_samples].re,
|
||||
2 * hf_samples_shift * sizeof(FLOAT32));
|
||||
}
|
||||
|
||||
for (k = 0; k < num_bands - lf_qmf_bands; k++) {
|
||||
memcpy(&handle->hf_buffer[k][hf_samples_shift].re,
|
||||
&in_qmf[k + lf_qmf_bands][0].re, 2 * num_samples * sizeof(FLOAT32));
|
||||
}
|
||||
|
||||
ixheaacd_mps_hyb_filt_type1(
|
||||
&(handle->lf_buffer[0][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]),
|
||||
scratch, num_samples, ixheaacd_ia_mps_hyb_filter_coeff_8);
|
||||
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
hyb[k][n].re = scratch[k + 6][n].re;
|
||||
hyb[k + 2][n].re = scratch[k][n].re;
|
||||
hyb[k + 4][n].re = scratch[k + 2][n].re;
|
||||
hyb[k + 4][n].re += scratch[5 - k][n].re;
|
||||
|
||||
hyb[k][n].im = scratch[k + 6][n].im;
|
||||
hyb[k + 2][n].im = scratch[k][n].im;
|
||||
hyb[k + 4][n].im = scratch[k + 2][n].im;
|
||||
hyb[k + 4][n].im += scratch[5 - k][n].im;
|
||||
}
|
||||
}
|
||||
|
||||
ixheaacd_mps_hyb_filt_type2(
|
||||
&(handle->lf_buffer[1][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]),
|
||||
scratch, num_samples, ixheaacd_mps_hyb_filter_coeff_2);
|
||||
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
hyb[k + 6][n].re = scratch[1 - k][n].re;
|
||||
hyb[k + 6][n].im = scratch[1 - k][n].im;
|
||||
}
|
||||
}
|
||||
|
||||
ixheaacd_mps_hyb_filt_type2(
|
||||
&(handle->lf_buffer[2][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]),
|
||||
scratch, num_samples, ixheaacd_mps_hyb_filter_coeff_2);
|
||||
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (n = 0; n < num_samples; n++) {
|
||||
hyb[k + 8][n].re = scratch[k][n].re;
|
||||
hyb[k + 8][n].im = scratch[k][n].im;
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < num_bands - lf_qmf_bands; k++) {
|
||||
memcpy(&hyb[k + 10][0].re, &handle->hf_buffer[k][hf_samples_shift].re,
|
||||
2 * num_samples * sizeof(FLOAT32));
|
||||
}
|
||||
}
|
||||
|
||||
VOID ixheaacd_mps_qmf_hybrid_synthesis(
|
||||
ia_cmplx_flt_struct hyb[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],
|
||||
WORD32 num_bands, WORD32 num_samples,
|
||||
|
|
@ -328,9 +403,7 @@ VOID ixheaacd_mps_qmf_hybrid_synthesis(
|
|||
in_qmf[n][2].re = hyb[n][8].re + hyb[n][9].re;
|
||||
in_qmf[n][2].im = hyb[n][8].im + hyb[n][9].im;
|
||||
|
||||
for (k = 3; k < num_bands; k++) {
|
||||
in_qmf[n][k].re = hyb[n][k - 3 + 10].re;
|
||||
in_qmf[n][k].im = hyb[n][k - 3 + 10].im;
|
||||
}
|
||||
memcpy(&in_qmf[n][3].re, &hyb[n][10].re,
|
||||
2 * (num_bands - 3) * sizeof(FLOAT32));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ extern const FLOAT32 ixheaacd_c_l_table[31];
|
|||
extern const FLOAT32 ixheaacd_sin_table[8][31];
|
||||
extern const FLOAT32 ixheaacd_cos_table[8][31];
|
||||
|
||||
extern const WORD32 ixheaacd_mps_gain_set_indx[29];
|
||||
|
||||
static WORD32 ixheaacd_mps_phase_wraping(WORD32 phase) {
|
||||
const WORD32 pi_2 = 2 * PI_IN_Q28;
|
||||
|
||||
|
|
@ -342,68 +344,115 @@ VOID ixheaacd_mps_par2umx_pred(ia_mps_dec_state_struct *self,
|
|||
WORD32 ixheaacd_mps_apply_pre_matrix(ia_mps_dec_state_struct *self) {
|
||||
WORD32 ts, qs, row;
|
||||
WORD32 err = 0;
|
||||
err = ixheaacd_mps_upmix_interp(self->m1_param_re, self->r_out_re_in_m1,
|
||||
self->m1_param_re_prev,
|
||||
(self->dir_sig_count + self->decor_sig_count),
|
||||
1, self, self->bs_high_rate_mode);
|
||||
if (err < 0) return err;
|
||||
if (self->pre_mix_req) {
|
||||
err = ixheaacd_mps_upmix_interp_type1(
|
||||
self->m1_param_re, self->r_out_re_in_m1, self->m1_param_re_prev,
|
||||
(self->dir_sig_count + self->decor_sig_count), 1, self,
|
||||
self->bs_high_rate_mode);
|
||||
if (err < 0) return err;
|
||||
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < 2; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < 2; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
|
||||
FLOAT32 real =
|
||||
self->hyb_in[0][ts][qs].re * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
FLOAT32 imag =
|
||||
self->hyb_in[0][ts][qs].im * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
|
||||
row++) {
|
||||
self->v[row][ts][qs].re = real;
|
||||
self->v[row][ts][qs].im = imag;
|
||||
FLOAT32 real =
|
||||
self->hyb_in[0][qs][ts].re * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
FLOAT32 imag =
|
||||
self->hyb_in[0][qs][ts].im * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
|
||||
row++) {
|
||||
self->v[row][ts][qs].re = real;
|
||||
self->v[row][ts][qs].im = imag;
|
||||
}
|
||||
}
|
||||
for (qs = 2; qs < self->hyb_band_count[0]; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
FLOAT32 real =
|
||||
self->hyb_in[0][qs][ts].re * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
FLOAT32 imag =
|
||||
self->hyb_in[0][qs][ts].im * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
|
||||
row++) {
|
||||
self->v[row][ts][qs].re = real;
|
||||
self->v[row][ts][qs].im = imag;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (qs = 2; qs < self->hyb_band_count[0]; qs++) {
|
||||
WORD32 sign = 1;
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
FLOAT32 real =
|
||||
self->hyb_in[0][ts][qs].re * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
FLOAT32 imag =
|
||||
self->hyb_in[0][ts][qs].im * self->r_out_re_in_m1[ts][indx][0][0];
|
||||
for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
|
||||
row++) {
|
||||
self->v[row][ts][qs].re = real;
|
||||
self->v[row][ts][qs].im = imag;
|
||||
} else {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
|
||||
FLOAT32 real = self->hyb_in[0][qs][ts].re;
|
||||
FLOAT32 imag = self->hyb_in[0][qs][ts].im;
|
||||
for (row = 0; row < (self->dir_sig_count + self->decor_sig_count);
|
||||
row++) {
|
||||
self->v[row][ts][qs].re = real;
|
||||
self->v[row][ts][qs].im = imag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self) {
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix_type1(ia_mps_dec_state_struct *self) {
|
||||
WORD32 ts, qs, row;
|
||||
WORD32 err = 0;
|
||||
|
||||
err = ixheaacd_mps_upmix_interp_type2(
|
||||
self->m2_decor_re, self->r_out_diff_re_in_m2, self->m2_decor_re_prev,
|
||||
self->out_ch_count, self, 1);
|
||||
if (err < 0) return err;
|
||||
|
||||
err = ixheaacd_mps_upmix_interp_type2(self->m2_resid_re, self->r_out_re_in_m2,
|
||||
self->m2_resid_re_prev,
|
||||
self->out_ch_count, self, 0);
|
||||
if (err < 0) return err;
|
||||
|
||||
for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
self->hyb_dir_out[row][ts][qs].re =
|
||||
self->w_dir[0][ts][qs].re * self->r_out_re_in_m2[ts][indx][row][0];
|
||||
self->hyb_dir_out[row][ts][qs].im =
|
||||
self->w_dir[0][ts][qs].im * self->r_out_re_in_m2[ts][indx][row][0];
|
||||
self->hyb_diff_out[row][ts][qs].re =
|
||||
self->w_diff[1][ts][qs].re *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
self->hyb_diff_out[row][ts][qs].im =
|
||||
self->w_diff[1][ts][qs].im *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix_type2(ia_mps_dec_state_struct *self) {
|
||||
WORD32 ts, qs, row, col;
|
||||
WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
|
||||
WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
|
||||
WORD32 err = 0;
|
||||
WORD32 num_col_iters = 0;
|
||||
|
||||
err = ixheaacd_mps_upmix_interp(self->m2_decor_re, self->r_out_diff_re_in_m2,
|
||||
self->m2_decor_re_prev, self->out_ch_count,
|
||||
(self->dir_sig_count + self->decor_sig_count),
|
||||
self, 1);
|
||||
err = ixheaacd_mps_upmix_interp_type1(
|
||||
self->m2_decor_re, self->r_out_diff_re_in_m2, self->m2_decor_re_prev,
|
||||
self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self,
|
||||
1);
|
||||
if (err < 0) return err;
|
||||
err = ixheaacd_mps_upmix_interp(self->m2_resid_re, self->r_out_re_in_m2,
|
||||
self->m2_resid_re_prev, self->out_ch_count,
|
||||
(self->dir_sig_count + self->decor_sig_count),
|
||||
self, 1);
|
||||
err = ixheaacd_mps_upmix_interp_type1(
|
||||
self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
|
||||
self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self,
|
||||
1);
|
||||
if (err < 0) return err;
|
||||
|
||||
if (complex_m2 && !phase_interpolation) {
|
||||
err = ixheaacd_mps_upmix_interp(
|
||||
err = ixheaacd_mps_upmix_interp_type1(
|
||||
self->m2_decor_im, self->r_out_diff_im_in_m2, self->m2_decor_im_prev,
|
||||
self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self,
|
||||
1);
|
||||
if (err < 0) return err;
|
||||
err = ixheaacd_mps_upmix_interp(
|
||||
err = ixheaacd_mps_upmix_interp_type1(
|
||||
self->m2_resid_im, self->r_out_im_in_m2, self->m2_resid_im_prev,
|
||||
self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self,
|
||||
1);
|
||||
|
|
@ -590,7 +639,371 @@ WORD32 ixheaacd_mps_apply_mix_matrix(ia_mps_dec_state_struct *self) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
WORD32 ixheaacd_mps_upmix_interp(
|
||||
WORD32 ixheaacd_mps_apply_mix_matrix_type3(ia_mps_dec_state_struct *self) {
|
||||
WORD32 ts, qs, row, col;
|
||||
WORD32 complex_m2 = ((self->config->bs_phase_coding != 0));
|
||||
WORD32 phase_interpolation = (self->config->bs_phase_coding == 1);
|
||||
WORD32 err = 0;
|
||||
WORD32 num_col_iters = 0;
|
||||
|
||||
if (self->res_bands != 28) {
|
||||
err = ixheaacd_mps_upmix_interp_type2(
|
||||
self->m2_decor_re, self->r_out_diff_re_in_m2, self->m2_decor_re_prev,
|
||||
self->out_ch_count, self, 1);
|
||||
if (err < 0) return err;
|
||||
}
|
||||
if (self->res_bands == 0) {
|
||||
num_col_iters = self->dir_sig_count;
|
||||
err = ixheaacd_mps_upmix_interp_type2(
|
||||
self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
|
||||
self->out_ch_count, self, 0);
|
||||
if (err < 0) return err;
|
||||
} else {
|
||||
num_col_iters = (self->dir_sig_count + self->decor_sig_count);
|
||||
err = ixheaacd_mps_upmix_interp_type1(
|
||||
self->m2_resid_re, self->r_out_re_in_m2, self->m2_resid_re_prev,
|
||||
self->out_ch_count, (self->dir_sig_count + self->decor_sig_count), self,
|
||||
1);
|
||||
if (err < 0) return err;
|
||||
}
|
||||
|
||||
if (complex_m2 && !phase_interpolation) {
|
||||
err = ixheaacd_mps_upmix_interp_type2(
|
||||
self->m2_resid_im, self->r_out_im_in_m2, self->m2_resid_im_prev,
|
||||
self->out_ch_count, self, 0);
|
||||
if (err < 0) return err;
|
||||
}
|
||||
|
||||
if (phase_interpolation) {
|
||||
ixheaacd_mps_phase_interpolation(
|
||||
self->phase_l, self->phase_r, self->phase_l_prev, self->phase_r_prev,
|
||||
self->r_out_ph_re_in_m2, self->r_out_ph_im_in_m2, self);
|
||||
|
||||
if (self->res_bands == 0) {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
WORD32 pb;
|
||||
for (pb = 0; pb < self->bs_param_bands; pb++) {
|
||||
self->r_out_im_in_m2[ts][pb][0][0] =
|
||||
self->r_out_re_in_m2[ts][pb][0][0] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_im_in_m2[ts][pb][1][0] =
|
||||
self->r_out_re_in_m2[ts][pb][1][0] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][0][0] =
|
||||
self->r_out_re_in_m2[ts][pb][0][0] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][1][0] =
|
||||
self->r_out_re_in_m2[ts][pb][1][0] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_diff_im_in_m2[ts][pb][0][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_diff_im_in_m2[ts][pb][1][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_diff_re_in_m2[ts][pb][0][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_diff_re_in_m2[ts][pb][1][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][1];
|
||||
}
|
||||
}
|
||||
} else if (self->res_bands == 28) {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
WORD32 pb;
|
||||
for (pb = 0; pb < self->bs_param_bands; pb++) {
|
||||
self->r_out_im_in_m2[ts][pb][0][0] =
|
||||
self->r_out_re_in_m2[ts][pb][0][0] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_im_in_m2[ts][pb][0][1] =
|
||||
self->r_out_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_im_in_m2[ts][pb][1][0] =
|
||||
self->r_out_re_in_m2[ts][pb][1][0] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_im_in_m2[ts][pb][1][1] =
|
||||
self->r_out_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][0][0] =
|
||||
self->r_out_re_in_m2[ts][pb][0][0] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][0][1] =
|
||||
self->r_out_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][1][0] =
|
||||
self->r_out_re_in_m2[ts][pb][1][0] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][1][1] =
|
||||
self->r_out_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][1];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
WORD32 pb;
|
||||
for (pb = 0; pb < self->bs_param_bands; pb++) {
|
||||
self->r_out_im_in_m2[ts][pb][0][0] =
|
||||
self->r_out_re_in_m2[ts][pb][0][0] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_im_in_m2[ts][pb][0][1] =
|
||||
self->r_out_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_im_in_m2[ts][pb][1][0] =
|
||||
self->r_out_re_in_m2[ts][pb][1][0] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_im_in_m2[ts][pb][1][1] =
|
||||
self->r_out_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][0][0] =
|
||||
self->r_out_re_in_m2[ts][pb][0][0] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][0][1] =
|
||||
self->r_out_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][1][0] =
|
||||
self->r_out_re_in_m2[ts][pb][1][0] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_re_in_m2[ts][pb][1][1] =
|
||||
self->r_out_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_diff_im_in_m2[ts][pb][0][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_diff_im_in_m2[ts][pb][1][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_im_in_m2[ts][pb][1];
|
||||
|
||||
self->r_out_diff_re_in_m2[ts][pb][0][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][0][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][0];
|
||||
|
||||
self->r_out_diff_re_in_m2[ts][pb][1][1] =
|
||||
self->r_out_diff_re_in_m2[ts][pb][1][1] *
|
||||
self->r_out_ph_re_in_m2[ts][pb][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self->res_bands == 0) {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < self->hyb_band_count[0]; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
self->hyb_dir_out[row][ts][qs].re =
|
||||
self->w_dir[0][ts][qs].re *
|
||||
self->r_out_re_in_m2[ts][indx][row][0];
|
||||
self->hyb_dir_out[row][ts][qs].im =
|
||||
self->w_dir[0][ts][qs].im *
|
||||
self->r_out_re_in_m2[ts][indx][row][0];
|
||||
self->hyb_diff_out[row][ts][qs].re =
|
||||
self->w_diff[1][ts][qs].re *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
self->hyb_diff_out[row][ts][qs].im =
|
||||
self->w_diff[1][ts][qs].im *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (self->res_bands == 28) {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < self->hyb_band_count[1]; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
FLOAT32 sum_re_dir = 0;
|
||||
FLOAT32 sum_im_dir = 0;
|
||||
for (col = 0; col < num_col_iters; col++) {
|
||||
sum_re_dir += self->w_dir[col][ts][qs].re *
|
||||
self->r_out_re_in_m2[ts][indx][row][col];
|
||||
sum_im_dir += self->w_dir[col][ts][qs].im *
|
||||
self->r_out_re_in_m2[ts][indx][row][col];
|
||||
}
|
||||
self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
|
||||
self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
|
||||
}
|
||||
}
|
||||
for (; qs < self->hyb_band_count[0]; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
self->hyb_dir_out[row][ts][qs].re =
|
||||
self->w_dir[0][ts][qs].re *
|
||||
self->r_out_re_in_m2[ts][indx][row][0];
|
||||
self->hyb_dir_out[row][ts][qs].im =
|
||||
self->w_dir[0][ts][qs].im *
|
||||
self->r_out_re_in_m2[ts][indx][row][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WORD32 dif_s = ixheaacd_mps_gain_set_indx[self->res_bands];
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < dif_s; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
FLOAT32 sum_re_dir = 0;
|
||||
FLOAT32 sum_im_dir = 0;
|
||||
for (col = 0; col < num_col_iters; col++) {
|
||||
sum_re_dir += self->w_dir[col][ts][qs].re *
|
||||
self->r_out_re_in_m2[ts][indx][row][col];
|
||||
sum_im_dir += self->w_dir[col][ts][qs].im *
|
||||
self->r_out_re_in_m2[ts][indx][row][col];
|
||||
}
|
||||
self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
|
||||
self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
|
||||
}
|
||||
}
|
||||
for (; qs < self->hyb_band_count[1]; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
FLOAT32 sum_re_dir = 0;
|
||||
FLOAT32 sum_im_dir = 0;
|
||||
for (col = 0; col < num_col_iters; col++) {
|
||||
sum_re_dir += self->w_dir[col][ts][qs].re *
|
||||
self->r_out_re_in_m2[ts][indx][row][col];
|
||||
sum_im_dir += self->w_dir[col][ts][qs].im *
|
||||
self->r_out_re_in_m2[ts][indx][row][col];
|
||||
}
|
||||
self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
|
||||
self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
|
||||
self->hyb_diff_out[row][ts][qs].re =
|
||||
self->w_diff[1][ts][qs].re *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
self->hyb_diff_out[row][ts][qs].im =
|
||||
self->w_diff[1][ts][qs].im *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
}
|
||||
}
|
||||
for (; qs < self->hyb_band_count[0]; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
self->hyb_dir_out[row][ts][qs].re =
|
||||
self->w_dir[0][ts][qs].re *
|
||||
self->r_out_re_in_m2[ts][indx][row][0];
|
||||
self->hyb_dir_out[row][ts][qs].im =
|
||||
self->w_dir[0][ts][qs].im *
|
||||
self->r_out_re_in_m2[ts][indx][row][0];
|
||||
self->hyb_diff_out[row][ts][qs].re =
|
||||
self->w_diff[1][ts][qs].re *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
self->hyb_diff_out[row][ts][qs].im =
|
||||
self->w_diff[1][ts][qs].im *
|
||||
self->r_out_diff_re_in_m2[ts][indx][row][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (complex_m2) {
|
||||
if (phase_interpolation) {
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < 2; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
|
||||
FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
|
||||
for (col = 0; col < num_col_iters; col++) {
|
||||
sum_re_dir += self->w_dir[col][ts][qs].im *
|
||||
self->r_out_im_in_m2[ts][indx][row][col];
|
||||
sum_im_dir -= self->w_dir[col][ts][qs].re *
|
||||
self->r_out_im_in_m2[ts][indx][row][col];
|
||||
}
|
||||
self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
|
||||
self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
|
||||
self->hyb_diff_out[row][ts][qs].re +=
|
||||
self->w_diff[1][ts][qs].im *
|
||||
self->r_out_diff_im_in_m2[ts][indx][row][1];
|
||||
self->hyb_diff_out[row][ts][qs].im -=
|
||||
self->w_diff[1][ts][qs].re *
|
||||
self->r_out_diff_im_in_m2[ts][indx][row][1];
|
||||
}
|
||||
}
|
||||
for (qs = 2; qs < self->hyb_band_count_max; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
|
||||
FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
|
||||
for (col = 0; col < num_col_iters; col++) {
|
||||
sum_re_dir -= self->w_dir[col][ts][qs].im *
|
||||
self->r_out_im_in_m2[ts][indx][row][col];
|
||||
sum_im_dir += self->w_dir[col][ts][qs].re *
|
||||
self->r_out_im_in_m2[ts][indx][row][col];
|
||||
}
|
||||
self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
|
||||
self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
|
||||
self->hyb_diff_out[row][ts][qs].re -=
|
||||
self->w_diff[1][ts][qs].im *
|
||||
self->r_out_diff_im_in_m2[ts][indx][row][1];
|
||||
self->hyb_diff_out[row][ts][qs].im +=
|
||||
self->w_diff[1][ts][qs].re *
|
||||
self->r_out_diff_im_in_m2[ts][indx][row][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int num_cols = (self->dir_sig_count + self->decor_sig_count) > 1
|
||||
? 1
|
||||
: (self->dir_sig_count + self->decor_sig_count);
|
||||
for (ts = 0; ts < self->time_slots; ts++) {
|
||||
for (qs = 0; qs < 2; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
|
||||
FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
|
||||
if (num_cols > 0) {
|
||||
sum_re_dir += self->w_dir[0][ts][qs].im *
|
||||
self->r_out_im_in_m2[ts][indx][row][0];
|
||||
sum_im_dir -= self->w_dir[0][ts][qs].re *
|
||||
self->r_out_im_in_m2[ts][indx][row][0];
|
||||
}
|
||||
self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
|
||||
self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
|
||||
}
|
||||
}
|
||||
for (qs = 2; qs < self->hyb_band_count_max; qs++) {
|
||||
WORD32 indx = self->hyb_band_to_processing_band_table[qs];
|
||||
for (row = 0; row < self->out_ch_count; row++) {
|
||||
FLOAT32 sum_re_dir = self->hyb_dir_out[row][ts][qs].re;
|
||||
FLOAT32 sum_im_dir = self->hyb_dir_out[row][ts][qs].im;
|
||||
if (num_cols > 0) {
|
||||
sum_re_dir -= self->w_dir[0][ts][qs].im *
|
||||
self->r_out_im_in_m2[ts][indx][row][0];
|
||||
sum_im_dir += self->w_dir[0][ts][qs].re *
|
||||
self->r_out_im_in_m2[ts][indx][row][0];
|
||||
}
|
||||
self->hyb_dir_out[row][ts][qs].re = sum_re_dir;
|
||||
self->hyb_dir_out[row][ts][qs].im = sum_im_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WORD32 ixheaacd_mps_upmix_interp_type1(
|
||||
FLOAT32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
[MAX_M_INPUT],
|
||||
FLOAT32 r_matrix_float[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
|
|
@ -642,6 +1055,53 @@ WORD32 ixheaacd_mps_upmix_interp(
|
|||
return 0;
|
||||
}
|
||||
|
||||
WORD32 ixheaacd_mps_upmix_interp_type2(
|
||||
FLOAT32 m_matrix[MAX_PARAMETER_SETS_MPS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
[MAX_M_INPUT],
|
||||
FLOAT32 r_matrix_float[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS][MAX_M_OUTPUT]
|
||||
[MAX_M_INPUT],
|
||||
FLOAT32 m_matrix_prev[MAX_PARAMETER_BANDS][MAX_M_OUTPUT][MAX_M_INPUT],
|
||||
WORD32 num_rows, ia_mps_dec_state_struct *self, WORD32 col) {
|
||||
WORD32 ts, ps, pb, row, i;
|
||||
FLOAT32 ks, ms, ls;
|
||||
FLOAT32 fl_step, fl_base;
|
||||
|
||||
if (MAX_TIME_SLOTS < (self->param_slot_diff[0])) return -1;
|
||||
|
||||
for (pb = 0; pb < self->bs_param_bands; pb++) {
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
ts = 0;
|
||||
ps = 0;
|
||||
ks = self->inv_param_slot_diff[ps];
|
||||
ms = m_matrix[ps][pb][row][col];
|
||||
ls = m_matrix_prev[pb][row][col];
|
||||
fl_step = ks * (ms - ls);
|
||||
fl_base = ls + fl_step;
|
||||
|
||||
for (i = 1; i <= (WORD32)self->param_slot_diff[0]; i++) {
|
||||
r_matrix_float[ts][pb][row][col] = fl_base;
|
||||
fl_base += fl_step;
|
||||
ts++;
|
||||
}
|
||||
for (ps = 1; ps < self->num_parameter_sets; ps++) {
|
||||
if (MAX_TIME_SLOTS < (ts + self->param_slot_diff[ps])) return -1;
|
||||
ks = self->inv_param_slot_diff[ps];
|
||||
ms = m_matrix[ps][pb][row][col];
|
||||
ls = m_matrix[ps - 1][pb][row][col];
|
||||
fl_step = ks * (ms - ls);
|
||||
fl_base = ls + fl_step;
|
||||
|
||||
for (i = 1; i <= (WORD32)self->param_slot_diff[ps]; i++) {
|
||||
r_matrix_float[ts][pb][row][col] = fl_base;
|
||||
fl_base += fl_step;
|
||||
ts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FLOAT32 ixheaacd_mps_angle_interpolation(FLOAT32 angle1, FLOAT32 angle2,
|
||||
FLOAT32 alpha, FLOAT32 *step) {
|
||||
while (angle2 - angle1 > (FLOAT32)P_PI)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
VOID ixheaacd_mps_res_buf_copy(ia_mps_dec_state_struct* self);
|
||||
VOID ixheaacd_mps_qmf_hyb_analysis(ia_mps_dec_state_struct* self);
|
||||
VOID ixheaacd_mps_qmf_hyb_analysis_no_pre_mix(ia_mps_dec_state_struct* self);
|
||||
VOID ixheaacd_mps_qmf_hyb_synthesis(ia_mps_dec_state_struct* self);
|
||||
VOID ixheaacd_mps_decor(ia_mps_dec_state_struct* self);
|
||||
VOID ixheaacd_mps_create_w(ia_mps_dec_state_struct* self);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ VOID ixheaacd_mps_pre_matrix_mix_matrix_smoothing(
|
|||
int ps = 0, pb, row, col;
|
||||
int res_bands = 0;
|
||||
int *p_smoothing_data;
|
||||
|
||||
self->pre_mix_req = 0;
|
||||
if (self->residual_coding) res_bands = self->max_res_bands;
|
||||
|
||||
p_smoothing_data = &self->smoothing_data[ps][res_bands];
|
||||
|
|
@ -72,6 +72,7 @@ VOID ixheaacd_mps_pre_matrix_mix_matrix_smoothing(
|
|||
MULT(one_minus_delta, self->m2_resid_im_prev[pb][row][col]));
|
||||
}
|
||||
}
|
||||
self->pre_mix_req++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +113,7 @@ VOID ixheaacd_mps_pre_matrix_mix_matrix_smoothing(
|
|||
self->m2_resid_im[ps - 1][pb][row][col]));
|
||||
}
|
||||
}
|
||||
self->pre_mix_req++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,14 +83,26 @@ static VOID ixheaacd_mps_est_normalized_envelope(ia_mps_dec_state_struct *self,
|
|||
break;
|
||||
case DOWNMIX_IN:
|
||||
ch_offset = self->out_ch_count;
|
||||
for (ii = 0; ii < self->time_slots; ii++) {
|
||||
for (jj = 0; jj < self->hyb_band_count_max; jj++) {
|
||||
slot_energy[ii]
|
||||
[ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] +=
|
||||
self->hyb_in[ch][ii][jj].re * self->hyb_in[ch][ii][jj].re +
|
||||
self->hyb_in[ch][ii][jj].im * self->hyb_in[ch][ii][jj].im;
|
||||
if ((self->pre_mix_req | self->bs_tsd_enable)) {
|
||||
for (ii = 0; ii < self->time_slots; ii++) {
|
||||
for (jj = 0; jj < self->hyb_band_count_max; jj++) {
|
||||
slot_energy
|
||||
[ii][ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] +=
|
||||
self->hyb_in[ch][jj][ii].re * self->hyb_in[ch][jj][ii].re +
|
||||
self->hyb_in[ch][jj][ii].im * self->hyb_in[ch][jj][ii].im;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ii = 0; ii < self->time_slots; ii++) {
|
||||
for (jj = 0; jj < self->hyb_band_count_max; jj++) {
|
||||
slot_energy
|
||||
[ii][ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] +=
|
||||
self->w_dir[ch][ii][jj].re * self->w_dir[ch][ii][jj].re +
|
||||
self->w_dir[ch][ii][jj].im * self->w_dir[ch][ii][jj].im;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ch_offset = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue