988 lines
34 KiB
C
988 lines
34 KiB
C
/******************************************************************************
|
|
* *
|
|
* Copyright (C) 2018 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_sbr_common.h"
|
|
#include "ixheaacd_type_def.h"
|
|
|
|
#include "ixheaacd_constants.h"
|
|
#include "ixheaacd_basic_ops32.h"
|
|
#include "ixheaacd_basic_ops16.h"
|
|
#include "ixheaacd_basic_ops40.h"
|
|
#include "ixheaacd_basic_ops.h"
|
|
|
|
#include "ixheaacd_intrinsics.h"
|
|
#include "ixheaacd_common_rom.h"
|
|
#include "ixheaacd_bitbuffer.h"
|
|
#include "ixheaacd_sbrdecsettings.h"
|
|
#include "ixheaacd_sbr_scale.h"
|
|
#include "ixheaacd_lpp_tran.h"
|
|
#include "ixheaacd_env_extr_part.h"
|
|
#include "ixheaacd_sbr_rom.h"
|
|
#include "ixheaacd_hybrid.h"
|
|
#include "ixheaacd_ps_dec.h"
|
|
#include "ixheaacd_env_extr.h"
|
|
#include "ixheaacd_qmf_dec.h"
|
|
|
|
#include "ixheaacd_basic_op.h"
|
|
#include "ixheaacd_env_calc.h"
|
|
|
|
#include "ixheaacd_interface.h"
|
|
|
|
#include "ixheaacd_function_selector.h"
|
|
#include "ixheaacd_audioobjtypes.h"
|
|
|
|
#define DCT3_LEN (32)
|
|
#define DCT2_LEN (64)
|
|
|
|
#define LP_SHIFT_VAL 7
|
|
#define HQ_SHIFT_64 4
|
|
#define RADIXSHIFT 1
|
|
#define ROUNDING_SPECTRA 1
|
|
#define HQ_SHIFT_VAL 4
|
|
|
|
static PLATFORM_INLINE WORD32 ixheaacd_mult32x32in32_shift25(WORD32 a,
|
|
WORD32 b) {
|
|
WORD32 result;
|
|
WORD64 temp_result;
|
|
|
|
temp_result = (WORD64)a * (WORD64)b;
|
|
|
|
result = (WORD32)(temp_result >> 25);
|
|
|
|
return (result);
|
|
}
|
|
|
|
VOID ixheaacd_pretwdct2(WORD32 *inp, WORD32 *out_fwd) {
|
|
WORD32 n;
|
|
WORD32 *out_rev = out_fwd + DCT2_LEN - 1;
|
|
|
|
for (n = 0; n < DCT2_LEN / 2; n++) {
|
|
*out_fwd = *inp;
|
|
inp++;
|
|
*out_rev = *inp;
|
|
out_fwd++;
|
|
|
|
out_rev--;
|
|
inp++;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static PLATFORM_INLINE VOID ixheaacd_pretwdct2_32(WORD32 *inp, WORD32 *out_fwd,
|
|
int dct2_len) {
|
|
WORD32 n;
|
|
|
|
WORD32 *out_rev = out_fwd + dct2_len - 1;
|
|
for (n = dct2_len / 2 - 1; n >= 0; n--) {
|
|
*out_fwd = *inp;
|
|
inp++;
|
|
*out_rev = *inp;
|
|
out_fwd++;
|
|
|
|
out_rev--;
|
|
inp++;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID ixheaacd_fftposttw(WORD32 *out,
|
|
ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
|
|
int k;
|
|
WORD32 *p_out_fwd, *ptr_out_rev;
|
|
const WORD16 *twidle_fwd, *twidle_rev;
|
|
WORD32 in1, in2, val1, val2;
|
|
|
|
twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 1;
|
|
twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 15;
|
|
|
|
p_out_fwd = out;
|
|
ptr_out_rev = out + DCT2_LEN - 1;
|
|
|
|
in1 = ((*p_out_fwd++) << 1);
|
|
val1 = ((*p_out_fwd--) << 1);
|
|
|
|
*p_out_fwd++ = in1;
|
|
*p_out_fwd++ = val1;
|
|
|
|
for (k = 1; k <= DCT2_LEN / 4; k++) {
|
|
WORD32 temp[4];
|
|
WORD16 twid_re, twid_im;
|
|
|
|
temp[0] = *p_out_fwd++;
|
|
temp[1] = *p_out_fwd--;
|
|
temp[3] = *ptr_out_rev--;
|
|
temp[2] = *ptr_out_rev++;
|
|
|
|
in2 = ixheaacd_sub32_sat(temp[3], temp[1]);
|
|
in1 = ixheaacd_add32_sat(temp[3], temp[1]);
|
|
|
|
temp[1] = ixheaacd_sub32_sat(temp[0], temp[2]);
|
|
temp[3] = ixheaacd_add32_sat(temp[0], temp[2]);
|
|
|
|
twid_re = *twidle_fwd++;
|
|
twid_im = *twidle_rev--;
|
|
val1 = ixheaacd_mult32x16in32(in1, twid_re) -
|
|
ixheaacd_mult32x16in32(temp[1], twid_im);
|
|
val2 = ixheaacd_mult32x16in32(temp[1], twid_re) +
|
|
ixheaacd_mult32x16in32(in1, twid_im);
|
|
val1 = val1 << 1;
|
|
val2 = val2 << 1;
|
|
|
|
*p_out_fwd++ = ixheaacd_add32_sat(temp[3], val1);
|
|
*p_out_fwd++ = ixheaacd_add32_sat(in2, val2);
|
|
|
|
*ptr_out_rev-- = ixheaacd_sub32_sat(val2, in2);
|
|
*ptr_out_rev-- = ixheaacd_sub32_sat(temp[3], val1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID ixheaacd_posttwdct2(WORD32 *inp, WORD16 *out_fwd,
|
|
ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
|
|
WORD32 k;
|
|
WORD32 inp_re, inp_im, out_re, out_im, last_val, out_re1;
|
|
WORD16 *out_fwd2, *out_rev2, *out_rev;
|
|
WORD16 twid_re, twid_im;
|
|
const WORD16 *twidle_fwd;
|
|
WORD16 re1, im1, im2;
|
|
|
|
out_rev = out_fwd + DCT2_LEN - 1;
|
|
out_rev2 = out_fwd - 1;
|
|
out_fwd2 = out_fwd + 65;
|
|
out_re = *inp++;
|
|
out_im = *inp++;
|
|
out_re1 =
|
|
ixheaacd_sat64_32(ixheaacd_add64((WORD64)out_re, (WORD64)out_im) >> 1);
|
|
re1 = ixheaacd_round16(ixheaacd_shl32(out_re1, (5 - 1)));
|
|
|
|
*out_fwd++ = re1;
|
|
|
|
last_val = ixheaacd_sub32_sat(out_re, out_im);
|
|
|
|
twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 2;
|
|
for (k = DCT2_LEN / 2 - 2; k >= 0; k--) {
|
|
inp_re = *inp++;
|
|
inp_im = *inp++;
|
|
|
|
twid_re = *twidle_fwd++;
|
|
twid_im = *twidle_fwd++;
|
|
out_re = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(inp_re, twid_re),
|
|
ixheaacd_mult32x16in32(inp_im, twid_im));
|
|
out_im = ixheaacd_add32_sat(ixheaacd_mult32x16in32(inp_im, twid_re),
|
|
ixheaacd_mult32x16in32(inp_re, twid_im));
|
|
re1 = ixheaacd_round16(ixheaacd_shl32(out_re, (5 - 1)));
|
|
im1 = ixheaacd_round16(ixheaacd_shl32(out_im, (5 - 1)));
|
|
im2 = ixheaacd_negate16(im1);
|
|
|
|
*out_fwd++ = re1;
|
|
*out_rev2-- = re1;
|
|
*out_rev-- = im1;
|
|
*out_fwd2++ = im2;
|
|
}
|
|
twid_re = *twidle_fwd++;
|
|
|
|
out_re = ixheaacd_mult32x16in32(last_val, twid_re);
|
|
re1 = ixheaacd_round16(ixheaacd_shl32(out_re, (5 - 1)));
|
|
|
|
*out_fwd++ = re1;
|
|
*out_rev2-- = re1;
|
|
|
|
return;
|
|
}
|
|
|
|
static PLATFORM_INLINE VOID ixheaacd_fftposttw_32(
|
|
WORD32 *out, int dct2_len, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
|
|
int k;
|
|
WORD32 *ptr_out_fwd, *ptr_out_rev;
|
|
const WORD16 *twidle_fwd, *twidle_rev;
|
|
WORD32 in1, in2, val1, val2;
|
|
|
|
twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 2;
|
|
twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 14;
|
|
|
|
ptr_out_fwd = out;
|
|
ptr_out_rev = out + dct2_len - 1;
|
|
|
|
in1 = ((*ptr_out_fwd++) << 1);
|
|
val1 = ((*ptr_out_fwd--) << 1);
|
|
|
|
*ptr_out_fwd++ = in1;
|
|
*ptr_out_fwd++ = val1;
|
|
|
|
for (k = dct2_len / 4 - 1; k >= 0; k--) {
|
|
WORD32 temp0, temp1, temp2, temp3;
|
|
WORD16 twid_re, twid_im;
|
|
|
|
temp0 = *ptr_out_fwd++;
|
|
temp1 = *ptr_out_fwd--;
|
|
temp3 = *ptr_out_rev--;
|
|
temp2 = *ptr_out_rev++;
|
|
|
|
in1 = ixheaacd_add32_sat(temp1, temp3);
|
|
in2 = ixheaacd_sub32_sat(temp3, temp1);
|
|
|
|
temp1 = ixheaacd_sub32_sat(temp0, temp2);
|
|
temp3 = ixheaacd_add32_sat(temp0, temp2);
|
|
|
|
twid_re = *twidle_fwd;
|
|
twidle_fwd += 2;
|
|
|
|
twid_im = *twidle_rev;
|
|
twidle_rev -= 2;
|
|
|
|
val1 = ixheaacd_mult32x16in32(in1, twid_re) -
|
|
ixheaacd_mult32x16in32(temp1, twid_im);
|
|
val2 = ixheaacd_mult32x16in32(temp1, twid_re) +
|
|
ixheaacd_mult32x16in32(in1, twid_im);
|
|
|
|
val1 = val1 << 1;
|
|
val2 = val2 << 1;
|
|
|
|
*ptr_out_fwd++ = ixheaacd_add32_sat(temp3, val1);
|
|
*ptr_out_fwd++ = ixheaacd_add32_sat(in2, val2);
|
|
|
|
*ptr_out_rev-- = ixheaacd_sub32_sat(val2, in2);
|
|
*ptr_out_rev-- = ixheaacd_sub32_sat(temp3, val1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static PLATFORM_INLINE VOID
|
|
ixheaacd_posttwdct2_32(WORD32 *inp, WORD16 *out_fwd,
|
|
ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
|
|
int k;
|
|
WORD32 inp_re, out_re, out_im, last_val, out_re1;
|
|
WORD16 *out_rev, *out_rev2, *out_fwd2;
|
|
WORD16 twid_re, twid_im;
|
|
const WORD16 *twidle_fwd;
|
|
WORD16 re1, im1, im2;
|
|
WORD32 rounding_fac = 0x8000;
|
|
|
|
out_rev = out_fwd + 32 - 1;
|
|
out_rev2 = out_fwd - 1;
|
|
out_fwd2 = out_fwd + 32 + 1;
|
|
out_fwd[32] = 0;
|
|
|
|
out_re = *inp++;
|
|
out_im = *inp++;
|
|
|
|
out_re1 =
|
|
ixheaacd_sat64_32(ixheaacd_add64((WORD64)out_re, (WORD64)out_im) >> 1);
|
|
re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re1, (5 - 1)));
|
|
*out_fwd++ = re1;
|
|
last_val = ixheaacd_sub32_sat(out_re, out_im);
|
|
|
|
twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 4;
|
|
for (k = 14; k >= 0; k--) {
|
|
WORD32 temp1, temp2;
|
|
inp_re = *inp++;
|
|
twid_re = *twidle_fwd++;
|
|
twid_im = *twidle_fwd;
|
|
twidle_fwd += 3;
|
|
|
|
temp1 = ixheaacd_mult32x16in32(inp_re, twid_re);
|
|
temp2 = ixheaacd_mult32x16in32(inp_re, twid_im);
|
|
|
|
inp_re = *inp++;
|
|
|
|
out_re = ixheaacd_sub32_sat(temp1, ixheaacd_mult32x16in32(inp_re, twid_im));
|
|
out_im = ixheaacd_add32_sat(ixheaacd_mult32x16in32(inp_re, twid_re), temp2);
|
|
|
|
out_re = ixheaacd_add32_sat(out_re, out_re);
|
|
out_im = ixheaacd_add32_sat(out_im, out_im);
|
|
out_re = ixheaacd_add32_sat(out_re, out_re);
|
|
out_im = ixheaacd_add32_sat(out_im, out_im);
|
|
out_re = ixheaacd_add32_sat(out_re, out_re);
|
|
out_im = ixheaacd_add32_sat(out_im, out_im);
|
|
out_re = ixheaacd_add32_sat(out_re, out_re);
|
|
out_im = ixheaacd_add32_sat(out_im, out_im);
|
|
out_re = ixheaacd_add32_sat(out_re, rounding_fac);
|
|
out_im = ixheaacd_add32_sat(out_im, rounding_fac);
|
|
re1 = (out_re >> 16);
|
|
im1 = (out_im >> 16);
|
|
im2 = ixheaacd_negate16(im1);
|
|
|
|
*out_fwd++ = re1;
|
|
*out_rev2-- = re1;
|
|
*out_rev-- = im1;
|
|
*out_fwd2++ = im2;
|
|
}
|
|
twid_re = *twidle_fwd++;
|
|
|
|
out_re = ixheaacd_mult32x16in32(last_val, twid_re);
|
|
re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re, (5 - 1)));
|
|
*out_fwd++ = re1;
|
|
*out_rev2-- = re1;
|
|
|
|
return;
|
|
}
|
|
|
|
VOID ixheaacd_dct2_32(WORD32 *inp, WORD32 *out,
|
|
ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
|
|
WORD16 *filter_states) {
|
|
WORD32 *output;
|
|
|
|
output = out + 16;
|
|
filter_states = filter_states + 16;
|
|
ixheaacd_pretwdct2_32(inp, output, 32);
|
|
|
|
ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_16, output, 1, 4);
|
|
ixheaacd_postradixcompute4(inp, output, qmf_dec_tables_ptr->dig_rev_table4_16,
|
|
16);
|
|
ixheaacd_fftposttw_32(inp, 32, qmf_dec_tables_ptr);
|
|
|
|
ixheaacd_posttwdct2_32(inp, filter_states, qmf_dec_tables_ptr);
|
|
|
|
return;
|
|
}
|
|
|
|
VOID ixheaacd_sbr_qmfanal32_winadd_eld(WORD16 *inp1, WORD16 *inp2,
|
|
WORD16 *p_qmf1, WORD16 *p_qmf2,
|
|
WORD32 *p_out) {
|
|
WORD32 n;
|
|
|
|
for (n = 0; n < 32; n += 2) {
|
|
WORD32 accu;
|
|
accu = ixheaacd_mult16x16in32(inp1[n + 0], p_qmf1[(n + 0)]);
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 64], p_qmf1[(n + 64)]));
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 128], p_qmf1[(n + 128)]));
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 192], p_qmf1[(n + 192)]));
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 256], p_qmf1[(n + 256)]));
|
|
p_out[n] = accu;
|
|
|
|
accu = ixheaacd_mult16x16in32(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]);
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 1 + 64], p_qmf1[(n + 1 + 64)]));
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 1 + 128], p_qmf1[(n + 1 + 128)]));
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 1 + 192], p_qmf1[(n + 1 + 192)]));
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp1[n + 1 + 256], p_qmf1[(n + 1 + 256)]));
|
|
p_out[n + 1] = accu;
|
|
|
|
accu = ixheaacd_mult16x16in32(inp2[n + 0], p_qmf2[(n + 0)]);
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 64], p_qmf2[(n + 64)]));
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 128], p_qmf2[(n + 128)]));
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 192], p_qmf2[(n + 192)]));
|
|
accu = ixheaacd_add32(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 256], p_qmf2[(n + 256)]));
|
|
p_out[n + 32] = accu;
|
|
|
|
accu = ixheaacd_mult16x16in32(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]);
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 1 + 64], p_qmf2[(n + 1 + 64)]));
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 1 + 128], p_qmf2[(n + 1 + 128)]));
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 1 + 192], p_qmf2[(n + 1 + 192)]));
|
|
accu = ixheaacd_add32_sat(
|
|
accu, ixheaacd_mult16x16in32(inp2[n + 1 + 256], p_qmf2[(n + 1 + 256)]));
|
|
p_out[n + 1 + 32] = accu;
|
|
}
|
|
}
|
|
|
|
VOID ixheaacd_esbr_qmfanal32_winadd(WORD32 *inp1, WORD32 *inp2, WORD32 *p_qmf1,
|
|
WORD32 *p_qmf2, WORD32 *p_out,
|
|
WORD32 num_band_anal_qmf) {
|
|
WORD32 n;
|
|
WORD64 accu;
|
|
|
|
if (num_band_anal_qmf == 32) {
|
|
for (n = 0; n < num_band_anal_qmf; n += 2) {
|
|
accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[2 * (n + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 8 * num_band_anal_qmf)]));
|
|
p_out[n] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[2 * (n + 1 + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 1 + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 1 + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 1 + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
|
|
p_qmf1[2 * (n + 1 + 8 * num_band_anal_qmf)]));
|
|
p_out[n + 1] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[2 * (n + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 8 * num_band_anal_qmf)]));
|
|
p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[2 * (n + 1 + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 1 + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 1 + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 1 + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
|
|
p_qmf2[2 * (n + 1 + 8 * num_band_anal_qmf)]));
|
|
p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
|
|
}
|
|
} else if (num_band_anal_qmf == 24) {
|
|
for (n = 0; n < num_band_anal_qmf; n += 2) {
|
|
accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[(n + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf],
|
|
p_qmf1[(n + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf],
|
|
p_qmf1[(n + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf],
|
|
p_qmf1[(n + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf],
|
|
p_qmf1[(n + 8 * num_band_anal_qmf)]));
|
|
p_out[n] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
|
|
p_qmf1[(n + 1 + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
|
|
p_qmf1[(n + 1 + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
|
|
p_qmf1[(n + 1 + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
|
|
p_qmf1[(n + 1 + 8 * num_band_anal_qmf)]));
|
|
p_out[n + 1] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[(n + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf],
|
|
p_qmf2[(n + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf],
|
|
p_qmf2[(n + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf],
|
|
p_qmf2[(n + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf],
|
|
p_qmf2[(n + 8 * num_band_anal_qmf)]));
|
|
p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
|
|
p_qmf2[(n + 1 + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
|
|
p_qmf2[(n + 1 + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
|
|
p_qmf2[(n + 1 + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
|
|
p_qmf2[(n + 1 + 8 * num_band_anal_qmf)]));
|
|
p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
|
|
}
|
|
|
|
} else {
|
|
for (n = 0; n < num_band_anal_qmf; n += 2) {
|
|
accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[4 * (n + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 8 * num_band_anal_qmf)]));
|
|
p_out[n] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[4 * (n + 1 + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 1 + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 1 + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 1 + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
|
|
p_qmf1[4 * (n + 1 + 8 * num_band_anal_qmf)]));
|
|
p_out[n + 1] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[4 * (n + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 8 * num_band_anal_qmf)]));
|
|
p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
|
|
|
|
accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[4 * (n + 1 + 0)]);
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 1 + 2 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 1 + 4 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 1 + 6 * num_band_anal_qmf)]));
|
|
accu = ixheaacd_add64(
|
|
accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
|
|
p_qmf2[4 * (n + 1 + 8 * num_band_anal_qmf)]));
|
|
p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID ixheaacd_esbr_inv_modulation(
|
|
WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf,
|
|
ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
|
|
ixheaacd_esbr_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->esbr_w_32,
|
|
qmf_dec_tables_ptr->dig_rev_table2_32);
|
|
}
|
|
|
|
VOID ixheaacd_sbr_qmfsyn32_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1,
|
|
WORD16 *sample_buffer, FLAG shift,
|
|
WORD32 ch_fac) {
|
|
WORD32 k;
|
|
WORD32 rounding_fac = 0x8000;
|
|
rounding_fac = rounding_fac >> shift;
|
|
|
|
for (k = 0; k < 32; k++) {
|
|
WORD32 syn_out = rounding_fac;
|
|
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp1[0 + k], inp1[2 * (k + 0)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp1[128 + k], inp1[2 * (k + 64)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp1[256 + k], inp1[2 * (k + 128)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp1[384 + k], inp1[2 * (k + 192)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp1[512 + k], inp1[2 * (k + 256)]));
|
|
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp2[64 + k], inp1[2 * (k + 32)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp2[192 + k], inp1[2 * (k + 96)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp2[320 + k], inp1[2 * (k + 160)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp2[448 + k], inp1[2 * (k + 224)]));
|
|
syn_out = ixheaacd_add32(
|
|
syn_out, ixheaacd_mult16x16in32(tmp2[576 + k], inp1[2 * (k + 288)]));
|
|
syn_out = ixheaacd_add32_sat(syn_out, syn_out);
|
|
if (shift == 2) {
|
|
syn_out = ixheaacd_add32_sat(syn_out, syn_out);
|
|
}
|
|
sample_buffer[ch_fac * k] = (syn_out >> 16);
|
|
}
|
|
}
|
|
|
|
void ixheaacd_sbr_pre_twiddle(WORD32 *p_xre, WORD32 *p_xim,
|
|
WORD16 *p_twiddles) {
|
|
int k;
|
|
|
|
for (k = 62; k >= 0; k--) {
|
|
WORD32 x_re = *p_xre;
|
|
WORD32 x_im = *p_xim;
|
|
|
|
WORD16 ixheaacd_cosine = *p_twiddles++;
|
|
WORD16 ixheaacd_sine = *p_twiddles++;
|
|
|
|
WORD32 re, im;
|
|
|
|
re = ixheaacd_mac32x16in32_shl_sat(
|
|
ixheaacd_mult32x16in32_shl(x_re, ixheaacd_cosine), x_im, ixheaacd_sine);
|
|
im = ixheaacd_sub32_sat(ixheaacd_mult32x16in32_shl(x_im, ixheaacd_cosine),
|
|
ixheaacd_mult32x16in32_shl(x_re, ixheaacd_sine));
|
|
|
|
*p_xre++ = re;
|
|
*p_xim++ = im;
|
|
}
|
|
}
|
|
|
|
VOID ixheaacd_cplx_synt_qmffilt(
|
|
WORD32 **qmf_real, WORD32 **qmf_imag, WORD32 split,
|
|
ia_sbr_scale_fact_struct *sbr_scale_factor, WORD16 *time_out,
|
|
ia_sbr_qmf_filter_bank_struct *qmf_bank, ia_ps_dec_struct *ptr_ps_dec,
|
|
FLAG active, FLAG low_pow_flag, ia_sbr_tables_struct *sbr_tables_ptr,
|
|
ixheaacd_misc_tables *pstr_common_tables, WORD32 ch_fac, FLAG drc_on,
|
|
WORD32 drc_sbr_factors[][64], WORD32 audio_object_type) {
|
|
WORD32 i;
|
|
|
|
WORD32 code_scale_factor;
|
|
WORD32 scale_factor;
|
|
WORD32 out_scale_factor;
|
|
WORD32 low_band_scale_factor;
|
|
WORD32 high_band_scale_factor;
|
|
WORD16 *filter_states = qmf_bank->filter_states;
|
|
WORD32 **ptr_qmf_imag_temp;
|
|
WORD32 qmf_real2[2 * NO_SYNTHESIS_CHANNELS];
|
|
|
|
WORD32 no_synthesis_channels = qmf_bank->no_channels;
|
|
WORD32 p1;
|
|
|
|
WORD16 *fp1;
|
|
WORD16 *fp2;
|
|
|
|
WORD32 sixty4 = NO_SYNTHESIS_CHANNELS;
|
|
WORD32 thirty2 = qmf_bank->no_channels;
|
|
|
|
WORD16 *filter_coeff;
|
|
WORD32 num_time_slots = qmf_bank->num_time_slots;
|
|
WORD32 ixheaacd_drc_offset;
|
|
WORD32 ov_lb_scale = sbr_scale_factor->ov_lb_scale;
|
|
WORD32 lb_scale = sbr_scale_factor->lb_scale;
|
|
WORD32 st_syn_scale = sbr_scale_factor->st_syn_scale;
|
|
WORD32 ov_lb_shift, lb_shift, hb_shift;
|
|
|
|
WORD32 *qmf_real_tmp = qmf_real2;
|
|
WORD32 *qmf_imag_tmp = &qmf_real2[NO_SYNTHESIS_CHANNELS];
|
|
WORD32 env = 0;
|
|
|
|
WORD32 common_shift;
|
|
|
|
if (no_synthesis_channels == 32) {
|
|
qmf_bank->cos_twiddle =
|
|
(WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32;
|
|
qmf_bank->alt_sin_twiddle =
|
|
(WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32;
|
|
qmf_bank->t_cos =
|
|
(WORD16 *)
|
|
sbr_tables_ptr->qmf_dec_tables_ptr->sbr_cos_sin_twiddle_ds_l32;
|
|
} else {
|
|
qmf_bank->cos_twiddle =
|
|
(WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l64;
|
|
qmf_bank->alt_sin_twiddle =
|
|
(WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l64;
|
|
}
|
|
if (audio_object_type != AOT_ER_AAC_ELD &&
|
|
audio_object_type != AOT_ER_AAC_LD) {
|
|
qmf_bank->filter_pos_syn +=
|
|
(sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c - qmf_bank->p_filter);
|
|
qmf_bank->p_filter = sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c;
|
|
} else {
|
|
qmf_bank->filter_pos_syn +=
|
|
(sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c_eld - qmf_bank->p_filter);
|
|
qmf_bank->p_filter = sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c_eld;
|
|
}
|
|
|
|
fp1 = &filter_states[0];
|
|
fp2 = fp1 + no_synthesis_channels;
|
|
|
|
if (audio_object_type == AOT_ER_AAC_ELD ||
|
|
audio_object_type == AOT_ER_AAC_LD) {
|
|
fp1 = qmf_bank->fp1_syn;
|
|
fp2 = qmf_bank->fp2_syn;
|
|
sixty4 = qmf_bank->sixty4;
|
|
}
|
|
|
|
filter_coeff = qmf_bank->filter_pos_syn;
|
|
|
|
if (active) {
|
|
code_scale_factor = scale_factor = sbr_scale_factor->ps_scale;
|
|
} else {
|
|
code_scale_factor = ixheaacd_min32(lb_scale, ov_lb_scale);
|
|
scale_factor = sbr_scale_factor->hb_scale;
|
|
}
|
|
|
|
low_band_scale_factor = (st_syn_scale - code_scale_factor);
|
|
high_band_scale_factor = (st_syn_scale - scale_factor);
|
|
|
|
p1 = 0;
|
|
|
|
if (low_pow_flag)
|
|
|
|
{
|
|
ov_lb_shift = (st_syn_scale - ov_lb_scale) - 4;
|
|
lb_shift = (st_syn_scale - lb_scale) - 4;
|
|
hb_shift = high_band_scale_factor - 4;
|
|
out_scale_factor = -((sbr_scale_factor->st_syn_scale - 1));
|
|
ptr_qmf_imag_temp = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
out_scale_factor = -((sbr_scale_factor->st_syn_scale - 3));
|
|
if (active) {
|
|
ov_lb_shift = (sbr_scale_factor->ps_scale - ov_lb_scale);
|
|
lb_shift = (sbr_scale_factor->ps_scale - lb_scale);
|
|
hb_shift = (sbr_scale_factor->ps_scale - sbr_scale_factor->hb_scale);
|
|
common_shift = low_band_scale_factor - 8;
|
|
|
|
} else {
|
|
if (audio_object_type != AOT_ER_AAC_ELD &&
|
|
audio_object_type != AOT_ER_AAC_LD) {
|
|
ov_lb_shift = (st_syn_scale - ov_lb_scale) - 8;
|
|
lb_shift = (st_syn_scale - lb_scale) - 8;
|
|
hb_shift = high_band_scale_factor - 8;
|
|
} else {
|
|
ov_lb_shift = (st_syn_scale - ov_lb_scale) - 7;
|
|
lb_shift = (st_syn_scale - lb_scale) - 7;
|
|
hb_shift = high_band_scale_factor - 7;
|
|
}
|
|
common_shift = 0;
|
|
}
|
|
ptr_qmf_imag_temp = qmf_imag;
|
|
}
|
|
|
|
{
|
|
if (ov_lb_shift == lb_shift) {
|
|
(*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb, 0,
|
|
num_time_slots, ov_lb_shift, low_pow_flag);
|
|
|
|
} else {
|
|
(*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb, 0,
|
|
split, ov_lb_shift, low_pow_flag);
|
|
|
|
(*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb,
|
|
split, num_time_slots, lb_shift, low_pow_flag);
|
|
}
|
|
|
|
(*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, qmf_bank->lsb,
|
|
qmf_bank->usb, 0, num_time_slots, hb_shift,
|
|
low_pow_flag);
|
|
}
|
|
|
|
ixheaacd_drc_offset = qmf_bank->ixheaacd_drc_offset;
|
|
|
|
if (1 == drc_on) {
|
|
for (i = 0; i < num_time_slots; i++) {
|
|
WORD32 loop_val;
|
|
for (loop_val = 0; loop_val < 64; loop_val++) {
|
|
qmf_real[i][loop_val] = ixheaacd_mult32x32in32_shift25(
|
|
qmf_real[i][loop_val], drc_sbr_factors[6 + i][loop_val]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (low_pow_flag)
|
|
|
|
{
|
|
WORD16 *fptemp;
|
|
|
|
VOID(*sbr_qmf_syn_winadd)
|
|
(WORD16 *, WORD16 *, WORD16 *, WORD16 *, FLAG, WORD32);
|
|
ia_qmf_dec_tables_struct *qmf_tab_ptr = sbr_tables_ptr->qmf_dec_tables_ptr;
|
|
|
|
if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED)
|
|
sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn32_winadd;
|
|
else
|
|
sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn64_winadd;
|
|
|
|
for (i = 0; i < num_time_slots; i++) {
|
|
ixheaacd_inv_modulation_lp(qmf_real[i],
|
|
&filter_states[ixheaacd_drc_offset], qmf_bank,
|
|
qmf_tab_ptr);
|
|
|
|
sbr_qmf_syn_winadd(fp1, fp2, filter_coeff, &time_out[ch_fac * p1], 2,
|
|
ch_fac);
|
|
|
|
ixheaacd_drc_offset -= no_synthesis_channels << 1;
|
|
|
|
if (ixheaacd_drc_offset < 0)
|
|
ixheaacd_drc_offset += ((no_synthesis_channels << 1) * 10);
|
|
|
|
fptemp = fp1;
|
|
fp1 = fp2;
|
|
fp2 = fptemp;
|
|
|
|
filter_coeff += 64;
|
|
|
|
if (filter_coeff == qmf_bank->p_filter + 640)
|
|
filter_coeff = (WORD16 *)qmf_bank->p_filter;
|
|
|
|
p1 += no_synthesis_channels;
|
|
}
|
|
|
|
} else {
|
|
for (i = 0; i < num_time_slots; i++) {
|
|
WORD32 *t_qmf_imag;
|
|
t_qmf_imag = qmf_imag[i];
|
|
|
|
if (active) {
|
|
if (i == ptr_ps_dec->border_position[env]) {
|
|
ixheaacd_init_rot_env(ptr_ps_dec, (WORD16)env, qmf_bank->usb,
|
|
sbr_tables_ptr, pstr_common_tables->trig_data);
|
|
env++;
|
|
}
|
|
|
|
ixheaacd_apply_ps(ptr_ps_dec, &qmf_real[i], &qmf_imag[i], qmf_real_tmp,
|
|
qmf_imag_tmp, sbr_scale_factor, (WORD16)i,
|
|
sbr_tables_ptr);
|
|
}
|
|
if (1 == drc_on) {
|
|
WORD32 loop_val;
|
|
for (loop_val = 0; loop_val < 64; loop_val++) {
|
|
qmf_real[i][loop_val] = ixheaacd_mult32x32in32_shift25(
|
|
qmf_real[i][loop_val], drc_sbr_factors[6 + i][loop_val]);
|
|
}
|
|
}
|
|
|
|
if (active) {
|
|
if (common_shift)
|
|
ixheaacd_shiftrountine(qmf_real[i], t_qmf_imag, no_synthesis_channels,
|
|
common_shift);
|
|
}
|
|
|
|
if (audio_object_type == AOT_ER_AAC_ELD ||
|
|
audio_object_type == AOT_ER_AAC_LD)
|
|
ixheaacd_sbr_pre_twiddle(
|
|
qmf_real[i], t_qmf_imag,
|
|
sbr_tables_ptr->qmf_dec_tables_ptr->ixheaacd_sbr_synth_cos_sin_l32);
|
|
|
|
ixheaacd_inv_emodulation(qmf_real[i], qmf_bank,
|
|
sbr_tables_ptr->qmf_dec_tables_ptr);
|
|
|
|
{
|
|
WORD32 temp_out_scale_fac = out_scale_factor + 1;
|
|
if (audio_object_type == AOT_ER_AAC_LD ||
|
|
audio_object_type == AOT_ER_AAC_ELD) {
|
|
temp_out_scale_fac = temp_out_scale_fac - 1;
|
|
|
|
ixheaacd_shiftrountine_with_rnd_eld(
|
|
qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset],
|
|
no_synthesis_channels, temp_out_scale_fac);
|
|
|
|
}
|
|
|
|
else {
|
|
ixheaacd_shiftrountine_with_rnd(
|
|
qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset],
|
|
no_synthesis_channels, temp_out_scale_fac);
|
|
}
|
|
}
|
|
|
|
if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED) {
|
|
WORD32 temp = 1;
|
|
if (audio_object_type == AOT_ER_AAC_LD ||
|
|
audio_object_type == AOT_ER_AAC_ELD) {
|
|
temp = 2;
|
|
}
|
|
ixheaacd_sbr_qmfsyn32_winadd(fp1, fp2, filter_coeff,
|
|
&time_out[ch_fac * p1], temp, ch_fac);
|
|
|
|
fp1 += thirty2;
|
|
fp2 -= thirty2;
|
|
thirty2 = -thirty2;
|
|
|
|
ixheaacd_drc_offset -= 64;
|
|
|
|
if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 640;
|
|
|
|
} else {
|
|
WORD32 temp = 1;
|
|
if (audio_object_type == AOT_ER_AAC_LD ||
|
|
audio_object_type == AOT_ER_AAC_ELD) {
|
|
temp = 2;
|
|
}
|
|
ixheaacd_sbr_qmfsyn64_winadd(fp1, fp2, filter_coeff,
|
|
&time_out[ch_fac * p1], temp, ch_fac);
|
|
|
|
fp1 += sixty4;
|
|
fp2 -= sixty4;
|
|
sixty4 = -sixty4;
|
|
ixheaacd_drc_offset -= 128;
|
|
|
|
if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 1280;
|
|
}
|
|
|
|
filter_coeff += 64;
|
|
|
|
if (filter_coeff == qmf_bank->p_filter + 640)
|
|
filter_coeff = (WORD16 *)qmf_bank->p_filter;
|
|
|
|
p1 += no_synthesis_channels;
|
|
|
|
if (active)
|
|
memcpy(qmf_real[i], qmf_real_tmp,
|
|
2 * no_synthesis_channels * sizeof(WORD32));
|
|
}
|
|
}
|
|
|
|
if (audio_object_type == AOT_ER_AAC_LD ||
|
|
audio_object_type == AOT_ER_AAC_ELD) {
|
|
qmf_bank->fp1_syn = fp1;
|
|
qmf_bank->fp2_syn = fp2;
|
|
qmf_bank->sixty4 = sixty4;
|
|
}
|
|
|
|
qmf_bank->filter_pos_syn = filter_coeff;
|
|
qmf_bank->ixheaacd_drc_offset = ixheaacd_drc_offset;
|
|
}
|