From 8eb646f89b94cf6d0aa26e5bca39ba083a554965 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Wed, 9 May 2018 14:23:00 -0700 Subject: [PATCH] Collected Cleanups from Ittiam Test: CTS android.media.cts.DecoderTest{AacDrc,XheAac} Added __ARM_NEON__ check to generic function selector Bug: 80432407 Change-Id: I66c7879fda1369da88ccaea5f8792ea54657cdaf Added support to build for mips Bug: 80432286 Change-Id: I908029bbaddd3c1fbc39be1192926b56d981576e Add optimized versions for qmf_dec for armv7 and armv8 Separating common functions and platform specific functions in ixheaacd_qmf_dec.c. Platform specific functions are moved to qmf_dec in armv7, armv8 and generic folder. Bug: 80431870 Change-Id: I860cb79a1870e228d2108b7915418e1c003cefc5 Fixes for crashes reported by Fuzzer tool Bug: 109697676 Change-Id: I862fc054b99ee9d427d20596bc8d2e85522a7188 --- Android.bp | 32 +- decoder/armv7/ixheaacd_qmf_dec.c | 1282 ------------ decoder/armv7/ixheaacd_qmf_dec_armv7.c | 355 ++++ decoder/armv8/ixheaacd_qmf_dec_armv8.c | 1349 ++++++++++++ .../ixheaacd_function_selector_generic.c | 6 +- .../ixheaacd_qmf_dec_generic.c} | 1449 ++++--------- decoder/ixheaacd_acelp_decode.c | 4 +- decoder/ixheaacd_arith_dec.c | 16 +- decoder/ixheaacd_avq_dec.c | 5 +- decoder/ixheaacd_basic_ops40.h | 12 + decoder/ixheaacd_bitbuffer.h | 1 + decoder/ixheaacd_common_initfuncs.c | 4 + decoder/ixheaacd_config.h | 2 +- decoder/ixheaacd_create.c | 3 + decoder/ixheaacd_decode_main.c | 10 +- decoder/ixheaacd_env_extr.c | 22 +- decoder/ixheaacd_env_extr.h | 2 +- decoder/ixheaacd_esbr_polyphase.c | 20 +- decoder/ixheaacd_hbe_trans.c | 15 +- decoder/ixheaacd_headerdecode.c | 2 +- decoder/ixheaacd_init_config.c | 11 +- decoder/ixheaacd_lpc.c | 13 +- decoder/ixheaacd_process.c | 23 +- decoder/ixheaacd_qmf_dec.c | 1841 +---------------- decoder/ixheaacd_qmf_dec.h | 39 + decoder/ixheaacd_qmf_poly.h | 4 +- decoder/ixheaacd_sbr_dec.c | 12 +- decoder/ixheaacd_sbr_dec.h | 8 +- decoder/ixheaacd_sbrdec_lpfuncs.c | 10 +- decoder/ixheaacd_sbrdecoder.c | 23 +- decoder/ixheaacd_sbrqmftrans.h | 4 +- decoder/ixheaacd_spectrum_dec.c | 5 + decoder/ixheaacd_ver_number.h | 6 +- 33 files changed, 2427 insertions(+), 4163 deletions(-) delete mode 100644 decoder/armv7/ixheaacd_qmf_dec.c create mode 100644 decoder/armv7/ixheaacd_qmf_dec_armv7.c create mode 100644 decoder/armv8/ixheaacd_qmf_dec_armv8.c rename decoder/{armv8/ixheaacd_qmf_dec.c => generic/ixheaacd_qmf_dec_generic.c} (54%) diff --git a/Android.bp b/Android.bp index dfb86d0..6f1d23c 100644 --- a/Android.bp +++ b/Android.bp @@ -101,6 +101,7 @@ cc_library_static { "decoder/ixheaacd_mps_poly_filt.c", "decoder/ixheaacd_huff_code_reorder.c", "decoder/ixheaacd_rev_vlc.c", + "decoder/ixheaacd_qmf_dec.c", "decoder/drc_src/impd_drc_api.c", "decoder/drc_src/impd_drc_bitbuffer.c", "decoder/drc_src/impd_drc_dec.c", @@ -129,8 +130,6 @@ cc_library_static { "decoder/drc_src/impd_drc_selection_process_init.c", "decoder/drc_src/impd_drc_shape_filter.c", "decoder/drc_src/impd_drc_static_payload.c", - - "decoder/ixheaacd_qmf_dec.c", ], sanitize: { @@ -148,6 +147,7 @@ cc_library_static { srcs: [ "decoder/generic/ixheaacd_function_selector_generic.c", + "decoder/generic/ixheaacd_qmf_dec_generic.c", ], neon: { cflags: [ @@ -158,6 +158,7 @@ cc_library_static { ], srcs: [ + "decoder/armv7/ixheaacd_qmf_dec_armv7.c", "decoder/armv7/ixheaacd_fft_armv7.c", "decoder/armv7/ixheaacd_function_selector_armv7.c", "decoder/armv7/ixheaacd_overlap_add1.s", @@ -231,6 +232,7 @@ cc_library_static { ], srcs: [ + "decoder/armv8/ixheaacd_qmf_dec_armv8.c", "decoder/armv8/ixheaacd_function_selector_armv8.c", "decoder/armv8/ixheaacd_calcmaxspectralline.s", "decoder/armv8/ixheaacd_sbr_imdct_using_fft.s", @@ -262,6 +264,7 @@ cc_library_static { ], srcs: [ + "decoder/generic/ixheaacd_qmf_dec_generic.c", "decoder/x86/ixheaacd_function_selector_x86.c", ], }, @@ -274,9 +277,34 @@ cc_library_static { ], srcs: [ + "decoder/generic/ixheaacd_qmf_dec_generic.c", "decoder/x86_64/ixheaacd_function_selector_x86_64.c", ], }, + + mips: { + cflags: [ + ], + + local_include_dirs: [ + ], + + srcs: [ + "decoder/generic/ixheaacd_function_selector_generic.c", + ], + }, + + mips64: { + cflags: [ + ], + + local_include_dirs: [ + ], + + srcs: [ + "decoder/generic/ixheaacd_function_selector_generic.c", + ], + }, }, } diff --git a/decoder/armv7/ixheaacd_qmf_dec.c b/decoder/armv7/ixheaacd_qmf_dec.c deleted file mode 100644 index ca45ca8..0000000 --- a/decoder/armv7/ixheaacd_qmf_dec.c +++ /dev/null @@ -1,1282 +0,0 @@ -/****************************************************************************** - * * - * 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 - -#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 -#include "ixheaacd_env_calc.h" - -#include "ixheaacd_interface.h" - -#include "ixheaacd_function_selector.h" -#include "ixheaacd_audioobjtypes.h" - -#define mult16x16_16(a, b) ixheaacd_mult16((a), (b)) -#define mac16x16(a, b, c) ixheaacd_mac16x16in32((a), (b), (c)) -#define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b)) -#define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b)) -#define mpy_32x32(a, b) ixheaacd_mult32((a), (b)) -#define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b)) -#define msu16x16(a, b, c) msu16x16in32((a), (b), (c)) - -#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); -} - -static PLATFORM_INLINE 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; -} - -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 = temp[3] - temp[1]; - in1 = temp[3] + temp[1]; - - temp[1] = temp[0] - temp[2]; - temp[3] = temp[0] + temp[2]; - - twid_re = *twidle_fwd++; - twid_im = *twidle_rev--; - val1 = msu32x16in32_dual(in1, twid_re, temp[1], twid_im); - val2 = mac32x16in32_dual(temp[1], twid_re, in1, twid_im); - val1 = val1 << 1; - val2 = val2 << 1; - - *p_out_fwd++ = temp[3] + val1; - *p_out_fwd++ = in2 + val2; - - *ptr_out_rev-- = -in2 + val2; - *ptr_out_rev-- = 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 = (out_re + out_im) >> 1; - re1 = ixheaacd_round16(ixheaacd_shl32(out_re1, (5 - 1))); - - *out_fwd++ = re1; - - last_val = (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 = msu32x16in32_dual(inp_re, twid_re, inp_im, twid_im); - out_im = mac32x16in32_dual(inp_im, twid_re, 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; -} - -VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, - WORD16 *filter_states) { - ixheaacd_pretwdct2(x, X); - - ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x, - qmf_dec_tables_ptr->dig_rev_table2_128, - qmf_dec_tables_ptr->dig_rev_table2_128, - qmf_dec_tables_ptr->dig_rev_table2_128, - qmf_dec_tables_ptr->dig_rev_table2_128); - - ixheaacd_fftposttw(x, qmf_dec_tables_ptr); - - ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr); - - 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; -} - -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 = temp1 + temp3; - in2 = -temp1 + temp3; - - temp1 = temp0 - temp2; - temp3 = 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++ = temp3 + val1; - *ptr_out_fwd++ = in2 + val2; - - *ptr_out_rev-- = -in2 + val2; - *ptr_out_rev-- = 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 = (out_re + out_im) >> 1; - re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re1, (5 - 1))); - *out_fwd++ = re1; - last_val = (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(temp1, ixheaacd_mult32x16in32(inp_re, twid_im)); - out_im = ixheaacd_add32(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; - } -} - -#define HQ_SHIFT_VAL 4 - -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_cplx_anal_qmffilt(const WORD16 *time_sample_buf, - ia_sbr_scale_fact_struct *sbr_scale_factor, - WORD32 **qmf_real, WORD32 **qmf_imag, - ia_sbr_qmf_filter_bank_struct *qmf_bank, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, - WORD32 ch_fac, WORD32 low_pow_flag, - WORD audio_object_type) { - WORD32 i, k; - WORD32 num_time_slots = qmf_bank->num_time_slots; - - WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS]; - WORD16 *filter_states = qmf_bank->core_samples_buffer; - - WORD16 *fp1, *fp2, *tmp; - - WORD16 *filter_1; - WORD16 *filter_2; - WORD16 *filt_ptr; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - qmf_bank->filter_pos += - (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff); - qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c; - } else { - qmf_bank->filter_pos += - (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff); - qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3; - } - - filter_1 = qmf_bank->filter_pos; - - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - filter_2 = filter_1 + 64; - } else { - filter_2 = filter_1 + 32; - } - - sbr_scale_factor->st_lb_scale = 0; - sbr_scale_factor->lb_scale = -10; - if (!low_pow_flag) { - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - sbr_scale_factor->lb_scale = -8; - } else { - sbr_scale_factor->lb_scale = -9; - } - qmf_bank->cos_twiddle = - (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32; - qmf_bank->alt_sin_twiddle = - (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32; - } else { - qmf_bank->t_cos = - (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld; - } - } - - fp1 = qmf_bank->anal_filter_states; - fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS; - - if (audio_object_type == AOT_ER_AAC_ELD || - audio_object_type == AOT_ER_AAC_LD) { - filter_2 = qmf_bank->filter_2; - fp1 = qmf_bank->fp1_anal; - fp2 = qmf_bank->fp2_anal; - } - - for (i = 0; i < num_time_slots; i++) { - for (k = 0; k < NO_ANALYSIS_CHANNELS; k++) - filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k]; - - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2, - analysis_buffer, filter_states, - time_sample_buf, ch_fac); - } else { - ixheaacd_sbr_qmfanal32_winadds_eld(fp1, fp2, filter_1, filter_2, - analysis_buffer, filter_states, - time_sample_buf, ch_fac); - } - - time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac; - - filter_states -= NO_ANALYSIS_CHANNELS; - if (filter_states < qmf_bank->anal_filter_states) { - filter_states = qmf_bank->anal_filter_states + 288; - } - - tmp = fp1; - fp1 = fp2; - fp2 = tmp; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - filter_1 += 64; - filter_2 += 64; - } else { - filter_1 += 32; - filter_2 += 32; - } - - filt_ptr = filter_1; - filter_1 = filter_2; - filter_2 = filt_ptr; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - if (filter_2 > (qmf_bank->analy_win_coeff + 640)) { - filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; - filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64; - } - } else { - if (filter_2 > (qmf_bank->analy_win_coeff + 320)) { - filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; - filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32; - } - } - - if (!low_pow_flag) { - ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i], - qmf_bank, qmf_dec_tables_ptr); - } else { - ixheaacd_dct3_32( - (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw, - qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16, - qmf_dec_tables_ptr->dig_rev_table4_16); - } - } - - qmf_bank->filter_pos = filter_1; - qmf_bank->core_samples_buffer = filter_states; - - if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD) - - { - qmf_bank->fp1_anal = fp1; - qmf_bank->fp2_anal = fp2; - qmf_bank->filter_2 = filter_2; - } -} - -static PLATFORM_INLINE VOID -ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, - ia_sbr_qmf_filter_bank_struct *syn_qmf, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { - WORD32 L = syn_qmf->no_channels; - const WORD32 M = (L >> 1); - WORD32 *dct_in = qmf_real; - WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS]; - - WORD32 ui_rem = ((WORD32)(&time_out[0]) % 8); - WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem); - - if (L == 64) - ixheaacd_dec_DCT2_64_asm(dct_in, ptime_out, qmf_dec_tables_ptr->w1024, - qmf_dec_tables_ptr->dig_rev_table2_128, - qmf_dec_tables_ptr->post_fft_tbl, - qmf_dec_tables_ptr->dct23_tw, filter_states + M); - else - ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states); - - filter_states[3 * M] = 0; -} - -static VOID ixheaacd_inv_emodulation( - WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { - ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024, - (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128); -} - -#define HQ_SHIFT_64 4 -#define RADIXSHIFT 1 -VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, - ia_sbr_qmf_filter_bank_struct *qmf_bank, - WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) { - WORD32 z; - WORD32 temp[128]; - WORD32 scaleshift = 0; - - WORD32 M_2; - WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); - - const WORD32 *p_sin; - const WORD32 *p_sin_cos; - - WORD32 subband_tmp[128]; - - p_sin_cos = qmf_bank->esbr_cos_twiddle; - ixheaacd_esbr_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp); - - M_2 = ixheaacd_shr32(M, 1); - if (M == 32) { - ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8); - ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2); - ixheaacd_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32); - - ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8); - ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2); - ixheaacd_postradixcompute2(&subband[64], &subband_tmp[64], p_dig_rev_tbl, - 32); - - } - - else if (M == 16) { - ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4); - ixheaacd_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16); - - ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4); - ixheaacd_postradixcompute4(&subband[64], &subband_tmp[64], p_dig_rev_tbl, - 16); - - } - - else if (M == 12) { - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[2 * z]; - temp[12 + z] = subband_tmp[2 * z + 1]; - } - - ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[2 * z] = temp[z]; - subband[2 * z + 1] = temp[z + 12]; - } - scaleshift = 0; - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[64 + 2 * z]; - temp[12 + z] = subband_tmp[64 + 2 * z + 1]; - } - - ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[64 + 2 * z] = temp[z]; - subband[64 + 2 * z + 1] = temp[z + 12]; - } - - } - - else { - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[2 * z]; - temp[8 + z] = subband_tmp[2 * z + 1]; - } - - (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[2 * z] = temp[z] << scaleshift; - subband[2 * z + 1] = temp[z + 8] << scaleshift; - } - scaleshift = 0; - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[64 + 2 * z]; - temp[8 + z] = subband_tmp[64 + 2 * z + 1]; - } - - (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[64 + 2 * z] = temp[z] << scaleshift; - subband[64 + 2 * z + 1] = temp[8 + z] << scaleshift; - } - } - p_sin = qmf_bank->esbr_alt_sin_twiddle; - ixheaacd_esbr_cos_sin_mod_loop2(subband, p_sin, M); -} - -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_qmfsyn64_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1, - WORD16 *sample_buffer, FLAG shift, - WORD32 ch_fac); - -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 *pXre, WORD32 *pXim, WORD16 *pTwiddles) { - int k; - - for (k = 62; k >= 0; k--) { - WORD32 Xre = *pXre; - WORD32 Xim = *pXim; - - WORD16 ixheaacd_cosine = *pTwiddles++; - WORD16 ixheaacd_sine = *pTwiddles++; - - WORD32 re, im; - - re = ixheaacd_mac32x16in32_shl( - ixheaacd_mult32x16in32_shl(Xre, ixheaacd_cosine), Xim, ixheaacd_sine); - im = ixheaacd_sub32(ixheaacd_mult32x16in32_shl(Xim, ixheaacd_cosine), - ixheaacd_mult32x16in32_shl(Xre, ixheaacd_sine)); - - *pXre++ = re; - *pXim++ = 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; -} diff --git a/decoder/armv7/ixheaacd_qmf_dec_armv7.c b/decoder/armv7/ixheaacd_qmf_dec_armv7.c new file mode 100644 index 0000000..d75de06 --- /dev/null +++ b/decoder/armv7/ixheaacd_qmf_dec_armv7.c @@ -0,0 +1,355 @@ +/****************************************************************************** + * * + * 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 + +#include "ixheaacd_sbr_common.h" +#include + +#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 +#include "ixheaacd_env_calc.h" + +#include "ixheaacd_interface.h" + +#include "ixheaacd_function_selector.h" +#include "ixheaacd_audioobjtypes.h" + +#define mult16x16_16(a, b) ixheaacd_mult16((a), (b)) +#define mac16x16(a, b, c) ixheaacd_mac16x16in32((a), (b), (c)) +#define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b)) +#define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b)) +#define mpy_32x32(a, b) ixheaacd_mult32((a), (b)) +#define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b)) +#define msu16x16(a, b, c) msu16x16in32((a), (b), (c)) + +#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 + +VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, + WORD16 *filter_states) { + ixheaacd_pretwdct2(x, X); + + ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x, + qmf_dec_tables_ptr->dig_rev_table2_128, + qmf_dec_tables_ptr->dig_rev_table2_128, + qmf_dec_tables_ptr->dig_rev_table2_128, + qmf_dec_tables_ptr->dig_rev_table2_128); + + ixheaacd_fftposttw(x, qmf_dec_tables_ptr); + + ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr); + + return; +} + +VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf, + ia_sbr_scale_fact_struct *sbr_scale_factor, + WORD32 **qmf_real, WORD32 **qmf_imag, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, + WORD32 ch_fac, WORD32 low_pow_flag, + WORD audio_object_type) { + WORD32 i, k; + WORD32 num_time_slots = qmf_bank->num_time_slots; + + WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS]; + WORD16 *filter_states = qmf_bank->core_samples_buffer; + + WORD16 *fp1, *fp2, *tmp; + + WORD16 *filter_1; + WORD16 *filter_2; + WORD16 *filt_ptr; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + qmf_bank->filter_pos += + (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff); + qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c; + } else { + qmf_bank->filter_pos += + (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff); + qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3; + } + + filter_1 = qmf_bank->filter_pos; + + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + filter_2 = filter_1 + 64; + } else { + filter_2 = filter_1 + 32; + } + + sbr_scale_factor->st_lb_scale = 0; + sbr_scale_factor->lb_scale = -10; + if (!low_pow_flag) { + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + sbr_scale_factor->lb_scale = -8; + } else { + sbr_scale_factor->lb_scale = -9; + } + qmf_bank->cos_twiddle = + (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32; + qmf_bank->alt_sin_twiddle = + (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32; + } else { + qmf_bank->t_cos = + (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld; + } + } + + fp1 = qmf_bank->anal_filter_states; + fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS; + + if (audio_object_type == AOT_ER_AAC_ELD || + audio_object_type == AOT_ER_AAC_LD) { + filter_2 = qmf_bank->filter_2; + fp1 = qmf_bank->fp1_anal; + fp2 = qmf_bank->fp2_anal; + } + + for (i = 0; i < num_time_slots; i++) { + for (k = 0; k < NO_ANALYSIS_CHANNELS; k++) + filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k]; + + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2, + analysis_buffer, filter_states, + time_sample_buf, ch_fac); + } else { + ixheaacd_sbr_qmfanal32_winadds_eld(fp1, fp2, filter_1, filter_2, + analysis_buffer, filter_states, + time_sample_buf, ch_fac); + } + + time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac; + + filter_states -= NO_ANALYSIS_CHANNELS; + if (filter_states < qmf_bank->anal_filter_states) { + filter_states = qmf_bank->anal_filter_states + 288; + } + + tmp = fp1; + fp1 = fp2; + fp2 = tmp; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + filter_1 += 64; + filter_2 += 64; + } else { + filter_1 += 32; + filter_2 += 32; + } + + filt_ptr = filter_1; + filter_1 = filter_2; + filter_2 = filt_ptr; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + if (filter_2 > (qmf_bank->analy_win_coeff + 640)) { + filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; + filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64; + } + } else { + if (filter_2 > (qmf_bank->analy_win_coeff + 320)) { + filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; + filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32; + } + } + + if (!low_pow_flag) { + ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i], + qmf_bank, qmf_dec_tables_ptr); + } else { + ixheaacd_dct3_32( + (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw, + qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16, + qmf_dec_tables_ptr->dig_rev_table4_16); + } + } + + qmf_bank->filter_pos = filter_1; + qmf_bank->core_samples_buffer = filter_states; + + if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD) + + { + qmf_bank->fp1_anal = fp1; + qmf_bank->fp2_anal = fp2; + qmf_bank->filter_2 = filter_2; + } +} + +VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, + ia_sbr_qmf_filter_bank_struct *syn_qmf, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { + WORD32 L = syn_qmf->no_channels; + const WORD32 M = (L >> 1); + WORD32 *dct_in = qmf_real; + WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS]; + + WORD32 ui_rem = ((WORD32)(&time_out[0]) % 8); + WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem); + + if (L == 64) + ixheaacd_dec_DCT2_64_asm(dct_in, ptime_out, qmf_dec_tables_ptr->w1024, + qmf_dec_tables_ptr->dig_rev_table2_128, + qmf_dec_tables_ptr->post_fft_tbl, + qmf_dec_tables_ptr->dct23_tw, filter_states + M); + else + ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states); + + filter_states[3 * M] = 0; +} + +VOID ixheaacd_inv_emodulation( + WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { + ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024, + (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128); +} + +VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) { + WORD32 z; + WORD32 temp[128]; + WORD32 scaleshift = 0; + + WORD32 M_2; + WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); + + const WORD32 *p_sin; + const WORD32 *p_sin_cos; + + WORD32 subband_tmp[128]; + + p_sin_cos = qmf_bank->esbr_cos_twiddle; + ixheaacd_esbr_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp); + + M_2 = ixheaacd_shr32(M, 1); + if (M == 32) { + ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8); + ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2); + ixheaacd_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32); + + ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8); + ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2); + ixheaacd_postradixcompute2(&subband[64], &subband_tmp[64], p_dig_rev_tbl, + 32); + + } + + else if (M == 16) { + ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4); + ixheaacd_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16); + + ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4); + ixheaacd_postradixcompute4(&subband[64], &subband_tmp[64], p_dig_rev_tbl, + 16); + + } + + else if (M == 12) { + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[2 * z]; + temp[12 + z] = subband_tmp[2 * z + 1]; + } + + ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[2 * z] = temp[z]; + subband[2 * z + 1] = temp[z + 12]; + } + scaleshift = 0; + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[64 + 2 * z]; + temp[12 + z] = subband_tmp[64 + 2 * z + 1]; + } + + ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[64 + 2 * z] = temp[z]; + subband[64 + 2 * z + 1] = temp[z + 12]; + } + + } + + else { + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[2 * z]; + temp[8 + z] = subband_tmp[2 * z + 1]; + } + + (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[2 * z] = temp[z] << scaleshift; + subband[2 * z + 1] = temp[z + 8] << scaleshift; + } + scaleshift = 0; + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[64 + 2 * z]; + temp[8 + z] = subband_tmp[64 + 2 * z + 1]; + } + + (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[64 + 2 * z] = temp[z] << scaleshift; + subband[64 + 2 * z + 1] = temp[8 + z] << scaleshift; + } + } + p_sin = qmf_bank->esbr_alt_sin_twiddle; + ixheaacd_esbr_cos_sin_mod_loop2(subband, p_sin, M); +} + diff --git a/decoder/armv8/ixheaacd_qmf_dec_armv8.c b/decoder/armv8/ixheaacd_qmf_dec_armv8.c new file mode 100644 index 0000000..ac1a300 --- /dev/null +++ b/decoder/armv8/ixheaacd_qmf_dec_armv8.c @@ -0,0 +1,1349 @@ +/****************************************************************************** + * * + * 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 +#include "ixheaacd_sbr_common.h" +#include + +#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 +#include "ixheaacd_env_calc.h" + +#include "ixheaacd_interface.h" +#include "ixheaacd_function_selector.h" +#include "ixheaacd_audioobjtypes.h" + +#define mult16x16_16(a, b) ixheaacd_mult16((a), (b)) +#define mac16x16(a, b, c) ixheaacd_mac16x16in32((a), (b), (c)) +#define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b)) +#define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b)) +#define mpy_32x32(a, b) ixheaacd_mult32((a), (b)) +#define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b)) +#define msu16x16(a, b, c) msu16x16in32((a), (b), (c)) + +#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 + +VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, + const WORD16 *main_twidle_fwd, const WORD16 *post_tbl, + const WORD16 *w_16, const WORD32 *p_table) { + WORD32 n, k; + + WORD32 temp1[6]; + WORD32 temp2[4]; + WORD16 twid_re, twid_im; + WORD32 *ptr_reverse, *ptr_forward, *p_out, *ptr_out1; + const WORD16 *twidle_fwd, *twidle_rev; + + ptr_forward = &input[49]; + ptr_reverse = &input[47]; + + p_out = output; + twidle_fwd = main_twidle_fwd; + twidle_fwd += 4; + + *p_out++ = input[48] >> LP_SHIFT_VAL; + *p_out++ = 0; + + for (n = 1; n < DCT3_LEN / 2; n++) { + temp1[0] = *ptr_forward++; + temp1[1] = *ptr_reverse--; + temp1[0] = ixheaacd_add32(ixheaacd_shr32(temp1[0], LP_SHIFT_VAL), + ixheaacd_shr32(temp1[1], LP_SHIFT_VAL)); + + temp1[2] = *(ptr_forward - 33); + temp1[3] = *(ptr_reverse - 31); + temp1[1] = ixheaacd_sub32(ixheaacd_shr32(temp1[2], LP_SHIFT_VAL), + ixheaacd_shr32(temp1[3], LP_SHIFT_VAL)); + twid_re = *twidle_fwd++; + + twid_im = *twidle_fwd; + twidle_fwd += 3; + *p_out++ = mac32x16in32_dual(temp1[0], twid_re, temp1[1], twid_im); + *p_out++ = msu32x16in32_dual(temp1[0], twid_im, temp1[1], twid_re); + } + twid_re = *twidle_fwd++; + + twid_im = *twidle_fwd; + twidle_fwd += 3; + + temp1[1] = *ptr_reverse--; + temp1[0] = *(ptr_reverse - 31); + temp1[1] = ixheaacd_sub32(ixheaacd_shr32(temp1[1], LP_SHIFT_VAL), + ixheaacd_shr32(temp1[0], LP_SHIFT_VAL)); + + temp1[0] = temp1[1]; + + temp2[2] = mac32x16in32_dual(temp1[0], twid_re, temp1[1], twid_im); + temp2[3] = msu32x16in32_dual(temp1[0], twid_im, temp1[1], twid_re); + + ptr_forward = output; + ptr_reverse = &output[DCT3_LEN - 1]; + temp2[0] = *ptr_forward++; + temp2[1] = *ptr_forward--; + + temp1[0] = -temp2[1] - temp2[3]; + temp1[1] = temp2[0] - temp2[2]; + temp2[0] = (temp2[0] + temp2[2] + temp1[0]); + temp2[1] = (temp2[1] - temp2[3] + temp1[1]); + + temp2[0] >>= 1; + temp2[1] >>= 1; + + *ptr_forward++ = temp2[0]; + *ptr_forward++ = temp2[1]; + + twidle_fwd = post_tbl + 2; + twidle_rev = post_tbl + 14; + + for (n = 1; n < DCT3_LEN / 4; n++) { + temp2[0] = *ptr_forward++; + temp2[1] = *ptr_forward--; + temp2[3] = *ptr_reverse--; + temp2[2] = *ptr_reverse++; + + twid_re = *twidle_rev; + twidle_rev -= 2; + twid_im = *twidle_fwd; + twidle_fwd += 2; + + temp1[0] = temp2[0] - temp2[2]; + temp1[1] = (temp2[0] + temp2[2]); + + temp1[2] = temp2[1] + temp2[3]; + temp1[3] = (temp2[1] - temp2[3]); + temp1[4] = mac32x16in32_dual(temp1[0], twid_re, temp1[2], twid_im); + temp1[5] = msu32x16in32_dual(temp1[0], twid_im, temp1[2], twid_re); + + temp1[1] >>= 1; + temp1[3] >>= 1; + + *ptr_forward++ = temp1[1] - temp1[4]; + *ptr_forward++ = temp1[3] + temp1[5]; + + *ptr_reverse-- = -temp1[3] + temp1[5]; + *ptr_reverse-- = temp1[1] + temp1[4]; + } + temp2[0] = *ptr_forward++; + temp2[1] = *ptr_forward--; + temp2[3] = *ptr_reverse--; + temp2[2] = *ptr_reverse++; + + twid_re = *twidle_rev; + twidle_rev -= 2; + twid_im = *twidle_fwd; + twidle_fwd += 2; + + temp1[0] = temp2[0] - temp2[2]; + temp1[1] = (temp2[0] + temp2[2]); + + temp1[2] = temp2[1] + temp2[3]; + temp1[3] = (temp2[1] - temp2[3]); + + temp1[4] = -mac32x16in32_dual(temp1[0], twid_re, temp1[2], twid_im); + temp1[5] = msu32x16in32_dual(temp1[0], twid_im, temp1[2], twid_re); + + temp1[1] >>= 1; + temp1[3] >>= 1; + *ptr_forward++ = temp1[1] + temp1[4]; + *ptr_forward++ = temp1[3] + temp1[5]; + + ixheaacd_radix4bfly(w_16, output, 1, 4); + ixheaacd_postradixcompute4(input, output, p_table, 16); + + output[0] = input[0]; + output[2] = input[1]; + + p_out = input + 2; + ptr_forward = output + 1; + ptr_reverse = output + 30; + ptr_out1 = input + 18; + + for (k = (DCT3_LEN / 4) - 1; k != 0; k--) { + WORD32 tempre, tempim; + + tempre = *p_out++; + tempim = *p_out++; + *ptr_forward = (tempim); + ptr_forward += 2; + *ptr_forward = (tempre); + ptr_forward += 2; + + tempre = *ptr_out1++; + tempim = *ptr_out1++; + *ptr_reverse = (tempim); + ptr_reverse -= 2; + *ptr_reverse = (tempre); + ptr_reverse -= 2; + } + + { + WORD32 tempre, tempim; + tempre = *p_out++; + tempim = *p_out++; + *ptr_forward = (tempim); + ptr_forward += 2; + *ptr_forward = (tempre); + ptr_forward += 2; + } + + return; +} +VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, + WORD16 *filter_states) { + ixheaacd_pretwdct2(x, X); + + ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x, + qmf_dec_tables_ptr->dig_rev_table2_128, + qmf_dec_tables_ptr->dig_rev_table2_128, + qmf_dec_tables_ptr->dig_rev_table2_128, + qmf_dec_tables_ptr->dig_rev_table2_128); + + ixheaacd_fftposttw(x, qmf_dec_tables_ptr); + + ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr); + + return; +} + +VOID ixheaacd_cos_sin_mod(WORD32 *subband, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + WORD16 *p_twiddle, WORD32 *p_dig_rev_tbl) { + WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); + + const WORD16 *p_sin; + const WORD16 *p_sin_cos = &qmf_bank->cos_twiddle[0]; + WORD32 subband_tmp[128]; + + ixheaacd_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp); + + if (M == 32) { + ixheaacd_sbr_imdct_using_fft( + (const WORD32 *)p_twiddle, 32, subband_tmp, subband, + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + + ixheaacd_sbr_imdct_using_fft( + (const WORD32 *)p_twiddle, 32, &subband_tmp[64], &subband[64], + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + + } else { + ixheaacd_sbr_imdct_using_fft( + (const WORD32 *)p_twiddle, 16, subband_tmp, subband, + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + + ixheaacd_sbr_imdct_using_fft( + (const WORD32 *)p_twiddle, 16, &subband_tmp[64], &subband[64], + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, + (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + } + + p_sin = &qmf_bank->alt_sin_twiddle[0]; + ixheaacd_cos_sin_mod_loop2(subband, p_sin, M); +} + +VOID ixheaacd_fwd_modulation(const WORD32 *p_time_in1, WORD32 *real_subband, + WORD32 *imag_subband, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { + WORD32 i; + const WORD32 *p_time_in2 = &p_time_in1[2 * NO_ANALYSIS_CHANNELS - 1]; + WORD32 temp1, temp2; + WORD32 *t_real_subband = real_subband; + WORD32 *t_imag_subband = imag_subband; + const WORD16 *tcos; + + for (i = NO_ANALYSIS_CHANNELS - 1; i >= 0; i--) { + temp1 = ixheaacd_shr32(*p_time_in1++, HQ_SHIFT_VAL); + temp2 = ixheaacd_shr32(*p_time_in2--, HQ_SHIFT_VAL); + + *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2); + ; + *t_imag_subband++ = ixheaacd_add32(temp1, temp2); + ; + } + + ixheaacd_cos_sin_mod(real_subband, qmf_bank, + (WORD16 *)qmf_dec_tables_ptr->w1024, + (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128); + + tcos = qmf_bank->t_cos; + + for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) { + WORD16 cosh, sinh; + WORD32 re, im; + + re = *real_subband; + im = *imag_subband; + cosh = *tcos++; + sinh = *tcos++; + *real_subband++ = ixheaacd_add32(ixheaacd_mult32x16in32_shl(re, cosh), + ixheaacd_mult32x16in32_shl(im, sinh)); + *imag_subband++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32_shl(im, cosh), + ixheaacd_mult32x16in32_shl(re, sinh)); + } +} + +VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf, + ia_sbr_scale_fact_struct *sbr_scale_factor, + WORD32 **qmf_real, WORD32 **qmf_imag, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, + WORD32 ch_fac, WORD32 low_pow_flag, + WORD audio_object_type) { + WORD32 i, k; + WORD32 num_time_slots = qmf_bank->num_time_slots; + + WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS]; + WORD16 *filter_states = qmf_bank->core_samples_buffer; + + WORD16 *fp1, *fp2, *tmp; + + WORD16 *filter_1; + WORD16 *filter_2; + WORD16 *filt_ptr; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + qmf_bank->filter_pos += + (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff); + qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c; + } else { + qmf_bank->filter_pos += + (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff); + qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3; + } + + filter_1 = qmf_bank->filter_pos; + + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + filter_2 = filter_1 + 64; + } else { + filter_2 = filter_1 + 32; + } + + sbr_scale_factor->st_lb_scale = 0; + sbr_scale_factor->lb_scale = -10; + if (!low_pow_flag) { + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + sbr_scale_factor->lb_scale = -8; + } else { + sbr_scale_factor->lb_scale = -9; + } + qmf_bank->cos_twiddle = + (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32; + qmf_bank->alt_sin_twiddle = + (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32; + } else { + qmf_bank->t_cos = + (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld; + } + } + + fp1 = qmf_bank->anal_filter_states; + fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS; + + if (audio_object_type == AOT_ER_AAC_ELD || + audio_object_type == AOT_ER_AAC_LD) { + filter_2 = qmf_bank->filter_2; + fp1 = qmf_bank->fp1_anal; + fp2 = qmf_bank->fp2_anal; + } + + for (i = 0; i < num_time_slots; i++) { + for (k = 0; k < NO_ANALYSIS_CHANNELS; k++) + filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k]; + + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2, + analysis_buffer, filter_states, + time_sample_buf, ch_fac); + } + + else { + ixheaacd_sbr_qmfanal32_winadd_eld(fp1, fp2, filter_1, filter_2, + analysis_buffer); + } + + time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac; + + filter_states -= NO_ANALYSIS_CHANNELS; + if (filter_states < qmf_bank->anal_filter_states) { + filter_states = qmf_bank->anal_filter_states + 288; + } + + tmp = fp1; + fp1 = fp2; + fp2 = tmp; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + filter_1 += 64; + filter_2 += 64; + } else { + filter_1 += 32; + filter_2 += 32; + } + + filt_ptr = filter_1; + filter_1 = filter_2; + filter_2 = filt_ptr; + if (audio_object_type != AOT_ER_AAC_ELD && + audio_object_type != AOT_ER_AAC_LD) { + if (filter_2 > (qmf_bank->analy_win_coeff + 640)) { + filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; + filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64; + } + } else { + if (filter_2 > (qmf_bank->analy_win_coeff + 320)) { + filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; + filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32; + } + } + + if (!low_pow_flag) { + ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i], + qmf_bank, qmf_dec_tables_ptr); + } else { + ixheaacd_dct3_32( + (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw, + qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16, + qmf_dec_tables_ptr->dig_rev_table4_16); + } + } + + qmf_bank->filter_pos = filter_1; + qmf_bank->core_samples_buffer = filter_states; + + if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD) + + { + qmf_bank->fp1_anal = fp1; + qmf_bank->fp2_anal = fp2; + qmf_bank->filter_2 = filter_2; + } +} + +VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, + ia_sbr_qmf_filter_bank_struct *syn_qmf, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { + WORD32 L = syn_qmf->no_channels; + const WORD32 M = (L >> 1); + WORD32 *dct_in = qmf_real; + WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS]; + + WORD32 ui_rem = ((WORD64)(&time_out[0]) % 8); + WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem); + + if (L == 64) + ixheaacd_dct2_64(dct_in, ptime_out, qmf_dec_tables_ptr, filter_states + M); + else + ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states); + + filter_states[3 * M] = 0; +} + +VOID ixheaacd_inv_emodulation( + WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { + ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024, + (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128); +} + +VOID ixheaacd_esbr_radix4bfly(const WORD32 *w, WORD32 *x, WORD32 index1, + WORD32 index) { + int i; + WORD32 l1, l2, h2, fft_jmp; + WORD32 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0; + WORD32 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0; + WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1; + WORD32 x_h2_0, x_h2_1; + WORD32 si10, si20, si30, co10, co20, co30; + + WORD64 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6; + WORD64 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12; + WORD32 *x_l1; + WORD32 *x_l2; + WORD32 *x_h2; + const WORD32 *w_ptr = w; + WORD32 i1; + + h2 = index << 1; + l1 = index << 2; + l2 = (index << 2) + (index << 1); + + x_l1 = &(x[l1]); + x_l2 = &(x[l2]); + x_h2 = &(x[h2]); + + fft_jmp = 6 * (index); + + for (i1 = 0; i1 < index1; i1++) { + for (i = 0; i < index; i++) { + si10 = (*w_ptr++); + co10 = (*w_ptr++); + si20 = (*w_ptr++); + co20 = (*w_ptr++); + si30 = (*w_ptr++); + co30 = (*w_ptr++); + + x_0 = x[0]; + x_h2_0 = x[h2]; + x_l1_0 = x[l1]; + x_l2_0 = x[l2]; + + xh0_0 = x_0 + x_l1_0; + xl0_0 = x_0 - x_l1_0; + + xh20_0 = x_h2_0 + x_l2_0; + xl20_0 = x_h2_0 - x_l2_0; + + x[0] = xh0_0 + xh20_0; + xt0_0 = xh0_0 - xh20_0; + + x_1 = x[1]; + x_h2_1 = x[h2 + 1]; + x_l1_1 = x[l1 + 1]; + x_l2_1 = x[l2 + 1]; + + xh1_0 = x_1 + x_l1_1; + xl1_0 = x_1 - x_l1_1; + + xh21_0 = x_h2_1 + x_l2_1; + xl21_0 = x_h2_1 - x_l2_1; + + x[1] = xh1_0 + xh21_0; + yt0_0 = xh1_0 - xh21_0; + + xt1_0 = xl0_0 + xl21_0; + xt2_0 = xl0_0 - xl21_0; + + yt2_0 = xl1_0 + xl20_0; + yt1_0 = xl1_0 - xl20_0; + + mul_11 = ixheaacd_mult64(xt2_0, co30); + mul_3 = ixheaacd_mult64(yt2_0, si30); + x[l2] = (WORD32)((mul_3 + mul_11) >> 32) << RADIXSHIFT; + + mul_5 = ixheaacd_mult64(xt2_0, si30); + mul_9 = ixheaacd_mult64(yt2_0, co30); + x[l2 + 1] = (WORD32)((mul_9 - mul_5) >> 32) << RADIXSHIFT; + + mul_12 = ixheaacd_mult64(xt0_0, co20); + mul_2 = ixheaacd_mult64(yt0_0, si20); + x[l1] = (WORD32)((mul_2 + mul_12) >> 32) << RADIXSHIFT; + + mul_6 = ixheaacd_mult64(xt0_0, si20); + mul_8 = ixheaacd_mult64(yt0_0, co20); + x[l1 + 1] = (WORD32)((mul_8 - mul_6) >> 32) << RADIXSHIFT; + + mul_4 = ixheaacd_mult64(xt1_0, co10); + mul_1 = ixheaacd_mult64(yt1_0, si10); + x[h2] = (WORD32)((mul_1 + mul_4) >> 32) << RADIXSHIFT; + + mul_10 = ixheaacd_mult64(xt1_0, si10); + mul_7 = ixheaacd_mult64(yt1_0, co10); + x[h2 + 1] = (WORD32)((mul_7 - mul_10) >> 32) << RADIXSHIFT; + + x += 2; + } + x += fft_jmp; + w_ptr = w_ptr - fft_jmp; + } +} + +VOID ixheaacd_esbr_postradixcompute2(WORD32 *ptr_y, WORD32 *ptr_x, + const WORD32 *pdig_rev_tbl, + WORD32 npoints) { + WORD32 i, k; + WORD32 h2; + WORD32 x_0, x_1, x_2, x_3; + WORD32 x_4, x_5, x_6, x_7; + WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f; + WORD32 n00, n10, n20, n30, n01, n11, n21, n31; + WORD32 n02, n12, n22, n32, n03, n13, n23, n33; + WORD32 n0, j0; + WORD32 *x2, *x0; + WORD32 *y0, *y1, *y2, *y3; + + y0 = ptr_y; + y2 = ptr_y + (WORD32)npoints; + x0 = ptr_x; + x2 = ptr_x + (WORD32)(npoints >> 1); + + y1 = y0 + (WORD32)(npoints >> 2); + y3 = y2 + (WORD32)(npoints >> 2); + j0 = 8; + n0 = npoints >> 1; + + for (k = 0; k < 2; k++) { + for (i = 0; i> 1; i += 8) { + h2 = *pdig_rev_tbl++ >> 2; + + x_0 = *x0++; + x_1 = *x0++; + x_2 = *x0++; + x_3 = *x0++; + x_4 = *x0++; + x_5 = *x0++; + x_6 = *x0++; + x_7 = *x0++; + + n00 = x_0 + x_2; + n01 = x_1 + x_3; + n20 = x_0 - x_2; + n21 = x_1 - x_3; + n10 = x_4 + x_6; + n11 = x_5 + x_7; + n30 = x_4 - x_6; + n31 = x_5 - x_7; + + y0[h2] = n00; + y0[h2 + 1] = n01; + y1[h2] = n10; + y1[h2 + 1] = n11; + y2[h2] = n20; + y2[h2 + 1] = n21; + y3[h2] = n30; + y3[h2 + 1] = n31; + + x_8 = *x2++; + x_9 = *x2++; + x_a = *x2++; + x_b = *x2++; + x_c = *x2++; + x_d = *x2++; + x_e = *x2++; + x_f = *x2++; + + n02 = x_8 + x_a; + n03 = x_9 + x_b; + n22 = x_8 - x_a; + n23 = x_9 - x_b; + n12 = x_c + x_e; + n13 = x_d + x_f; + n32 = x_c - x_e; + n33 = x_d - x_f; + + y0[h2 + 2] = n02; + y0[h2 + 3] = n03; + y1[h2 + 2] = n12; + y1[h2 + 3] = n13; + y2[h2 + 2] = n22; + y2[h2 + 3] = n23; + y3[h2 + 2] = n32; + y3[h2 + 3] = n33; + } + x0 += (WORD32)npoints >> 1; + x2 += (WORD32)npoints >> 1; + } +} + +VOID ixheaacd_esbr_postradixcompute4(WORD32 *ptr_y, WORD32 *ptr_x, + const WORD32 *p_dig_rev_tbl, + WORD32 npoints) { + WORD32 i, k; + WORD32 h2; + WORD32 xh0_0, xh1_0, xl0_0, xl1_0; + WORD32 xh0_1, xh1_1, xl0_1, xl1_1; + WORD32 x_0, x_1, x_2, x_3; + WORD32 xh0_2, xh1_2, xl0_2, xl1_2, xh0_3, xh1_3, xl0_3, xl1_3; + WORD32 x_4, x_5, x_6, x_7; + WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f; + WORD32 n00, n10, n20, n30, n01, n11, n21, n31; + WORD32 n02, n12, n22, n32, n03, n13, n23, n33; + WORD32 n0, j0; + WORD32 *x2, *x0; + WORD32 *y0, *y1, *y2, *y3; + + y0 = ptr_y; + y2 = ptr_y + (WORD32)npoints; + x0 = ptr_x; + x2 = ptr_x + (WORD32)(npoints >> 1); + + y1 = y0 + (WORD32)(npoints >> 1); + y3 = y2 + (WORD32)(npoints >> 1); + + j0 = 4; + n0 = npoints >> 2; + + for (k = 0; k < 2; k++) { + for (i = 0; i> 1; i += 8) { + h2 = *p_dig_rev_tbl++ >> 2; + x_0 = *x0++; + x_1 = *x0++; + x_2 = *x0++; + x_3 = *x0++; + x_4 = *x0++; + x_5 = *x0++; + x_6 = *x0++; + x_7 = *x0++; + + xh0_0 = x_0 + x_4; + xh1_0 = x_1 + x_5; + xl0_0 = x_0 - x_4; + xl1_0 = x_1 - x_5; + xh0_1 = x_2 + x_6; + xh1_1 = x_3 + x_7; + xl0_1 = x_2 - x_6; + xl1_1 = x_3 - x_7; + + n00 = xh0_0 + xh0_1; + n01 = xh1_0 + xh1_1; + n10 = xl0_0 + xl1_1; + n11 = xl1_0 - xl0_1; + n20 = xh0_0 - xh0_1; + n21 = xh1_0 - xh1_1; + n30 = xl0_0 - xl1_1; + n31 = xl1_0 + xl0_1; + + y0[h2] = n00; + y0[h2 + 1] = n01; + y1[h2] = n10; + y1[h2 + 1] = n11; + y2[h2] = n20; + y2[h2 + 1] = n21; + y3[h2] = n30; + y3[h2 + 1] = n31; + + x_8 = *x2++; + x_9 = *x2++; + x_a = *x2++; + x_b = *x2++; + x_c = *x2++; + x_d = *x2++; + x_e = *x2++; + x_f = *x2++; + + xh0_2 = x_8 + x_c; + xh1_2 = x_9 + x_d; + xl0_2 = x_8 - x_c; + xl1_2 = x_9 - x_d; + xh0_3 = x_a + x_e; + xh1_3 = x_b + x_f; + xl0_3 = x_a - x_e; + xl1_3 = x_b - x_f; + + n02 = xh0_2 + xh0_3; + n03 = xh1_2 + xh1_3; + n12 = xl0_2 + xl1_3; + n13 = xl1_2 - xl0_3; + n22 = xh0_2 - xh0_3; + n23 = xh1_2 - xh1_3; + n32 = xl0_2 - xl1_3; + n33 = xl1_2 + xl0_3; + + y0[h2 + 2] = n02; + y0[h2 + 3] = n03; + y1[h2 + 2] = n12; + y1[h2 + 3] = n13; + y2[h2 + 2] = n22; + y2[h2 + 3] = n23; + y3[h2 + 2] = n32; + y3[h2 + 3] = n33; + } + x0 += (WORD32)npoints >> 1; + x2 += (WORD32)npoints >> 1; + } +} + +VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) { + WORD32 z; + WORD32 temp[128]; + WORD32 scaleshift = 0; + + WORD32 re2, re3; + WORD32 wim, wre; + + WORD32 i, M_2; + WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); + + const WORD32 *p_sin; + const WORD32 *p_sin_cos; + + WORD32 subband_tmp[128]; + WORD32 re; + WORD32 im; + WORD32 *psubband, *psubband1; + WORD32 *psubband_t, *psubband1_t; + WORD32 *psubband2, *psubband12; + WORD32 *psubband_t2, *psubband1_t2; + + M_2 = ixheaacd_shr32(M, 1); + + p_sin_cos = qmf_bank->esbr_cos_twiddle; + + psubband = &subband[0]; + psubband1 = &subband[2 * M - 1]; + psubband_t = subband_tmp; + psubband1_t = &subband_tmp[2 * M - 1]; + + psubband2 = &subband[64]; + psubband12 = &subband[2 * M - 1 + 64]; + psubband_t2 = &subband_tmp[64]; + psubband1_t2 = &subband_tmp[2 * M - 1 + 64]; + + for (i = (M_2 >> 1) - 1; i >= 0; i--) { + re = *psubband++; + im = *psubband1--; + + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband_t++ = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> + 32); + *psubband_t++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), + ixheaacd_mult64(re, wim))) >> + 32); + + re = *psubband2++; + im = *psubband12--; + + *psubband_t2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), + ixheaacd_mult64(re, wre))) >> + 32); + *psubband_t2++ = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> + 32); + + re = *psubband1--; + im = *psubband++; + + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband1_t-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), + ixheaacd_mult64(re, wim))) >> + 32); + *psubband1_t-- = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> + 32); + + re = *psubband12--; + im = *psubband2++; + + *psubband1_t2-- = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> + 32); + *psubband1_t2-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), + ixheaacd_mult64(re, wre))) >> + 32); + + re = *psubband++; + im = *psubband1--; + + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband_t++ = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> + 32); + *psubband_t++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), + ixheaacd_mult64(re, wim))) >> + 32); + + re = *psubband2++; + im = *psubband12--; + + *psubband_t2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), + ixheaacd_mult64(re, wre))) >> + 32); + *psubband_t2++ = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> + 32); + + re = *psubband1--; + im = *psubband++; + ; + + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband1_t-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), + ixheaacd_mult64(re, wim))) >> + 32); + *psubband1_t-- = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> + 32); + + re = *psubband12--; + im = *psubband2++; + ; + + *psubband1_t2-- = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> + 32); + *psubband1_t2-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), + ixheaacd_mult64(re, wre))) >> + 32); + } + + if (M == 32) { + ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8); + ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2); + ixheaacd_esbr_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32); + + ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8); + ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2); + ixheaacd_esbr_postradixcompute2(&subband[64], &subband_tmp[64], + p_dig_rev_tbl, 32); + + } + + else if (M == 16) { + ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4); + ixheaacd_esbr_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16); + + ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4); + ixheaacd_esbr_postradixcompute4(&subband[64], &subband_tmp[64], + p_dig_rev_tbl, 16); + + } + + else if (M == 12) { + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[2 * z]; + temp[12 + z] = subband_tmp[2 * z + 1]; + } + + ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[2 * z] = temp[z]; + subband[2 * z + 1] = temp[z + 12]; + } + scaleshift = 0; + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[64 + 2 * z]; + temp[12 + z] = subband_tmp[64 + 2 * z + 1]; + } + + ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[64 + 2 * z] = temp[z]; + subband[64 + 2 * z + 1] = temp[z + 12]; + } + + } + + else { + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[2 * z]; + temp[8 + z] = subband_tmp[2 * z + 1]; + } + + (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[2 * z] = temp[z] << scaleshift; + subband[2 * z + 1] = temp[z + 8] << scaleshift; + } + scaleshift = 0; + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[64 + 2 * z]; + temp[8 + z] = subband_tmp[64 + 2 * z + 1]; + } + + (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); + + for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { + subband[64 + 2 * z] = temp[z] << scaleshift; + subband[64 + 2 * z + 1] = temp[8 + z] << scaleshift; + } + } + + psubband = &subband[0]; + psubband1 = &subband[2 * M - 1]; + + re = *psubband1; + + *psubband = *psubband >> 1; + psubband++; + *psubband1 = ixheaacd_negate32(*psubband >> 1); + psubband1--; + + p_sin = qmf_bank->esbr_alt_sin_twiddle; + + wim = *p_sin++; + wre = *p_sin++; + + im = *psubband1; + ; + + *psubband1-- = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> + 32); + *psubband++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), + ixheaacd_mult64(re, wim))) >> + 32); + + psubband2 = &subband[64]; + psubband12 = &subband[2 * M - 1 + 64]; + + re = *psubband12; + ; + + *psubband12-- = ixheaacd_negate32_sat(*psubband2 >> 1); + ; + *psubband2 = psubband2[1] >> 1; + ; + psubband2++; + + im = *psubband12; + ; + + *psubband2++ = ixheaacd_negate32_sat((WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> + 32)); + *psubband12-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re, wim), + ixheaacd_mult64(im, wre))) >> + 32); + + for (i = (M_2 - 2); i >= 0; i--) { + im = psubband[0]; + ; + re = psubband[1]; + ; + re2 = *psubband1; + ; + + *psubband++ = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> + 32); + *psubband1-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), + ixheaacd_mult64(re, wre))) >> + 32); + + im = psubband2[0]; + ; + re = psubband2[1]; + ; + re3 = *psubband12; + ; + + *psubband12-- = ixheaacd_negate32_sat((WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> + 32)); + *psubband2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re, wre), + ixheaacd_mult64(im, wim))) >> + 32); + + wim = *p_sin++; + wre = *p_sin++; + im = psubband1[0]; + ; + + *psubband1-- = (WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re2, wre), ixheaacd_mult64(im, wim))) >> + 32); + *psubband++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), + ixheaacd_mult64(re2, wim))) >> + 32); + + im = psubband12[0]; + ; + + *psubband2++ = ixheaacd_negate32_sat((WORD32)( + (ixheaacd_add64(ixheaacd_mult64(re3, wre), ixheaacd_mult64(im, wim))) >> + 32)); + *psubband12-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re3, wim), + ixheaacd_mult64(im, wre))) >> + 32); + } +} + + +VOID ixheaacd_esbr_fwd_modulation( + const WORD32 *time_sample_buf, WORD32 *real_subband, WORD32 *imag_subband, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { + WORD32 i; + const WORD32 *time_sample_buf1 = + &time_sample_buf[2 * qmf_bank->no_channels - 1]; + WORD32 temp1, temp2; + WORD32 *t_real_subband = real_subband; + WORD32 *t_imag_subband = imag_subband; + const WORD32 *tcos; + + for (i = qmf_bank->no_channels - 1; i >= 0; i--) { + temp1 = ixheaacd_shr32(*time_sample_buf++, HQ_SHIFT_64); + temp2 = ixheaacd_shr32(*time_sample_buf1--, HQ_SHIFT_64); + + *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2); + ; + *t_imag_subband++ = ixheaacd_add32(temp1, temp2); + ; + } + + ixheaacd_esbr_cos_sin_mod(real_subband, qmf_bank, + qmf_dec_tables_ptr->esbr_w_16, + qmf_dec_tables_ptr->dig_rev_table4_16); + + tcos = qmf_bank->esbr_t_cos; + + for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) { + WORD32 cosh, sinh; + WORD32 re, im; + + re = *real_subband; + im = *imag_subband; + cosh = *tcos++; + sinh = *tcos++; + *real_subband++ = (WORD32)((ixheaacd_add64(ixheaacd_mult64(re, cosh), + ixheaacd_mult64(im, sinh))) >> + 31); + *imag_subband++ = + (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, cosh), + ixheaacd_mult64(re, sinh))) >> + 31); + } +} + +VOID ixheaacd_esbr_qmfsyn64_winadd(WORD32 *tmp1, WORD32 *tmp2, WORD32 *inp1, + WORD32 *sample_buffer, WORD32 ch_fac) { + WORD32 k; + + for (k = 0; k < 64; k++) { + WORD64 syn_out = 0; + + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[0 + k], inp1[k + 0])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[256 + k], inp1[k + 128])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[512 + k], inp1[k + 256])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[768 + k], inp1[k + 384])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[1024 + k], inp1[k + 512])); + + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[128 + k], inp1[k + 64])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[384 + k], inp1[k + 192])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[640 + k], inp1[k + 320])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[896 + k], inp1[k + 448])); + syn_out = + ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[1152 + k], inp1[k + 576])); + + sample_buffer[ch_fac * k] = (WORD32)(syn_out >> 31); + } +} + +VOID ixheaacd_shiftrountine(WORD32 *qmf_real, WORD32 *qmf_imag, WORD32 len, + WORD32 common_shift) { + WORD32 treal, timag; + WORD32 j; + + if (common_shift < 0) { + WORD32 cshift = -common_shift; + cshift = ixheaacd_min32(cshift, 31); + for (j = len - 1; j >= 0; j--) { + treal = *qmf_real; + timag = *qmf_imag; + + treal = (ixheaacd_shr32(treal, cshift)); + timag = (ixheaacd_shr32(timag, cshift)); + + *qmf_real++ = treal; + *qmf_imag++ = timag; + } + } else { + for (j = len - 1; j >= 0; j--) { + treal = (ixheaacd_shl32_sat(*qmf_real, common_shift)); + timag = (ixheaacd_shl32_sat(*qmf_imag, common_shift)); + *qmf_real++ = treal; + *qmf_imag++ = timag; + } + } +} + +VOID ixheaacd_shiftrountine_with_rnd_hq(WORD32 *qmf_real, WORD32 *qmf_imag, + WORD32 *filter_states, WORD32 len, + WORD32 shift) { + WORD32 *filter_states_rev = filter_states + len; + WORD32 treal, timag; + WORD32 j; + + for (j = (len - 1); j >= 0; j -= 2) { + WORD32 r1, r2, i1, i2; + i2 = qmf_imag[j]; + r2 = qmf_real[j]; + r1 = *qmf_real++; + i1 = *qmf_imag++; + + timag = ixheaacd_add32(i1, r1); + timag = (ixheaacd_shl32_sat(timag, shift)); + filter_states_rev[j] = timag; + + treal = ixheaacd_sub32(i2, r2); + treal = (ixheaacd_shl32_sat(treal, shift)); + filter_states[j] = treal; + + treal = ixheaacd_sub32(i1, r1); + treal = (ixheaacd_shl32_sat(treal, shift)); + *filter_states++ = treal; + + timag = ixheaacd_add32(i2, r2); + timag = (ixheaacd_shl32_sat(timag, shift)); + *filter_states_rev++ = timag; + } +} + +VOID ixheaacd_radix4bfly(const WORD16 *w, WORD32 *x, WORD32 index1, + WORD32 index) { + int i; + WORD32 l1, l2, h2, fft_jmp; + WORD32 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0; + WORD32 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0; + WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1; + WORD32 x_h2_0, x_h2_1; + WORD16 si10, si20, si30, co10, co20, co30; + + WORD32 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6; + WORD32 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12; + WORD32 *x_l1; + WORD32 *x_l2; + WORD32 *x_h2; + const WORD16 *w_ptr = w; + WORD32 i1; + + h2 = index << 1; + l1 = index << 2; + l2 = (index << 2) + (index << 1); + + x_l1 = &(x[l1]); + x_l2 = &(x[l2]); + x_h2 = &(x[h2]); + + fft_jmp = 6 * (index); + + for (i1 = 0; i1 < index1; i1++) { + for (i = 0; i < index; i++) { + si10 = (*w_ptr++); + co10 = (*w_ptr++); + si20 = (*w_ptr++); + co20 = (*w_ptr++); + si30 = (*w_ptr++); + co30 = (*w_ptr++); + + x_0 = x[0]; + x_h2_0 = x[h2]; + x_l1_0 = x[l1]; + x_l2_0 = x[l2]; + + xh0_0 = x_0 + x_l1_0; + xl0_0 = x_0 - x_l1_0; + + xh20_0 = x_h2_0 + x_l2_0; + xl20_0 = x_h2_0 - x_l2_0; + + x[0] = xh0_0 + xh20_0; + xt0_0 = xh0_0 - xh20_0; + + x_1 = x[1]; + x_h2_1 = x[h2 + 1]; + x_l1_1 = x[l1 + 1]; + x_l2_1 = x[l2 + 1]; + + xh1_0 = x_1 + x_l1_1; + xl1_0 = x_1 - x_l1_1; + + xh21_0 = x_h2_1 + x_l2_1; + xl21_0 = x_h2_1 - x_l2_1; + + x[1] = xh1_0 + xh21_0; + yt0_0 = xh1_0 - xh21_0; + + xt1_0 = xl0_0 + xl21_0; + xt2_0 = xl0_0 - xl21_0; + + yt2_0 = xl1_0 + xl20_0; + yt1_0 = xl1_0 - xl20_0; + + mul_11 = ixheaacd_mult32x16in32(xt2_0, co30); + mul_3 = ixheaacd_mult32x16in32(yt2_0, si30); + x[l2] = (mul_3 + mul_11) << RADIXSHIFT; + + mul_5 = ixheaacd_mult32x16in32(xt2_0, si30); + mul_9 = ixheaacd_mult32x16in32(yt2_0, co30); + x[l2 + 1] = (mul_9 - mul_5) << RADIXSHIFT; + + mul_12 = ixheaacd_mult32x16in32(xt0_0, co20); + mul_2 = ixheaacd_mult32x16in32(yt0_0, si20); + x[l1] = (mul_2 + mul_12) << RADIXSHIFT; + + mul_6 = ixheaacd_mult32x16in32(xt0_0, si20); + mul_8 = ixheaacd_mult32x16in32(yt0_0, co20); + x[l1 + 1] = (mul_8 - mul_6) << RADIXSHIFT; + + mul_4 = ixheaacd_mult32x16in32(xt1_0, co10); + mul_1 = ixheaacd_mult32x16in32(yt1_0, si10); + x[h2] = (mul_1 + mul_4) << RADIXSHIFT; + + mul_10 = ixheaacd_mult32x16in32(xt1_0, si10); + mul_7 = ixheaacd_mult32x16in32(yt1_0, co10); + x[h2 + 1] = (mul_7 - mul_10) << RADIXSHIFT; + + x += 2; + } + x += fft_jmp; + w_ptr = w_ptr - fft_jmp; + } +} + + + diff --git a/decoder/generic/ixheaacd_function_selector_generic.c b/decoder/generic/ixheaacd_function_selector_generic.c index 1501ae2..8fdb4b9 100644 --- a/decoder/generic/ixheaacd_function_selector_generic.c +++ b/decoder/generic/ixheaacd_function_selector_generic.c @@ -62,6 +62,7 @@ #include "ixheaacd_env_calc.h" #include "ixheaacd_interface.h" #include "ixheaacd_dsp_fft32x32s.h" +#if !__ARM_NEON__ WORD32 (*ixheaacd_fix_div)(WORD32, WORD32) = &ixheaacd_fix_div_dec; @@ -245,4 +246,7 @@ VOID (*ixheaacd_inv_dit_fft_8pt) VOID (*ixheaacd_scale_factor_process) (WORD32 *x_invquant, WORD16 *scale_fact, WORD no_band, WORD8 *width, WORD32 *scale_tables_ptr, WORD32 total_channels, WORD32 object_type, - WORD32 aac_sf_data_resil_flag) = &ixheaacd_scale_factor_process_dec; \ No newline at end of file + WORD32 aac_sf_data_resil_flag) = &ixheaacd_scale_factor_process_dec; + +#endif + diff --git a/decoder/armv8/ixheaacd_qmf_dec.c b/decoder/generic/ixheaacd_qmf_dec_generic.c similarity index 54% rename from decoder/armv8/ixheaacd_qmf_dec.c rename to decoder/generic/ixheaacd_qmf_dec_generic.c index 27c26bd..a813a3c 100644 --- a/decoder/armv8/ixheaacd_qmf_dec.c +++ b/decoder/generic/ixheaacd_qmf_dec_generic.c @@ -18,8 +18,9 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ #include + #include "ixheaacd_sbr_common.h" -#include "ixheaacd_type_def.h" +#include #include "ixheaacd_constants.h" #include "ixheaacd_basic_ops32.h" @@ -44,16 +45,10 @@ #include "ixheaacd_env_calc.h" #include "ixheaacd_interface.h" + #include "ixheaacd_function_selector.h" #include "ixheaacd_audioobjtypes.h" - -#define mult16x16_16(a, b) ixheaacd_mult16((a), (b)) -#define mac16x16(a, b, c) ixheaacd_mac16x16in32((a), (b), (c)) -#define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b)) -#define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b)) -#define mpy_32x32(a, b) ixheaacd_mult32((a), (b)) -#define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b)) -#define msu16x16(a, b, c) msu16x16in32((a), (b), (c)) +#if !__ARM_NEON__ #define DCT3_LEN (32) #define DCT2_LEN (64) @@ -61,21 +56,8 @@ #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_dct3_32(WORD32 *input, WORD32 *output, const WORD16 *main_twidle_fwd, const WORD16 *post_tbl, const WORD16 *w_16, const WORD32 *p_table) { @@ -111,9 +93,13 @@ VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, twid_im = *twidle_fwd; twidle_fwd += 3; - *p_out++ = mac32x16in32_dual(temp1[0], twid_re, temp1[1], twid_im); - *p_out++ = msu32x16in32_dual(temp1[0], twid_im, temp1[1], twid_re); + + *p_out++ = ixheaacd_mult32x16in32(temp1[0], twid_re) + + ixheaacd_mult32x16in32(temp1[1], twid_im); + *p_out++ = -ixheaacd_mult32x16in32(temp1[1], twid_re) + + ixheaacd_mult32x16in32(temp1[0], twid_im); } + twid_re = *twidle_fwd++; twid_im = *twidle_fwd; @@ -126,11 +112,14 @@ VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, temp1[0] = temp1[1]; - temp2[2] = mac32x16in32_dual(temp1[0], twid_re, temp1[1], twid_im); - temp2[3] = msu32x16in32_dual(temp1[0], twid_im, temp1[1], twid_re); + temp2[2] = ixheaacd_mult32x16in32(temp1[0], twid_re) + + ixheaacd_mult32x16in32(temp1[1], twid_im); + temp2[3] = -ixheaacd_mult32x16in32(temp1[1], twid_re) + + ixheaacd_mult32x16in32(temp1[0], twid_im); ptr_forward = output; ptr_reverse = &output[DCT3_LEN - 1]; + temp2[0] = *ptr_forward++; temp2[1] = *ptr_forward--; @@ -164,8 +153,11 @@ VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, temp1[2] = temp2[1] + temp2[3]; temp1[3] = (temp2[1] - temp2[3]); - temp1[4] = mac32x16in32_dual(temp1[0], twid_re, temp1[2], twid_im); - temp1[5] = msu32x16in32_dual(temp1[0], twid_im, temp1[2], twid_re); + + temp1[4] = ixheaacd_mult32x16in32(temp1[0], twid_re) + + ixheaacd_mult32x16in32(temp1[2], twid_im); + temp1[5] = -ixheaacd_mult32x16in32(temp1[2], twid_re) + + ixheaacd_mult32x16in32(temp1[0], twid_im); temp1[1] >>= 1; temp1[3] >>= 1; @@ -181,7 +173,7 @@ VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, temp2[3] = *ptr_reverse--; temp2[2] = *ptr_reverse++; - twid_re = *twidle_rev; + twid_re = -*twidle_rev; twidle_rev -= 2; twid_im = *twidle_fwd; twidle_fwd += 2; @@ -192,8 +184,10 @@ VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, temp1[2] = temp2[1] + temp2[3]; temp1[3] = (temp2[1] - temp2[3]); - temp1[4] = -mac32x16in32_dual(temp1[0], twid_re, temp1[2], twid_im); - temp1[5] = msu32x16in32_dual(temp1[0], twid_im, temp1[2], twid_re); + temp1[4] = ixheaacd_mult32x16in32(temp1[0], twid_re) - + ixheaacd_mult32x16in32(temp1[2], twid_im); + temp1[5] = ixheaacd_mult32x16in32(temp1[2], twid_re) + + ixheaacd_mult32x16in32(temp1[0], twid_im); temp1[1] >>= 1; temp1[3] >>= 1; @@ -242,133 +236,16 @@ VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, return; } -static PLATFORM_INLINE 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; -} - -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 = temp[3] - temp[1]; - in1 = temp[3] + temp[1]; - - temp[1] = temp[0] - temp[2]; - temp[3] = temp[0] + temp[2]; - - twid_re = *twidle_fwd++; - twid_im = *twidle_rev--; - val1 = msu32x16in32_dual(in1, twid_re, temp[1], twid_im); - val2 = mac32x16in32_dual(temp[1], twid_re, in1, twid_im); - val1 = val1 << 1; - val2 = val2 << 1; - - *p_out_fwd++ = temp[3] + val1; - *p_out_fwd++ = in2 + val2; - - *ptr_out_rev-- = -in2 + val2; - *ptr_out_rev-- = 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 = (out_re + out_im) >> 1; - re1 = ixheaacd_round16(ixheaacd_shl32(out_re1, (5 - 1))); - - *out_fwd++ = re1; - - last_val = (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 = msu32x16in32_dual(inp_re, twid_re, inp_im, twid_im); - out_im = mac32x16in32_dual(inp_im, twid_re, 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; -} - VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, WORD16 *filter_states) { ixheaacd_pretwdct2(x, X); - ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x, - qmf_dec_tables_ptr->dig_rev_table2_128, - qmf_dec_tables_ptr->dig_rev_table2_128, - qmf_dec_tables_ptr->dig_rev_table2_128, - qmf_dec_tables_ptr->dig_rev_table2_128); + ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_32, X, 1, 8); + + ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_32 + 48, X, 4, 2); + + ixheaacd_postradixcompute2(x, X, qmf_dec_tables_ptr->dig_rev_table2_32, 32); ixheaacd_fftposttw(x, qmf_dec_tables_ptr); @@ -377,205 +254,213 @@ VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X, 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; -} - -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 = temp1 + temp3; - in2 = -temp1 + temp3; - - temp1 = temp0 - temp2; - temp3 = 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++ = temp3 + val1; - *ptr_out_fwd++ = in2 + val2; - - *ptr_out_rev-- = -in2 + val2; - *ptr_out_rev-- = 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 = (out_re + out_im) >> 1; - re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re1, (5 - 1))); - *out_fwd++ = re1; - last_val = (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(temp1, ixheaacd_mult32x16in32(inp_re, twid_im)); - out_im = ixheaacd_add32(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_cos_sin_mod(WORD32 *subband, ia_sbr_qmf_filter_bank_struct *qmf_bank, WORD16 *p_twiddle, WORD32 *p_dig_rev_tbl) { + WORD32 re2, re3; + WORD16 wim, wre; + + WORD32 i, M_2; WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); const WORD16 *p_sin; const WORD16 *p_sin_cos = &qmf_bank->cos_twiddle[0]; WORD32 subband_tmp[128]; + WORD32 re; + WORD32 im; + WORD32 *psubband, *psubband1; + WORD32 *psubband_t, *psubband1_t; + WORD32 *psubband2, *psubband12; + WORD32 *psubband_t2, *psubband1_t2; - ixheaacd_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp); + M_2 = ixheaacd_shr32(M, 1); - if (M == 32) { - ixheaacd_sbr_imdct_using_fft( - (const WORD32 *)p_twiddle, 32, subband_tmp, subband, - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + psubband = &subband[0]; + psubband1 = &subband[2 * M - 1]; + psubband_t = subband_tmp; + psubband1_t = &subband_tmp[2 * M - 1]; - ixheaacd_sbr_imdct_using_fft( - (const WORD32 *)p_twiddle, 32, &subband_tmp[64], &subband[64], - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + psubband2 = &subband[64]; + psubband12 = &subband[2 * M - 1 + 64]; + psubband_t2 = &subband_tmp[64]; + psubband1_t2 = &subband_tmp[2 * M - 1 + 64]; - } else { - ixheaacd_sbr_imdct_using_fft( - (const WORD32 *)p_twiddle, 16, subband_tmp, subband, - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + for (i = (M_2 >> 1) - 1; i >= 0; i--) { + re = *psubband++; + im = *psubband1--; - ixheaacd_sbr_imdct_using_fft( - (const WORD32 *)p_twiddle, 16, &subband_tmp[64], &subband[64], - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl, - (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl); + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband_t++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), + ixheaacd_mult32x16in32(im, wim)); + *psubband_t++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), + ixheaacd_mult32x16in32(re, wim)); + + re = *psubband2++; + im = *psubband12--; + + *psubband_t2++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), + ixheaacd_mult32x16in32(re, wre)); + *psubband_t2++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), + ixheaacd_mult32x16in32(im, wre)); + + re = *psubband1--; + im = *psubband++; + + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband1_t-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), + ixheaacd_mult32x16in32(re, wim)); + *psubband1_t-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), + ixheaacd_mult32x16in32(im, wim)); + + re = *psubband12--; + im = *psubband2++; + + *psubband1_t2-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), + ixheaacd_mult32x16in32(im, wre)); + *psubband1_t2-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), + ixheaacd_mult32x16in32(re, wre)); + + re = *psubband++; + im = *psubband1--; + + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband_t++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), + ixheaacd_mult32x16in32(im, wim)); + *psubband_t++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), + ixheaacd_mult32x16in32(re, wim)); + + re = *psubband2++; + im = *psubband12--; + + *psubband_t2++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), + ixheaacd_mult32x16in32(re, wre)); + *psubband_t2++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), + ixheaacd_mult32x16in32(im, wre)); + + re = *psubband1--; + im = *psubband++; + + wim = *p_sin_cos++; + wre = *p_sin_cos++; + + *psubband1_t-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), + ixheaacd_mult32x16in32(re, wim)); + *psubband1_t-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), + ixheaacd_mult32x16in32(im, wim)); + + re = *psubband12--; + im = *psubband2++; + ; + + *psubband1_t2-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), + ixheaacd_mult32x16in32(im, wre)); + *psubband1_t2-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), + ixheaacd_mult32x16in32(re, wre)); } + if (M == 32) { + ixheaacd_radix4bfly(p_twiddle, subband_tmp, 1, 8); + ixheaacd_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2); + ixheaacd_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32); + + ixheaacd_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8); + ixheaacd_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2); + ixheaacd_postradixcompute2(&subband[64], &subband_tmp[64], p_dig_rev_tbl, + 32); + + } else { + ixheaacd_radix4bfly(p_twiddle, subband_tmp, 1, 4); + ixheaacd_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16); + + ixheaacd_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4); + ixheaacd_postradixcompute4(&subband[64], &subband_tmp[64], p_dig_rev_tbl, + 16); + } + + psubband = &subband[0]; + psubband1 = &subband[2 * M - 1]; + + re = *psubband1; + + *psubband = *psubband >> 1; + psubband++; + *psubband1 = ixheaacd_negate32(*psubband >> 1); + psubband1--; + p_sin = &qmf_bank->alt_sin_twiddle[0]; - ixheaacd_cos_sin_mod_loop2(subband, p_sin, M); + wim = *p_sin++; + wre = *p_sin++; + + im = *psubband1; + + *psubband1-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), + ixheaacd_mult32x16in32(im, wim)); + *psubband++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), + ixheaacd_mult32x16in32(re, wim)); + + psubband2 = &subband[64]; + psubband12 = &subband[2 * M - 1 + 64]; + + re = *psubband12; + + *psubband12-- = ixheaacd_negate32_sat(*psubband2 >> 1); + + *psubband2 = psubband2[1] >> 1; + + psubband2++; + + im = *psubband12; + + *psubband2++ = ixheaacd_negate32_sat(ixheaacd_add32( + ixheaacd_mult32x16in32(re, wre), ixheaacd_mult32x16in32(im, wim))); + *psubband12-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(re, wim), + ixheaacd_mult32x16in32(im, wre)); + + for (i = (M_2 - 2); i >= 0; i--) { + im = psubband[0]; + + re = psubband[1]; + + re2 = *psubband1; + + *psubband++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), + ixheaacd_mult32x16in32(im, wre)); + *psubband1-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), + ixheaacd_mult32x16in32(re, wre)); + + im = psubband2[0]; + + re = psubband2[1]; + + re3 = *psubband12; + + *psubband12-- = ixheaacd_negate32_sat(ixheaacd_add32( + ixheaacd_mult32x16in32(re, wim), ixheaacd_mult32x16in32(im, wre))); + *psubband2++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(re, wre), + ixheaacd_mult32x16in32(im, wim)); + + wim = *p_sin++; + wre = *p_sin++; + im = psubband1[0]; + + *psubband1-- = ixheaacd_add32(ixheaacd_mult32x16in32(re2, wre), + ixheaacd_mult32x16in32(im, wim)); + *psubband++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), + ixheaacd_mult32x16in32(re2, wim)); + + im = psubband12[0]; + + *psubband2++ = ixheaacd_negate32_sat(ixheaacd_add32( + ixheaacd_mult32x16in32(re3, wre), ixheaacd_mult32x16in32(im, wim))); + *psubband12-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(re3, wim), + ixheaacd_mult32x16in32(im, wre)); + } } VOID ixheaacd_fwd_modulation(const WORD32 *p_time_in1, WORD32 *real_subband, @@ -594,14 +479,12 @@ VOID ixheaacd_fwd_modulation(const WORD32 *p_time_in1, WORD32 *real_subband, temp2 = ixheaacd_shr32(*p_time_in2--, HQ_SHIFT_VAL); *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2); - ; + *t_imag_subband++ = ixheaacd_add32(temp1, temp2); - ; } - ixheaacd_cos_sin_mod(real_subband, qmf_bank, - (WORD16 *)qmf_dec_tables_ptr->w1024, - (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128); + ixheaacd_cos_sin_mod(real_subband, qmf_bank, qmf_dec_tables_ptr->w_16, + qmf_dec_tables_ptr->dig_rev_table4_16); tcos = qmf_bank->t_cos; @@ -681,255 +564,6 @@ VOID ixheaacd_sbr_qmfanal32_winadd(WORD16 *inp1, WORD16 *inp2, WORD16 *p_qmf1, } } -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_cplx_anal_qmffilt(const WORD16 *time_sample_buf, ia_sbr_scale_fact_struct *sbr_scale_factor, WORD32 **qmf_real, WORD32 **qmf_imag, @@ -1006,12 +640,9 @@ VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf, if (audio_object_type != AOT_ER_AAC_ELD && audio_object_type != AOT_ER_AAC_LD) { - ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2, - analysis_buffer, filter_states, - time_sample_buf, ch_fac); - } - - else { + ixheaacd_sbr_qmfanal32_winadd(fp1, fp2, filter_1, filter_2, + analysis_buffer); + } else { ixheaacd_sbr_qmfanal32_winadd_eld(fp1, fp2, filter_1, filter_2, analysis_buffer); } @@ -1074,8 +705,7 @@ VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf, } } -static PLATFORM_INLINE VOID -ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, +VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, ia_sbr_qmf_filter_bank_struct *syn_qmf, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { WORD32 L = syn_qmf->no_channels; @@ -1083,8 +713,7 @@ ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, WORD32 *dct_in = qmf_real; WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS]; - WORD32 ui_rem = ((WORD64)(&time_out[0]) % 8); - WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem); + WORD32 *ptime_out = &time_out[0]; if (L == 64) ixheaacd_dct2_64(dct_in, ptime_out, qmf_dec_tables_ptr, filter_states + M); @@ -1094,11 +723,15 @@ ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, filter_states[3 * M] = 0; } -static VOID ixheaacd_inv_emodulation( +VOID ixheaacd_inv_emodulation( WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { - ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024, - (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128); + if (syn_qmf->no_channels == 64) + ixheaacd_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->w_32, + qmf_dec_tables_ptr->dig_rev_table2_32); + else + ixheaacd_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->w_16, + qmf_dec_tables_ptr->dig_rev_table4_16); } VOID ixheaacd_esbr_radix4bfly(const WORD32 *w, WORD32 *x, WORD32 index1, @@ -1508,7 +1141,6 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, re = *psubband1--; im = *psubband++; - ; wim = *p_sin_cos++; wre = *p_sin_cos++; @@ -1522,7 +1154,6 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, re = *psubband12--; im = *psubband2++; - ; *psubband1_t2-- = (WORD32)( (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> @@ -1623,7 +1254,6 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, wre = *p_sin++; im = *psubband1; - ; *psubband1-- = (WORD32)( (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> @@ -1636,16 +1266,14 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, psubband12 = &subband[2 * M - 1 + 64]; re = *psubband12; - ; *psubband12-- = ixheaacd_negate32_sat(*psubband2 >> 1); - ; + *psubband2 = psubband2[1] >> 1; - ; + psubband2++; im = *psubband12; - ; *psubband2++ = ixheaacd_negate32_sat((WORD32)( (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> @@ -1656,11 +1284,10 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, for (i = (M_2 - 2); i >= 0; i--) { im = psubband[0]; - ; + re = psubband[1]; - ; + re2 = *psubband1; - ; *psubband++ = (WORD32)( (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> @@ -1670,11 +1297,10 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, 32); im = psubband2[0]; - ; + re = psubband2[1]; - ; + re3 = *psubband12; - ; *psubband12-- = ixheaacd_negate32_sat((WORD32)( (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> @@ -1686,7 +1312,6 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, wim = *p_sin++; wre = *p_sin++; im = psubband1[0]; - ; *psubband1-- = (WORD32)( (ixheaacd_add64(ixheaacd_mult64(re2, wre), ixheaacd_mult64(im, wim))) >> @@ -1696,7 +1321,6 @@ VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, 32); im = psubband12[0]; - ; *psubband2++ = ixheaacd_negate32_sat((WORD32)( (ixheaacd_add64(ixheaacd_mult64(re3, wre), ixheaacd_mult64(im, wim))) >> @@ -1724,9 +1348,8 @@ VOID ixheaacd_esbr_fwd_modulation( temp2 = ixheaacd_shr32(*time_sample_buf1--, HQ_SHIFT_64); *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2); - ; + *t_imag_subband++ = ixheaacd_add32(temp1, temp2); - ; } ixheaacd_esbr_cos_sin_mod(real_subband, qmf_bank, @@ -1753,16 +1376,41 @@ VOID ixheaacd_esbr_fwd_modulation( } } -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_qmfsyn64_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1, WORD16 *sample_buffer, FLAG shift, - WORD32 ch_fac); + WORD32 ch_fac) { + WORD32 k; + WORD32 rounding_fac = 0x8000; + rounding_fac = rounding_fac >> shift; + + for (k = 0; k < 64; k++) { + WORD32 syn_out = rounding_fac; + + syn_out = ixheaacd_add32(syn_out, + ixheaacd_mult16x16in32(tmp1[0 + k], inp1[k + 0])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp1[256 + k], inp1[k + 128])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp1[512 + k], inp1[k + 256])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp1[768 + k], inp1[k + 384])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp1[1024 + k], inp1[k + 512])); + + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp2[128 + k], inp1[k + 64])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp2[384 + k], inp1[k + 192])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp2[640 + k], inp1[k + 320])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp2[896 + k], inp1[k + 448])); + syn_out = ixheaacd_add32( + syn_out, ixheaacd_mult16x16in32(tmp2[1152 + k], inp1[k + 576])); + + sample_buffer[ch_fac * k] = (ixheaacd_shl32_sat(syn_out, shift) >> 16); + } +} VOID ixheaacd_esbr_qmfsyn64_winadd(WORD32 *tmp1, WORD32 *tmp2, WORD32 *inp1, WORD32 *sample_buffer, WORD32 ch_fac) { @@ -1797,45 +1445,6 @@ VOID ixheaacd_esbr_qmfsyn64_winadd(WORD32 *tmp1, WORD32 *tmp2, WORD32 *inp1, } } -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_shiftrountine(WORD32 *qmf_real, WORD32 *qmf_imag, WORD32 len, WORD32 common_shift) { WORD32 treal, timag; @@ -1864,6 +1473,72 @@ VOID ixheaacd_shiftrountine(WORD32 *qmf_real, WORD32 *qmf_imag, WORD32 len, } } +VOID ixheaacd_shiftrountine_with_rnd(WORD32 *qmf_real, WORD32 *qmf_imag, + WORD16 *filter_states, WORD32 len, + WORD32 shift) { + WORD16 *filter_states_rev = filter_states + len; + WORD32 treal, timag; + WORD32 j; + + for (j = (len - 1); j >= 0; j -= 2) { + WORD32 r1, r2, i1, i2; + i2 = qmf_imag[j]; + r2 = qmf_real[j]; + + r1 = *qmf_real++; + i1 = *qmf_imag++; + + timag = ixheaacd_add32(i1, r1); + timag = (ixheaacd_shl32_sat(timag, shift)); + filter_states_rev[j] = ixheaacd_round16(timag); + + treal = ixheaacd_sub32(i2, r2); + treal = (ixheaacd_shl32_sat(treal, shift)); + filter_states[j] = ixheaacd_round16(treal); + + treal = ixheaacd_sub32(i1, r1); + treal = (ixheaacd_shl32_sat(treal, shift)); + *filter_states++ = ixheaacd_round16(treal); + + timag = ixheaacd_add32(i2, r2); + ; + timag = (ixheaacd_shl32_sat(timag, shift)); + *filter_states_rev++ = ixheaacd_round16(timag); + } +} + +VOID ixheaacd_shiftrountine_with_rnd_eld(WORD32 *qmf_real, WORD32 *qmf_imag, + WORD16 *filter_states, WORD32 len, + WORD32 shift) { + WORD16 *filter_states_rev = filter_states + len; + WORD32 treal, timag; + WORD32 j; + + for (j = (len - 1); j >= 0; j -= 2) { + WORD32 r1, r2, i1, i2; + i2 = qmf_imag[j]; + r2 = qmf_real[j]; + r1 = *qmf_real++; + i1 = *qmf_imag++; + + timag = ixheaacd_negate32(ixheaacd_add32(i1, r1)); + timag = (ixheaacd_shl32_sat(timag, shift)); + filter_states_rev[j] = ixheaacd_round16(timag); + + treal = ixheaacd_sub32(r2, i2); + treal = (ixheaacd_shl32_sat(treal, shift)); + filter_states[j] = ixheaacd_round16(treal); + + treal = ixheaacd_sub32(r1, i1); + treal = (ixheaacd_shl32_sat(treal, shift)); + *filter_states++ = ixheaacd_round16(treal); + + timag = ixheaacd_negate32(ixheaacd_add32(i2, r2)); + timag = (ixheaacd_shl32_sat(timag, shift)); + *filter_states_rev++ = ixheaacd_round16(timag); + } +} + VOID ixheaacd_shiftrountine_with_rnd_hq(WORD32 *qmf_real, WORD32 *qmf_imag, WORD32 *filter_states, WORD32 len, WORD32 shift) { @@ -1896,336 +1571,6 @@ VOID ixheaacd_shiftrountine_with_rnd_hq(WORD32 *qmf_real, WORD32 *qmf_imag, } } -void ixheaacd_sbr_pre_twiddle(WORD32 *pXre, WORD32 *pXim, WORD16 *pTwiddles) { - int k; - - for (k = 62; k >= 0; k--) { - WORD32 Xre = *pXre; - WORD32 Xim = *pXim; - - WORD16 ixheaacd_cosine = *pTwiddles++; - - WORD16 ixheaacd_sine = *pTwiddles++; - - WORD32 re, im; - - re = ixheaacd_mac32x16in32_shl( - ixheaacd_mult32x16in32_shl(Xre, ixheaacd_cosine), Xim, ixheaacd_sine); - im = ixheaacd_sub32(ixheaacd_mult32x16in32_shl(Xim, ixheaacd_cosine), - ixheaacd_mult32x16in32_shl(Xre, ixheaacd_sine)); - - *pXre++ = re; - *pXim++ = 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; -} VOID ixheaacd_radix4bfly(const WORD16 *w, WORD32 *x, WORD32 index1, WORD32 index) { int i; @@ -2328,9 +1673,116 @@ VOID ixheaacd_radix4bfly(const WORD16 *w, WORD32 *x, WORD32 index1, } } +VOID ixheaacd_postradixcompute4(WORD32 *ptr_y, WORD32 *ptr_x, + const WORD32 *p_dig_rev_tbl, WORD32 npoints) { + WORD32 i, k; + WORD32 h2; + WORD32 xh0_0, xh1_0, xl0_0, xl1_0; + WORD32 xh0_1, xh1_1, xl0_1, xl1_1; + WORD32 x_0, x_1, x_2, x_3; + WORD32 xh0_2, xh1_2, xl0_2, xl1_2, xh0_3, xh1_3, xl0_3, xl1_3; + WORD32 x_4, x_5, x_6, x_7; + WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f; + WORD32 n00, n10, n20, n30, n01, n11, n21, n31; + WORD32 n02, n12, n22, n32, n03, n13, n23, n33; + WORD32 n0, j0; + WORD32 *x2, *x0; + WORD32 *y0, *y1, *y2, *y3; + + y0 = ptr_y; + y2 = ptr_y + (WORD32)npoints; + x0 = ptr_x; + x2 = ptr_x + (WORD32)(npoints >> 1); + + y1 = y0 + (WORD32)(npoints >> 1); + y3 = y2 + (WORD32)(npoints >> 1); + + j0 = 4; + n0 = npoints >> 2; + + for (k = 0; k < 2; k++) { + for (i = 0; i> 1; i += 8) { + h2 = *p_dig_rev_tbl++ >> 2; + x_0 = *x0++; + x_1 = *x0++; + x_2 = *x0++; + x_3 = *x0++; + x_4 = *x0++; + x_5 = *x0++; + x_6 = *x0++; + x_7 = *x0++; + + xh0_0 = x_0 + x_4; + xh1_0 = x_1 + x_5; + xl0_0 = x_0 - x_4; + xl1_0 = x_1 - x_5; + xh0_1 = x_2 + x_6; + xh1_1 = x_3 + x_7; + xl0_1 = x_2 - x_6; + xl1_1 = x_3 - x_7; + + n00 = xh0_0 + xh0_1; + n01 = xh1_0 + xh1_1; + n10 = xl0_0 + xl1_1; + n11 = xl1_0 - xl0_1; + n20 = xh0_0 - xh0_1; + n21 = xh1_0 - xh1_1; + n30 = xl0_0 - xl1_1; + n31 = xl1_0 + xl0_1; + + y0[h2] = n00; + y0[h2 + 1] = n01; + y1[h2] = n10; + y1[h2 + 1] = n11; + y2[h2] = n20; + y2[h2 + 1] = n21; + y3[h2] = n30; + y3[h2 + 1] = n31; + + x_8 = *x2++; + x_9 = *x2++; + x_a = *x2++; + x_b = *x2++; + x_c = *x2++; + x_d = *x2++; + x_e = *x2++; + x_f = *x2++; + + xh0_2 = x_8 + x_c; + xh1_2 = x_9 + x_d; + xl0_2 = x_8 - x_c; + xl1_2 = x_9 - x_d; + xh0_3 = x_a + x_e; + xh1_3 = x_b + x_f; + xl0_3 = x_a - x_e; + xl1_3 = x_b - x_f; + + n02 = xh0_2 + xh0_3; + n03 = xh1_2 + xh1_3; + n12 = xl0_2 + xl1_3; + n13 = xl1_2 - xl0_3; + n22 = xh0_2 - xh0_3; + n23 = xh1_2 - xh1_3; + n32 = xl0_2 - xl1_3; + n33 = xl1_2 + xl0_3; + + y0[h2 + 2] = n02; + y0[h2 + 3] = n03; + y1[h2 + 2] = n12; + y1[h2 + 3] = n13; + y2[h2 + 2] = n22; + y2[h2 + 3] = n23; + y3[h2 + 2] = n32; + y3[h2 + 3] = n33; + } + x0 += (WORD32)npoints >> 1; + x2 += (WORD32)npoints >> 1; + } +} + VOID ixheaacd_postradixcompute2(WORD32 *ptr_y, WORD32 *ptr_x, const WORD32 *pdig_rev_tbl, WORD32 npoints) { - WORD32 i, k; + WORD32 i, k; WORD32 h2; WORD32 x_0, x_1, x_2, x_3; WORD32 x_4, x_5, x_6, x_7; @@ -2413,3 +1865,4 @@ VOID ixheaacd_postradixcompute2(WORD32 *ptr_y, WORD32 *ptr_x, x2 += (WORD32)npoints >> 1; } } +#endif diff --git a/decoder/ixheaacd_acelp_decode.c b/decoder/ixheaacd_acelp_decode.c index 00ee182..aaa168c 100644 --- a/decoder/ixheaacd_acelp_decode.c +++ b/decoder/ixheaacd_acelp_decode.c @@ -506,8 +506,8 @@ WORD32 ixheaacd_acelp_alias_cnx(ia_usac_data_struct *usac_data, ixheaacd_preemphsis_tool_float(code, TILT_CODE, LEN_SUBFR, tmp); i = pitch_lag; if (pitch_lag_frac > 2) i++; - - ixheaacd_acelp_pitch_sharpening(code, i); + if(i >= 0) + ixheaacd_acelp_pitch_sharpening(code, i); index = pstr_td_frame_data->gains[k * 4 + subfr_nb]; diff --git a/decoder/ixheaacd_arith_dec.c b/decoder/ixheaacd_arith_dec.c index ed9ff75..c732f3d 100644 --- a/decoder/ixheaacd_arith_dec.c +++ b/decoder/ixheaacd_arith_dec.c @@ -20,6 +20,10 @@ #include #include #include +#include "ixheaacd_constants.h" +#include +#include +#include #include "ixheaacd_bitbuffer.h" #include "ixheaacd_interface.h" @@ -41,6 +45,9 @@ #include "ixheaacd_bit_extract.h" +#include "ixheaacd_error_codes.h" + + #define ARITH_ESCAPE 16 UWORD16 ixheaacd_ari_cf_r[3][4] = { @@ -1664,6 +1671,10 @@ VOID ixheaacd_copy_to_bitbuff(ia_bit_buf_struct *it_bit_buff_src, it_bit_buff_dst->cnt_bits = it_bit_buff_src->cnt_bits; it_bit_buff_dst->size = it_bit_buff_src->size; + + it_bit_buff_dst->max_size = it_bit_buff_src->max_size; + + } static WORD32 ixheaacd_arith_get_context(WORD8 *c_prev, WORD8 *c_pres, @@ -1832,6 +1843,7 @@ WORD32 ixheaacd_arth_decoding_level2(ia_bit_buf_struct *it_bit_buff, } if (esc_nb < 0) { esc_nb = 0; + return -1; } } @@ -1871,6 +1883,8 @@ WORD32 ixheaacd_arth_decoding_level2(ia_bit_buf_struct *it_bit_buff, } bit_count -= 16 - 2; + if(bit_count > it_bit_buff->cnt_bits) + return IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES; if (bit_count > 0) { bit_count_5 = bit_count >> 5; @@ -1962,7 +1976,7 @@ static VOID ixheaacd_esc_iquant(WORD32 *q, WORD32 *coef, WORD32 noise_level, coef[i] = flag * (coef[i] << 1); } - temp = (fac_fix * coef[i]); + temp = ixheaacd_mult64_sat(fac_fix , (WORD64)coef[i]); coef[i] = (WORD32)(temp >> 22); } diff --git a/decoder/ixheaacd_avq_dec.c b/decoder/ixheaacd_avq_dec.c index ac1824d..edd6a96 100644 --- a/decoder/ixheaacd_avq_dec.c +++ b/decoder/ixheaacd_avq_dec.c @@ -158,7 +158,10 @@ VOID ixheaacd_voronoi_idx_dec(WORD32 *kv, WORD32 m, WORD32 *y, WORD32 count) { } y[0] += (4 * kv[0] + sum); z[0] = (y[0] - 2) >> count; - rem1[0] = (y[0] - 2) % m; + if(m != 0) + rem1[0] = (y[0] - 2) % m; + else + rem1[0] = (y[0] - 2); memcpy(rem2, rem1, 8 * sizeof(WORD32)); diff --git a/decoder/ixheaacd_basic_ops40.h b/decoder/ixheaacd_basic_ops40.h index 1a35901..d5d5ee8 100644 --- a/decoder/ixheaacd_basic_ops40.h +++ b/decoder/ixheaacd_basic_ops40.h @@ -324,6 +324,18 @@ static PLATFORM_INLINE WORD64 ixheaacd_mult64(WORD32 a, WORD32 b) { return (result); } +static PLATFORM_INLINE WORD64 ixheaacd_mult64_sat(WORD64 a, WORD64 b) { + WORD64 result; + + if (a > 0 && b > 0 && a > MAX_64 / b) return MAX_64; + if (a < 0 && b > 0 && a < MIN_64 / b) return MIN_64; + if (a > 0 && b < 0 && b < MIN_64 / a) return MIN_64; + if (a < 0 && b < 0 && a < MAX_64 / b) return MAX_64; + + result = a * b; + return (result); +} + static PLATFORM_INLINE WORD64 ixheaacd_add64_sat(WORD64 a, WORD64 b) { WORD64 result , comp; result = (a < 0) ? MIN_64 : MAX_64; diff --git a/decoder/ixheaacd_bitbuffer.h b/decoder/ixheaacd_bitbuffer.h index 0b82926..d9099d1 100644 --- a/decoder/ixheaacd_bitbuffer.h +++ b/decoder/ixheaacd_bitbuffer.h @@ -82,6 +82,7 @@ typedef struct ia_bit_buf_struct { UWORD8 *byte_ptr; UWORD8 *ptr_start; WORD32 write_bit_count; + WORD32 max_size; } ia_bit_buf_struct; diff --git a/decoder/ixheaacd_common_initfuncs.c b/decoder/ixheaacd_common_initfuncs.c index 4da4b79..45e4194 100644 --- a/decoder/ixheaacd_common_initfuncs.c +++ b/decoder/ixheaacd_common_initfuncs.c @@ -139,6 +139,10 @@ ia_bit_buf_struct *ixheaacd_create_bit_buf(ia_bit_buf_struct *it_bit_buff, it_bit_buff->adts_header_present = 0; it_bit_buff->protection_absent = 0; it_bit_buff->pstr_adts_crc_info = &it_bit_buff->str_adts_crc_info; + + it_bit_buff->max_size = it_bit_buff->size; + + ixheaacd_adts_crc_open(it_bit_buff->pstr_adts_crc_info); return it_bit_buff; diff --git a/decoder/ixheaacd_config.h b/decoder/ixheaacd_config.h index 6964d9d..f0c5cd3 100644 --- a/decoder/ixheaacd_config.h +++ b/decoder/ixheaacd_config.h @@ -627,6 +627,6 @@ UWORD32 ixheaacd_sbr_params(UWORD32 core_sbr_frame_len_idx, WORD32 *output_samples,WORD32 *sampling_freq, UWORD32* sample_freq_indx); WORD32 ixheaacd_config(ia_bit_buf_struct *bit_buff, - ia_usac_config_struct *pstr_usac_conf); + ia_usac_config_struct *pstr_usac_conf, UINT32 *chan); #endif /* IXHEAACD_CONFIG_H */ diff --git a/decoder/ixheaacd_create.c b/decoder/ixheaacd_create.c index 15232b1..8b32040 100644 --- a/decoder/ixheaacd_create.c +++ b/decoder/ixheaacd_create.c @@ -256,6 +256,9 @@ WORD32 ixheaacd_decode_init( usac_data->pstr_usac_winmap[2] = &usac_data->str_eight_short_info; usac_data->pstr_usac_winmap[3] = &usac_data->str_only_long_info; usac_data->pstr_usac_winmap[4] = &usac_data->str_only_long_info; + + if((usac_data->ccfl != 480) && (usac_data->ccfl != 512) && (usac_data->ccfl != 768) && (usac_data->ccfl != 960) &&(usac_data->ccfl != 1024)) + return -1; ixheaacd_info_init(&ixheaacd_samp_rate_info[usac_data->sampling_rate_idx], usac_data->ccfl, usac_data->pstr_usac_winmap[0], usac_data->pstr_usac_winmap[2], usac_data->sfb_width_short, diff --git a/decoder/ixheaacd_decode_main.c b/decoder/ixheaacd_decode_main.c index efd867c..aefb4ba 100644 --- a/decoder/ixheaacd_decode_main.c +++ b/decoder/ixheaacd_decode_main.c @@ -268,6 +268,7 @@ WORD32 ixheaacd_dec_main(VOID *temp_handle, WORD8 *inbuffer, WORD8 *outbuffer, delay = ixheaacd_decode_create( handle, pstr_dec_data, pstr_dec_data->str_frame_data.scal_out_select + 1); + pstr_dec_data->dec_bit_buf.max_size = handle->p_mem_info_aac[IA_MEMTYPE_INPUT].ui_size; if (delay == -1) return -1; *num_channel_out = pstr_dec_data->str_frame_data.scal_out_num_channels; return 0; @@ -276,13 +277,14 @@ WORD32 ixheaacd_dec_main(VOID *temp_handle, WORD8 *inbuffer, WORD8 *outbuffer, pstr_dec_data->dec_bit_buf.ptr_bit_buf_base = (UWORD8 *)inbuffer; pstr_dec_data->dec_bit_buf.size = aac_dec_handle->ui_in_bytes << 3; pstr_dec_data->dec_bit_buf.ptr_bit_buf_end = - (UWORD8 *)inbuffer + aac_dec_handle->ui_in_bytes; + (UWORD8 *)inbuffer + aac_dec_handle->ui_in_bytes - 1; pstr_dec_data->dec_bit_buf.ptr_read_next = (UWORD8 *)inbuffer; pstr_dec_data->dec_bit_buf.bit_pos = 7; pstr_dec_data->dec_bit_buf.cnt_bits = pstr_dec_data->dec_bit_buf.size; pstr_dec_data->str_usac_data.usac_flag = aac_dec_handle->usac_flag; - + if (pstr_dec_data->dec_bit_buf.size > pstr_dec_data->dec_bit_buf.max_size) + pstr_dec_data->dec_bit_buf.max_size = pstr_dec_data->dec_bit_buf.size; /* audio pre roll frame parsing*/ do{ @@ -319,7 +321,7 @@ WORD32 ixheaacd_dec_main(VOID *temp_handle, WORD8 *inbuffer, WORD8 *outbuffer, return -1; /* call codec re-configure*/ - err = ixheaacd_config(config_bit_buf, &(pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config)/*&pstr_audio_specific_config->str_usac_config*/); + err = ixheaacd_config(config_bit_buf, &(pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config),&(pstr_audio_specific_config->channel_configuration)/*&pstr_audio_specific_config->str_usac_config*/); free(config_bit_buf); if (err != 0) return -1; @@ -335,7 +337,7 @@ WORD32 ixheaacd_dec_main(VOID *temp_handle, WORD8 *inbuffer, WORD8 *outbuffer, pstr_dec_data->dec_bit_buf.ptr_bit_buf_base = (UWORD8 *)inbuffer; pstr_dec_data->dec_bit_buf.size = aac_dec_handle->ui_in_bytes << 3; pstr_dec_data->dec_bit_buf.ptr_bit_buf_end = - (UWORD8 *)inbuffer + aac_dec_handle->ui_in_bytes; + (UWORD8 *)inbuffer + aac_dec_handle->ui_in_bytes - 1; pstr_dec_data->dec_bit_buf.ptr_read_next = (UWORD8 *)inbuffer; pstr_dec_data->dec_bit_buf.bit_pos = 7; pstr_dec_data->dec_bit_buf.cnt_bits = pstr_dec_data->dec_bit_buf.size; diff --git a/decoder/ixheaacd_env_extr.c b/decoder/ixheaacd_env_extr.c index 4d908af..2560701 100644 --- a/decoder/ixheaacd_env_extr.c +++ b/decoder/ixheaacd_env_extr.c @@ -107,7 +107,7 @@ VOID ixheaacd_huffman_decode(WORD32 it_bit_buff, WORD16 *h_index, WORD16 *len, *len = length; } -static VOID ixheaacd_read_esbr_pvc_envelope(ia_pvc_data_struct *ptr_pvc_data, +static WORD32 ixheaacd_read_esbr_pvc_envelope(ia_pvc_data_struct *ptr_pvc_data, ia_bit_buf_struct *it_bit_buff, WORD32 indepFlag) { WORD32 i, j, k; @@ -158,6 +158,10 @@ static VOID ixheaacd_read_esbr_pvc_envelope(ia_pvc_data_struct *ptr_pvc_data, length = (UWORD8)ixheaacd_read_bits_buf(it_bit_buff, length_bits); length += 1; sum_length += length; + if((k+length-1) > PVC_NUM_TIME_SLOTS) + { + return -1; + } for (j = 1; j < length; j++, k++) { pvc_id[k] = pvc_id[k - 1]; } @@ -221,6 +225,7 @@ static VOID ixheaacd_read_esbr_pvc_envelope(ia_pvc_data_struct *ptr_pvc_data, for (i = 0; i < PVC_NUM_TIME_SLOTS; i++) { ptr_pvc_data->pvc_id[i] = pvc_id[i]; } + return 0; } static VOID ixheaacd_pvc_env_dtdf_data( @@ -624,12 +629,13 @@ static WORD16 ixheaacd_read_extn_data( return 1; } -VOID ixheaacd_sbr_read_pvc_sce(ia_sbr_frame_info_data_struct *ptr_frame_data, +WORD32 ixheaacd_sbr_read_pvc_sce(ia_sbr_frame_info_data_struct *ptr_frame_data, ia_bit_buf_struct *it_bit_buff, WORD32 hbe_flag, ia_pvc_data_struct *ptr_pvc_data, ia_sbr_tables_struct *ptr_sbr_tables, ia_sbr_header_data_struct *ptr_header_data) { WORD32 i; + WORD32 err_code = 0; ia_env_extr_tables_struct *env_extr_tables_ptr = ptr_sbr_tables->env_extr_tables_ptr; WORD32 usac_independency_flag = ptr_frame_data->usac_independency_flag; @@ -651,7 +657,9 @@ VOID ixheaacd_sbr_read_pvc_sce(ia_sbr_frame_info_data_struct *ptr_frame_data, } } - ixheaacd_pvc_time_freq_grid_info(it_bit_buff, ptr_frame_data); + err_code = ixheaacd_pvc_time_freq_grid_info(it_bit_buff, ptr_frame_data); + if(err_code) + return err_code; ptr_pvc_data->prev_sbr_mode = PVC_SBR; @@ -679,6 +687,8 @@ VOID ixheaacd_sbr_read_pvc_sce(ia_sbr_frame_info_data_struct *ptr_frame_data, ixheaacd_read_sbr_addi_data(ptr_frame_data, ptr_header_data, it_bit_buff); ptr_frame_data->coupling_mode = COUPLING_OFF; + + return 0; } WORD8 ixheaacd_sbr_read_sce(ia_sbr_header_data_struct *ptr_header_data, @@ -1442,7 +1452,7 @@ int ixheaacd_extract_frame_info_ld( return 1; } -VOID ixheaacd_pvc_time_freq_grid_info( +WORD32 ixheaacd_pvc_time_freq_grid_info( ia_bit_buf_struct *it_bit_buff, ia_sbr_frame_info_data_struct *ptr_frame_data) { WORD32 bs_num_env = 0, bs_num_noise = 0; @@ -1475,7 +1485,8 @@ VOID ixheaacd_pvc_time_freq_grid_info( } else { time_border[0] = 0; } - + if(time_border[0] < 0) + return -1; pvc_time_border[0] = 0; bs_freq_res[0] = 0; @@ -1528,6 +1539,7 @@ VOID ixheaacd_pvc_time_freq_grid_info( for (i = 0; i < (bs_num_noise + 1); i++) { p_frame_info->noise_border_vec[i] = time_border_noise[i]; } + return 0; } WORD16 ixheaacd_sbr_time_freq_grid_info( diff --git a/decoder/ixheaacd_env_extr.h b/decoder/ixheaacd_env_extr.h index 9535217..5078d98 100644 --- a/decoder/ixheaacd_env_extr.h +++ b/decoder/ixheaacd_env_extr.h @@ -141,7 +141,7 @@ WORD32 ixheaacd_ssc_huff_dec(ia_huffman_data_type h, int ixheaacd_extract_frame_info_ld(ia_bit_buf_struct *it_bit_buff, ia_sbr_frame_info_data_struct *h_frame_data); -VOID ixheaacd_pvc_time_freq_grid_info( +WORD32 ixheaacd_pvc_time_freq_grid_info( ia_bit_buf_struct *it_bit_buff, ia_sbr_frame_info_data_struct *ptr_frame_data); diff --git a/decoder/ixheaacd_esbr_polyphase.c b/decoder/ixheaacd_esbr_polyphase.c index 591cf2d..169231c 100644 --- a/decoder/ixheaacd_esbr_polyphase.c +++ b/decoder/ixheaacd_esbr_polyphase.c @@ -46,7 +46,7 @@ #include "string.h" -VOID ixheaacd_complex_anal_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer) { +WORD32 ixheaacd_complex_anal_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer) { WORD32 idx; WORD32 anal_size = 2 * ptr_hbe_txposer->synth_size; WORD32 N = (10 * anal_size); @@ -120,8 +120,10 @@ VOID ixheaacd_complex_anal_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer) { *ptr_u++ = ((*analy_cos_sin_tab++) * u[k]); *ptr_u++ = ((*analy_cos_sin_tab++) * u[k]); } - - (*ixheaacd_cmplx_anal_fft)(u_in, u_out, anal_size * 2); + if(ixheaacd_cmplx_anal_fft != NULL) + (*ixheaacd_cmplx_anal_fft)(u_in, u_out, anal_size * 2); + else + return -1; for (k = 0; k < anal_size / 2; k++) { *(anal_buf + 1) = -*ptr_v++; @@ -136,9 +138,10 @@ VOID ixheaacd_complex_anal_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer) { } } } + return 0; } -VOID ixheaacd_real_synth_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, +WORD32 ixheaacd_real_synth_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, WORD32 num_columns, FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64]) { WORD32 i, j, k, l, idx; @@ -159,7 +162,8 @@ VOID ixheaacd_real_synth_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, (idx + 1) * ptr_hbe_txposer->synth_size; FLOAT32 *synth_cos_tab = ptr_hbe_txposer->synth_cos_tab; const FLOAT32 *interp_window_coeff = ptr_hbe_txposer->synth_wind_coeff; - + if(ptr_hbe_txposer->k_start < 0) + return -1; for (k = 0; k < synth_size; k++) { WORD32 ki = ptr_hbe_txposer->k_start + k; synth_buf_r[k] = (FLOAT32)( @@ -206,7 +210,10 @@ VOID ixheaacd_real_synth_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, FLOAT32 *syn_buf = &buffer[kmax]; kmax += synth_size; - (*ixheaacd_real_synth_fft)(synth_buf_r, synth_out, synth_size * 2); + if(ixheaacd_real_synth_fft != NULL) + (*ixheaacd_real_synth_fft)(synth_buf_r, synth_out, synth_size * 2); + else + return -1; for (k = 0; k < kmax; k++) { tmp = ((*ptr_u++) * (*synth_cos_tab++)); @@ -243,4 +250,5 @@ VOID ixheaacd_real_synth_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, out_buf[i] = (FLOAT32)accu_r; } } + return 0; } diff --git a/decoder/ixheaacd_hbe_trans.c b/decoder/ixheaacd_hbe_trans.c index 656f3dd..30ae800 100644 --- a/decoder/ixheaacd_hbe_trans.c +++ b/decoder/ixheaacd_hbe_trans.c @@ -99,7 +99,7 @@ static FLOAT32 *ixheaacd_map_prot_filter(WORD32 filt_length) { } } -VOID ixheaacd_qmf_hbe_data_reinit(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, +WORD32 ixheaacd_qmf_hbe_data_reinit(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, WORD16 *p_freq_band_tab[2], WORD16 *p_num_sfb, WORD32 upsamp_4_flag) { WORD32 synth_size, sfb, patch, stop_patch; @@ -214,9 +214,14 @@ VOID ixheaacd_qmf_hbe_data_reinit(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, } } } + if(ptr_hbe_txposer->k_start < 0) + { + return -1; + } + return 0; } -VOID ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, +WORD32 ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64], WORD32 num_columns, FLOAT32 pv_qmf_buf_real[][64], @@ -224,6 +229,7 @@ VOID ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, WORD32 pitch_in_bins) { WORD32 i, qmf_band_idx; WORD32 qmf_voc_columns = ptr_hbe_txposer->no_bins / 2; + WORD32 err_code = 0; memcpy(ptr_hbe_txposer->ptr_input_buf, ptr_hbe_txposer->ptr_input_buf + @@ -239,7 +245,9 @@ VOID ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, TWICE_QMF_SYNTH_CHANNELS_NUM * sizeof(FLOAT32)); } - ixheaacd_complex_anal_filt(ptr_hbe_txposer); + err_code = ixheaacd_complex_anal_filt(ptr_hbe_txposer); + if(err_code) + return err_code; for (i = 0; i < (ptr_hbe_txposer->hbe_qmf_out_len - ptr_hbe_txposer->no_bins); i++) { @@ -272,6 +280,7 @@ VOID ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, ixheaacd_phase_vocoder_cos_table[qmf_band_idx]); } } + return 0; } VOID ixheaacd_norm_qmf_in_buf_4(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, diff --git a/decoder/ixheaacd_headerdecode.c b/decoder/ixheaacd_headerdecode.c index 3f504c2..7208525 100644 --- a/decoder/ixheaacd_headerdecode.c +++ b/decoder/ixheaacd_headerdecode.c @@ -604,7 +604,7 @@ WORD32 ixheaacd_ga_hdr_dec(ia_aac_dec_state_struct *aac_state_struct, ixheaacd_conf_default(&(pstr_audio_specific_config->str_usac_config)); err = ixheaacd_config(it_bit_buff, - &(pstr_audio_specific_config->str_usac_config)); + &(pstr_audio_specific_config->str_usac_config),&(pstr_audio_specific_config->channel_configuration)); if (err != 0) return -1; if (pstr_audio_specific_config->audio_object_type == AOT_USAC) { diff --git a/decoder/ixheaacd_init_config.c b/decoder/ixheaacd_init_config.c index 5555736..fe02d9b 100644 --- a/decoder/ixheaacd_init_config.c +++ b/decoder/ixheaacd_init_config.c @@ -249,6 +249,8 @@ WORD32 ixheaacd_ext_element_config( ixheaacd_read_escape_value(it_bit_buff, &(usac_ext_element_config_length), 4, 8, 16); + if(usac_ext_element_config_length >= 768) + return -1; flag = ixheaacd_read_bits_buf(it_bit_buff, 1); @@ -366,7 +368,7 @@ VOID ixheaacd_cpe_config( WORD32 ixheaacd_decoder_config( ia_bit_buf_struct *it_bit_buff, ia_usac_decoder_config_struct *pstr_usac_decoder_config, - WORD32 sbr_ratio_index) { + WORD32 sbr_ratio_index, UINT32 *chan) { UWORD32 elem_idx = 0; UWORD32 err = 0; @@ -404,6 +406,9 @@ WORD32 ixheaacd_decoder_config( case ID_USAC_CPE: ixheaacd_cpe_config(it_bit_buff, pstr_usac_element_config, sbr_ratio_index); + if (pstr_usac_element_config->stereo_config_index > 1 && *chan <2) + return -1; + break; case ID_USAC_LFE: @@ -494,7 +499,7 @@ WORD32 ixheaacd_config_extension( } WORD32 ixheaacd_config(ia_bit_buf_struct *it_bit_buff, - ia_usac_config_struct *pstr_usac_conf) { + ia_usac_config_struct *pstr_usac_conf, UINT32 *chan) { WORD32 tmp, err; err = 0; @@ -534,7 +539,7 @@ WORD32 ixheaacd_config(ia_bit_buf_struct *it_bit_buff, err = ixheaacd_decoder_config( it_bit_buff, &(pstr_usac_conf->str_usac_dec_config), - ixheaacd_sbr_ratio(pstr_usac_conf->core_sbr_framelength_index)); + ixheaacd_sbr_ratio(pstr_usac_conf->core_sbr_framelength_index),chan); if (err != 0) return -1; tmp = ixheaacd_read_bits_buf(it_bit_buff, 1); diff --git a/decoder/ixheaacd_lpc.c b/decoder/ixheaacd_lpc.c index 0d753a6..ca0546f 100644 --- a/decoder/ixheaacd_lpc.c +++ b/decoder/ixheaacd_lpc.c @@ -413,7 +413,10 @@ WORD32 ixheaacd_lpd_dec(ia_usac_data_struct *usac_data, } else { fac_length = len_subfrm / 2; } - + if((pstr_td_frame_data->fac_data[0] < 0) || (pstr_td_frame_data->fac_data[0] > 128)) + { + return -1; + } gain = ixheaacd_pow_10_i_by_128[pstr_td_frame_data->fac_data[0]]; memcpy(ptr_scratch, &pstr_td_frame_data->fac_data[0], @@ -699,6 +702,14 @@ WORD32 ixheaacd_lpd_bpf_fix(ia_usac_data_struct *usac_data, WORD32 is_short_flag for (i = 0; i < num_subfr_by2 + 2; i++) { tp = pitch[i]; + if((i * LEN_SUBFR + MAX_PITCH) < tp) + { + return -1; + } + else if((i * LEN_SUBFR + MAX_PITCH - tp) >= 1883) + { + return -1; + } if (pitch_gain[i] > 0.0f) { synth_corr = 0.0f, synth_energy = 1e-6f; for (k = 0; k < LEN_SUBFR; k++) { diff --git a/decoder/ixheaacd_process.c b/decoder/ixheaacd_process.c index 67037a3..ba4558b 100644 --- a/decoder/ixheaacd_process.c +++ b/decoder/ixheaacd_process.c @@ -88,6 +88,8 @@ #include "ixheaacd_pvc_dec.h" #include "ixheaacd_sbr_dec.h" +#include "ixheaacd_error_codes.h" + #define MAXNRSBRELEMENTS 6 VOID ixheaacd_allocate_sbr_scr(ia_sbr_scr_struct *sbr_scratch_struct, @@ -107,7 +109,7 @@ WORD16 ixheaacd_esbr_process(ia_usac_data_struct *usac_data, ia_bit_buf_struct *it_bit_buff, WORD32 stereo_config_idx, WORD16 num_channels, WORD32 audio_object_type) { - WORD16 err_code; + WORD16 err_code = 0; ia_aac_dec_sbr_bitstream_struct *esbr_bit_str = &usac_data->esbr_bit_str[0]; ia_handle_sbr_dec_inst_struct self = usac_data->pstr_esbr_dec; @@ -164,7 +166,7 @@ static VOID ixheaacd_sbr_ext_data_read( } } -static VOID ixheaacd_read_ext_element( +static WORD32 ixheaacd_read_ext_element( UWORD32 usac_ext_element_default_length, UWORD32 usac_ext_element_payload_frag, ia_bit_buf_struct *it_bit_buff , @@ -190,7 +192,8 @@ static VOID ixheaacd_read_ext_element( pay_load_length = (UWORD32)((WORD32)pay_load_length + val_add - 2); } } - + if ((it_bit_buff->cnt_bits >> 3) < (WORD32)pay_load_length) + return IA_ENHAACPLUS_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES; if (pay_load_length > 0) { if (usac_ext_element_payload_frag) tmp = ixheaacd_read_bits_buf(it_bit_buff, 2); @@ -212,6 +215,7 @@ static VOID ixheaacd_read_ext_element( } } } + return 0; } static VOID ixheaacd_sbr_ele_type_set( @@ -268,6 +272,7 @@ VOID ixheaacd_ms_processing(ia_usac_data_struct *pstr_usac_data) { WORD32 ixheaacd_usac_process(ia_dec_data_struct *pstr_dec_data, WORD32 *num_out_channels, VOID *codec_handle) { WORD32 ele_id = 0; + WORD32 err_code = 0; ia_aac_dec_state_struct *p_state_aac_dec = (ia_aac_dec_state_struct *)codec_handle; @@ -308,11 +313,15 @@ WORD32 ixheaacd_usac_process(ia_dec_data_struct *pstr_dec_data, case ID_USAC_CPE: nr_core_coder_channels = (stereo_config_index == 1) ? 1 : 2; + if((stereo_config_index > 1) && (p_state_aac_dec->num_of_output_ch<2)) + return -1; goto core_data_extracting; case ID_USAC_LFE: nr_core_coder_channels = 1; core_data_extracting: + if(ch_offset >= MAX_NUM_CHANNELS) + return -1; err = ixheaacd_core_coder_data(ele_id, pstr_usac_data, elem_idx, &ch_offset, it_bit_buff, nr_core_coder_channels); @@ -333,10 +342,12 @@ WORD32 ixheaacd_usac_process(ia_dec_data_struct *pstr_dec_data, if ((pstr_usac_data->sbr_ratio_idx > 0) && (pstr_usac_data->esbr_bit_str[0].no_elements != 0)) { - ixheaacd_esbr_process( + err_code = ixheaacd_esbr_process( pstr_usac_data, it_bit_buff, stereo_config_index, nr_core_coder_channels, pstr_dec_data->str_usac_data.audio_object_type); + if(err_code < 0) + return err_code; } if (stereo_config_index > 0) { @@ -387,11 +398,13 @@ WORD32 ixheaacd_usac_process(ia_dec_data_struct *pstr_dec_data, case ID_USAC_EXT: { ia_usac_dec_element_config_struct *pusac_element_config = &pstr_usac_dec_config->str_usac_element_config[elem_idx]; - ixheaacd_read_ext_element(pusac_element_config->usac_ext_eleme_def_len, + err = ixheaacd_read_ext_element(pusac_element_config->usac_ext_eleme_def_len, pusac_element_config->usac_ext_elem_pld_frag, it_bit_buff, pstr_usac_dec_config, elem_idx ); + if (err != 0) + return err; break; } diff --git a/decoder/ixheaacd_qmf_dec.c b/decoder/ixheaacd_qmf_dec.c index fbfa4b2..a01b8ec 100644 --- a/decoder/ixheaacd_qmf_dec.c +++ b/decoder/ixheaacd_qmf_dec.c @@ -45,6 +45,7 @@ #include "ixheaacd_env_calc.h" #include "ixheaacd_interface.h" + #include "ixheaacd_function_selector.h" #include "ixheaacd_audioobjtypes.h" @@ -69,189 +70,29 @@ static PLATFORM_INLINE WORD32 ixheaacd_mult32x32in32_shift25(WORD32 a, return (result); } -VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output, - const WORD16 *main_twidle_fwd, const WORD16 *post_tbl, - const WORD16 *w_16, const WORD32 *p_table) { - WORD32 n, k; +VOID ixheaacd_pretwdct2(WORD32 *inp, WORD32 *out_fwd) { + WORD32 n; + WORD32 *out_rev = out_fwd + DCT2_LEN - 1; - WORD32 temp1[6]; - WORD32 temp2[4]; - WORD16 twid_re, twid_im; - WORD32 *ptr_reverse, *ptr_forward, *p_out, *ptr_out1; - const WORD16 *twidle_fwd, *twidle_rev; + for (n = 0; n < DCT2_LEN / 2; n++) { + *out_fwd = *inp; + inp++; + *out_rev = *inp; + out_fwd++; - ptr_forward = &input[49]; - ptr_reverse = &input[47]; - - p_out = output; - twidle_fwd = main_twidle_fwd; - twidle_fwd += 4; - - *p_out++ = input[48] >> LP_SHIFT_VAL; - *p_out++ = 0; - - for (n = 1; n < DCT3_LEN / 2; n++) { - temp1[0] = *ptr_forward++; - temp1[1] = *ptr_reverse--; - temp1[0] = ixheaacd_add32(ixheaacd_shr32(temp1[0], LP_SHIFT_VAL), - ixheaacd_shr32(temp1[1], LP_SHIFT_VAL)); - - temp1[2] = *(ptr_forward - 33); - temp1[3] = *(ptr_reverse - 31); - temp1[1] = ixheaacd_sub32(ixheaacd_shr32(temp1[2], LP_SHIFT_VAL), - ixheaacd_shr32(temp1[3], LP_SHIFT_VAL)); - twid_re = *twidle_fwd++; - - twid_im = *twidle_fwd; - twidle_fwd += 3; - - *p_out++ = ixheaacd_mult32x16in32(temp1[0], twid_re) + - ixheaacd_mult32x16in32(temp1[1], twid_im); - *p_out++ = -ixheaacd_mult32x16in32(temp1[1], twid_re) + - ixheaacd_mult32x16in32(temp1[0], twid_im); - } - - twid_re = *twidle_fwd++; - - twid_im = *twidle_fwd; - twidle_fwd += 3; - - temp1[1] = *ptr_reverse--; - temp1[0] = *(ptr_reverse - 31); - temp1[1] = ixheaacd_sub32(ixheaacd_shr32(temp1[1], LP_SHIFT_VAL), - ixheaacd_shr32(temp1[0], LP_SHIFT_VAL)); - - temp1[0] = temp1[1]; - - temp2[2] = ixheaacd_mult32x16in32(temp1[0], twid_re) + - ixheaacd_mult32x16in32(temp1[1], twid_im); - temp2[3] = -ixheaacd_mult32x16in32(temp1[1], twid_re) + - ixheaacd_mult32x16in32(temp1[0], twid_im); - - ptr_forward = output; - ptr_reverse = &output[DCT3_LEN - 1]; - - temp2[0] = *ptr_forward++; - temp2[1] = *ptr_forward--; - - temp1[0] = -temp2[1] - temp2[3]; - temp1[1] = temp2[0] - temp2[2]; - temp2[0] = (temp2[0] + temp2[2] + temp1[0]); - temp2[1] = (temp2[1] - temp2[3] + temp1[1]); - - temp2[0] >>= 1; - temp2[1] >>= 1; - - *ptr_forward++ = temp2[0]; - *ptr_forward++ = temp2[1]; - - twidle_fwd = post_tbl + 2; - twidle_rev = post_tbl + 14; - - for (n = 1; n < DCT3_LEN / 4; n++) { - temp2[0] = *ptr_forward++; - temp2[1] = *ptr_forward--; - temp2[3] = *ptr_reverse--; - temp2[2] = *ptr_reverse++; - - twid_re = *twidle_rev; - twidle_rev -= 2; - twid_im = *twidle_fwd; - twidle_fwd += 2; - - temp1[0] = temp2[0] - temp2[2]; - temp1[1] = (temp2[0] + temp2[2]); - - temp1[2] = temp2[1] + temp2[3]; - temp1[3] = (temp2[1] - temp2[3]); - - temp1[4] = ixheaacd_mult32x16in32(temp1[0], twid_re) + - ixheaacd_mult32x16in32(temp1[2], twid_im); - temp1[5] = -ixheaacd_mult32x16in32(temp1[2], twid_re) + - ixheaacd_mult32x16in32(temp1[0], twid_im); - - temp1[1] >>= 1; - temp1[3] >>= 1; - - *ptr_forward++ = temp1[1] - temp1[4]; - *ptr_forward++ = temp1[3] + temp1[5]; - - *ptr_reverse-- = -temp1[3] + temp1[5]; - *ptr_reverse-- = temp1[1] + temp1[4]; - } - temp2[0] = *ptr_forward++; - temp2[1] = *ptr_forward--; - temp2[3] = *ptr_reverse--; - temp2[2] = *ptr_reverse++; - - twid_re = -*twidle_rev; - twidle_rev -= 2; - twid_im = *twidle_fwd; - twidle_fwd += 2; - - temp1[0] = temp2[0] - temp2[2]; - temp1[1] = (temp2[0] + temp2[2]); - - temp1[2] = temp2[1] + temp2[3]; - temp1[3] = (temp2[1] - temp2[3]); - - temp1[4] = ixheaacd_mult32x16in32(temp1[0], twid_re) - - ixheaacd_mult32x16in32(temp1[2], twid_im); - temp1[5] = ixheaacd_mult32x16in32(temp1[2], twid_re) + - ixheaacd_mult32x16in32(temp1[0], twid_im); - - temp1[1] >>= 1; - temp1[3] >>= 1; - *ptr_forward++ = temp1[1] + temp1[4]; - *ptr_forward++ = temp1[3] + temp1[5]; - - ixheaacd_radix4bfly(w_16, output, 1, 4); - ixheaacd_postradixcompute4(input, output, p_table, 16); - - output[0] = input[0]; - output[2] = input[1]; - - p_out = input + 2; - ptr_forward = output + 1; - ptr_reverse = output + 30; - ptr_out1 = input + 18; - - for (k = (DCT3_LEN / 4) - 1; k != 0; k--) { - WORD32 tempre, tempim; - - tempre = *p_out++; - tempim = *p_out++; - *ptr_forward = (tempim); - ptr_forward += 2; - *ptr_forward = (tempre); - ptr_forward += 2; - - tempre = *ptr_out1++; - tempim = *ptr_out1++; - *ptr_reverse = (tempim); - ptr_reverse -= 2; - *ptr_reverse = (tempre); - ptr_reverse -= 2; - } - - { - WORD32 tempre, tempim; - tempre = *p_out++; - tempim = *p_out++; - *ptr_forward = (tempim); - ptr_forward += 2; - *ptr_forward = (tempre); - ptr_forward += 2; + out_rev--; + inp++; } return; } -static PLATFORM_INLINE VOID ixheaacd_pretwdct2(WORD32 *inp, WORD32 *out_fwd) { +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 = 0; n < DCT2_LEN / 2; 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; @@ -369,42 +210,6 @@ VOID ixheaacd_posttwdct2(WORD32 *inp, WORD16 *out_fwd, return; } -VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, - WORD16 *filter_states) { - ixheaacd_pretwdct2(x, X); - - ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_32, X, 1, 8); - - ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_32 + 48, X, 4, 2); - - ixheaacd_postradixcompute2(x, X, qmf_dec_tables_ptr->dig_rev_table2_32, 32); - - ixheaacd_fftposttw(x, qmf_dec_tables_ptr); - - ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr); - - 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; -} - static PLATFORM_INLINE VOID ixheaacd_fftposttw_32( WORD32 *out, int dct2_len, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { int k; @@ -463,7 +268,6 @@ static PLATFORM_INLINE VOID ixheaacd_fftposttw_32( return; } - static PLATFORM_INLINE VOID ixheaacd_posttwdct2_32(WORD32 *inp, WORD16 *out_fwd, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { @@ -552,320 +356,11 @@ VOID ixheaacd_dct2_32(WORD32 *inp, WORD32 *out, return; } -VOID ixheaacd_cos_sin_mod(WORD32 *subband, - ia_sbr_qmf_filter_bank_struct *qmf_bank, - WORD16 *p_twiddle, WORD32 *p_dig_rev_tbl) { - WORD32 re2, re3; - WORD16 wim, wre; - - WORD32 i, M_2; - WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); - - const WORD16 *p_sin; - const WORD16 *p_sin_cos = &qmf_bank->cos_twiddle[0]; - WORD32 subband_tmp[128]; - WORD32 re; - WORD32 im; - WORD32 *psubband, *psubband1; - WORD32 *psubband_t, *psubband1_t; - WORD32 *psubband2, *psubband12; - WORD32 *psubband_t2, *psubband1_t2; - - M_2 = ixheaacd_shr32(M, 1); - - psubband = &subband[0]; - psubband1 = &subband[2 * M - 1]; - psubband_t = subband_tmp; - psubband1_t = &subband_tmp[2 * M - 1]; - - psubband2 = &subband[64]; - psubband12 = &subband[2 * M - 1 + 64]; - psubband_t2 = &subband_tmp[64]; - psubband1_t2 = &subband_tmp[2 * M - 1 + 64]; - - for (i = (M_2 >> 1) - 1; i >= 0; i--) { - re = *psubband++; - im = *psubband1--; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband_t++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), - ixheaacd_mult32x16in32(im, wim)); - *psubband_t++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), - ixheaacd_mult32x16in32(re, wim)); - - re = *psubband2++; - im = *psubband12--; - - *psubband_t2++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), - ixheaacd_mult32x16in32(re, wre)); - *psubband_t2++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), - ixheaacd_mult32x16in32(im, wre)); - - re = *psubband1--; - im = *psubband++; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband1_t-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), - ixheaacd_mult32x16in32(re, wim)); - *psubband1_t-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), - ixheaacd_mult32x16in32(im, wim)); - - re = *psubband12--; - im = *psubband2++; - - *psubband1_t2-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), - ixheaacd_mult32x16in32(im, wre)); - *psubband1_t2-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), - ixheaacd_mult32x16in32(re, wre)); - - re = *psubband++; - im = *psubband1--; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband_t++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), - ixheaacd_mult32x16in32(im, wim)); - *psubband_t++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), - ixheaacd_mult32x16in32(re, wim)); - - re = *psubband2++; - im = *psubband12--; - - *psubband_t2++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), - ixheaacd_mult32x16in32(re, wre)); - *psubband_t2++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), - ixheaacd_mult32x16in32(im, wre)); - - re = *psubband1--; - im = *psubband++; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband1_t-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), - ixheaacd_mult32x16in32(re, wim)); - *psubband1_t-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), - ixheaacd_mult32x16in32(im, wim)); - - re = *psubband12--; - im = *psubband2++; - ; - - *psubband1_t2-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), - ixheaacd_mult32x16in32(im, wre)); - *psubband1_t2-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), - ixheaacd_mult32x16in32(re, wre)); - } - - if (M == 32) { - ixheaacd_radix4bfly(p_twiddle, subband_tmp, 1, 8); - ixheaacd_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2); - ixheaacd_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32); - - ixheaacd_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8); - ixheaacd_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2); - ixheaacd_postradixcompute2(&subband[64], &subband_tmp[64], p_dig_rev_tbl, - 32); - - } else { - ixheaacd_radix4bfly(p_twiddle, subband_tmp, 1, 4); - ixheaacd_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16); - - ixheaacd_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4); - ixheaacd_postradixcompute4(&subband[64], &subband_tmp[64], p_dig_rev_tbl, - 16); - } - - psubband = &subband[0]; - psubband1 = &subband[2 * M - 1]; - - re = *psubband1; - - *psubband = *psubband >> 1; - psubband++; - *psubband1 = ixheaacd_negate32(*psubband >> 1); - psubband1--; - - p_sin = &qmf_bank->alt_sin_twiddle[0]; - wim = *p_sin++; - wre = *p_sin++; - - im = *psubband1; - - *psubband1-- = ixheaacd_add32(ixheaacd_mult32x16in32(re, wre), - ixheaacd_mult32x16in32(im, wim)); - *psubband++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), - ixheaacd_mult32x16in32(re, wim)); - - psubband2 = &subband[64]; - psubband12 = &subband[2 * M - 1 + 64]; - - re = *psubband12; - - *psubband12-- = ixheaacd_negate32_sat(*psubband2 >> 1); - - *psubband2 = psubband2[1] >> 1; - - psubband2++; - - im = *psubband12; - - *psubband2++ = ixheaacd_negate32_sat(ixheaacd_add32( - ixheaacd_mult32x16in32(re, wre), ixheaacd_mult32x16in32(im, wim))); - *psubband12-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(re, wim), - ixheaacd_mult32x16in32(im, wre)); - - for (i = (M_2 - 2); i >= 0; i--) { - im = psubband[0]; - - re = psubband[1]; - - re2 = *psubband1; - - *psubband++ = ixheaacd_add32(ixheaacd_mult32x16in32(re, wim), - ixheaacd_mult32x16in32(im, wre)); - *psubband1-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wim), - ixheaacd_mult32x16in32(re, wre)); - - im = psubband2[0]; - - re = psubband2[1]; - - re3 = *psubband12; - - *psubband12-- = ixheaacd_negate32_sat(ixheaacd_add32( - ixheaacd_mult32x16in32(re, wim), ixheaacd_mult32x16in32(im, wre))); - *psubband2++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(re, wre), - ixheaacd_mult32x16in32(im, wim)); - - wim = *p_sin++; - wre = *p_sin++; - im = psubband1[0]; - - *psubband1-- = ixheaacd_add32(ixheaacd_mult32x16in32(re2, wre), - ixheaacd_mult32x16in32(im, wim)); - *psubband++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(im, wre), - ixheaacd_mult32x16in32(re2, wim)); - - im = psubband12[0]; - - *psubband2++ = ixheaacd_negate32_sat(ixheaacd_add32( - ixheaacd_mult32x16in32(re3, wre), ixheaacd_mult32x16in32(im, wim))); - *psubband12-- = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(re3, wim), - ixheaacd_mult32x16in32(im, wre)); - } -} - -VOID ixheaacd_fwd_modulation(const WORD32 *p_time_in1, WORD32 *real_subband, - WORD32 *imag_subband, - ia_sbr_qmf_filter_bank_struct *qmf_bank, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { - WORD32 i; - const WORD32 *p_time_in2 = &p_time_in1[2 * NO_ANALYSIS_CHANNELS - 1]; - WORD32 temp1, temp2; - WORD32 *t_real_subband = real_subband; - WORD32 *t_imag_subband = imag_subband; - const WORD16 *tcos; - - for (i = NO_ANALYSIS_CHANNELS - 1; i >= 0; i--) { - temp1 = ixheaacd_shr32(*p_time_in1++, HQ_SHIFT_VAL); - temp2 = ixheaacd_shr32(*p_time_in2--, HQ_SHIFT_VAL); - - *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2); - - *t_imag_subband++ = ixheaacd_add32(temp1, temp2); - } - - ixheaacd_cos_sin_mod(real_subband, qmf_bank, qmf_dec_tables_ptr->w_16, - qmf_dec_tables_ptr->dig_rev_table4_16); - - tcos = qmf_bank->t_cos; - - for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) { - WORD16 cosh, sinh; - WORD32 re, im; - - re = *real_subband; - im = *imag_subband; - cosh = *tcos++; - sinh = *tcos++; - *real_subband++ = ixheaacd_add32(ixheaacd_mult32x16in32_shl(re, cosh), - ixheaacd_mult32x16in32_shl(im, sinh)); - *imag_subband++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32_shl(im, cosh), - ixheaacd_mult32x16in32_shl(re, sinh)); - } -} - -VOID ixheaacd_sbr_qmfanal32_winadd(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[2 * (n + 0)]); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp1[n + 64], p_qmf1[2 * (n + 64)])); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp1[n + 128], p_qmf1[2 * (n + 128)])); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp1[n + 192], p_qmf1[2 * (n + 192)])); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp1[n + 256], p_qmf1[2 * (n + 256)])); - p_out[n] = accu; - - accu = ixheaacd_mult16x16in32(inp1[n + 1 + 0], p_qmf1[2 * (n + 1 + 0)]); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp1[n + 1 + 64], p_qmf1[2 * (n + 1 + 64)])); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp1[n + 1 + 128], p_qmf1[2 * (n + 1 + 128)])); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp1[n + 1 + 192], p_qmf1[2 * (n + 1 + 192)])); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp1[n + 1 + 256], p_qmf1[2 * (n + 1 + 256)])); - p_out[n + 1] = accu; - - accu = ixheaacd_mult16x16in32(inp2[n + 0], p_qmf2[2 * (n + 0)]); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp2[n + 64], p_qmf2[2 * (n + 64)])); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp2[n + 128], p_qmf2[2 * (n + 128)])); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp2[n + 192], p_qmf2[2 * (n + 192)])); - accu = ixheaacd_add32( - accu, ixheaacd_mult16x16in32(inp2[n + 256], p_qmf2[2 * (n + 256)])); - p_out[n + 32] = accu; - - accu = ixheaacd_mult16x16in32(inp2[n + 1 + 0], p_qmf2[2 * (n + 1 + 0)]); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp2[n + 1 + 64], p_qmf2[2 * (n + 1 + 64)])); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp2[n + 1 + 128], p_qmf2[2 * (n + 1 + 128)])); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp2[n + 1 + 192], p_qmf2[2 * (n + 1 + 192)])); - accu = ixheaacd_add32_sat( - accu, - ixheaacd_mult16x16in32(inp2[n + 1 + 256], p_qmf2[2 * (n + 1 + 256)])); - p_out[n + 1 + 32] = accu; - } -} - 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)]); @@ -1110,819 +605,6 @@ VOID ixheaacd_esbr_qmfanal32_winadd(WORD32 *inp1, WORD32 *inp2, WORD32 *p_qmf1, } } -VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf, - ia_sbr_scale_fact_struct *sbr_scale_factor, - WORD32 **qmf_real, WORD32 **qmf_imag, - ia_sbr_qmf_filter_bank_struct *qmf_bank, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, - WORD32 ch_fac, WORD32 low_pow_flag, - WORD audio_object_type) { - WORD32 i, k; - WORD32 num_time_slots = qmf_bank->num_time_slots; - - WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS]; - WORD16 *filter_states = qmf_bank->core_samples_buffer; - - WORD16 *fp1, *fp2, *tmp; - - WORD16 *filter_1; - WORD16 *filter_2; - WORD16 *filt_ptr; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - qmf_bank->filter_pos += - (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff); - qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c; - } else { - qmf_bank->filter_pos += - (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff); - qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3; - } - - filter_1 = qmf_bank->filter_pos; - - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - filter_2 = filter_1 + 64; - } else { - filter_2 = filter_1 + 32; - } - - sbr_scale_factor->st_lb_scale = 0; - sbr_scale_factor->lb_scale = -10; - if (!low_pow_flag) { - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - sbr_scale_factor->lb_scale = -8; - } else { - sbr_scale_factor->lb_scale = -9; - } - qmf_bank->cos_twiddle = - (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32; - qmf_bank->alt_sin_twiddle = - (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32; - } else { - qmf_bank->t_cos = - (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld; - } - } - - fp1 = qmf_bank->anal_filter_states; - fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS; - - if (audio_object_type == AOT_ER_AAC_ELD || - audio_object_type == AOT_ER_AAC_LD) { - filter_2 = qmf_bank->filter_2; - fp1 = qmf_bank->fp1_anal; - fp2 = qmf_bank->fp2_anal; - } - - for (i = 0; i < num_time_slots; i++) { - for (k = 0; k < NO_ANALYSIS_CHANNELS; k++) - filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k]; - - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - ixheaacd_sbr_qmfanal32_winadd(fp1, fp2, filter_1, filter_2, - analysis_buffer); - } else { - ixheaacd_sbr_qmfanal32_winadd_eld(fp1, fp2, filter_1, filter_2, - analysis_buffer); - } - - time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac; - - filter_states -= NO_ANALYSIS_CHANNELS; - if (filter_states < qmf_bank->anal_filter_states) { - filter_states = qmf_bank->anal_filter_states + 288; - } - - tmp = fp1; - fp1 = fp2; - fp2 = tmp; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - filter_1 += 64; - filter_2 += 64; - } else { - filter_1 += 32; - filter_2 += 32; - } - - filt_ptr = filter_1; - filter_1 = filter_2; - filter_2 = filt_ptr; - if (audio_object_type != AOT_ER_AAC_ELD && - audio_object_type != AOT_ER_AAC_LD) { - if (filter_2 > (qmf_bank->analy_win_coeff + 640)) { - filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; - filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64; - } - } else { - if (filter_2 > (qmf_bank->analy_win_coeff + 320)) { - filter_1 = (WORD16 *)qmf_bank->analy_win_coeff; - filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32; - } - } - - if (!low_pow_flag) { - ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i], - qmf_bank, qmf_dec_tables_ptr); - } else { - ixheaacd_dct3_32( - (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw, - qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16, - qmf_dec_tables_ptr->dig_rev_table4_16); - } - } - - qmf_bank->filter_pos = filter_1; - qmf_bank->core_samples_buffer = filter_states; - - if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD) - - { - qmf_bank->fp1_anal = fp1; - qmf_bank->fp2_anal = fp2; - qmf_bank->filter_2 = filter_2; - } -} - -static PLATFORM_INLINE VOID -ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, - ia_sbr_qmf_filter_bank_struct *syn_qmf, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { - WORD32 L = syn_qmf->no_channels; - const WORD32 M = (L >> 1); - WORD32 *dct_in = qmf_real; - WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS]; - - WORD32 *ptime_out = &time_out[0]; - - if (L == 64) - ixheaacd_dct2_64(dct_in, ptime_out, qmf_dec_tables_ptr, filter_states + M); - else - ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states); - - filter_states[3 * M] = 0; -} - -static VOID ixheaacd_inv_emodulation( - WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { - if (syn_qmf->no_channels == 64) - ixheaacd_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->w_32, - qmf_dec_tables_ptr->dig_rev_table2_32); - else - ixheaacd_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->w_16, - qmf_dec_tables_ptr->dig_rev_table4_16); -} - -VOID ixheaacd_esbr_radix4bfly(const WORD32 *w, WORD32 *x, WORD32 index1, - WORD32 index) { - int i; - WORD32 l1, l2, h2, fft_jmp; - WORD32 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0; - WORD32 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0; - WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1; - WORD32 x_h2_0, x_h2_1; - WORD32 si10, si20, si30, co10, co20, co30; - - WORD64 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6; - WORD64 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12; - WORD32 *x_l1; - WORD32 *x_l2; - WORD32 *x_h2; - const WORD32 *w_ptr = w; - WORD32 i1; - - h2 = index << 1; - l1 = index << 2; - l2 = (index << 2) + (index << 1); - - x_l1 = &(x[l1]); - x_l2 = &(x[l2]); - x_h2 = &(x[h2]); - - fft_jmp = 6 * (index); - - for (i1 = 0; i1 < index1; i1++) { - for (i = 0; i < index; i++) { - si10 = (*w_ptr++); - co10 = (*w_ptr++); - si20 = (*w_ptr++); - co20 = (*w_ptr++); - si30 = (*w_ptr++); - co30 = (*w_ptr++); - - x_0 = x[0]; - x_h2_0 = x[h2]; - x_l1_0 = x[l1]; - x_l2_0 = x[l2]; - - xh0_0 = x_0 + x_l1_0; - xl0_0 = x_0 - x_l1_0; - - xh20_0 = x_h2_0 + x_l2_0; - xl20_0 = x_h2_0 - x_l2_0; - - x[0] = xh0_0 + xh20_0; - xt0_0 = xh0_0 - xh20_0; - - x_1 = x[1]; - x_h2_1 = x[h2 + 1]; - x_l1_1 = x[l1 + 1]; - x_l2_1 = x[l2 + 1]; - - xh1_0 = x_1 + x_l1_1; - xl1_0 = x_1 - x_l1_1; - - xh21_0 = x_h2_1 + x_l2_1; - xl21_0 = x_h2_1 - x_l2_1; - - x[1] = xh1_0 + xh21_0; - yt0_0 = xh1_0 - xh21_0; - - xt1_0 = xl0_0 + xl21_0; - xt2_0 = xl0_0 - xl21_0; - - yt2_0 = xl1_0 + xl20_0; - yt1_0 = xl1_0 - xl20_0; - - mul_11 = ixheaacd_mult64(xt2_0, co30); - mul_3 = ixheaacd_mult64(yt2_0, si30); - x[l2] = (WORD32)((mul_3 + mul_11) >> 32) << RADIXSHIFT; - - mul_5 = ixheaacd_mult64(xt2_0, si30); - mul_9 = ixheaacd_mult64(yt2_0, co30); - x[l2 + 1] = (WORD32)((mul_9 - mul_5) >> 32) << RADIXSHIFT; - - mul_12 = ixheaacd_mult64(xt0_0, co20); - mul_2 = ixheaacd_mult64(yt0_0, si20); - x[l1] = (WORD32)((mul_2 + mul_12) >> 32) << RADIXSHIFT; - - mul_6 = ixheaacd_mult64(xt0_0, si20); - mul_8 = ixheaacd_mult64(yt0_0, co20); - x[l1 + 1] = (WORD32)((mul_8 - mul_6) >> 32) << RADIXSHIFT; - - mul_4 = ixheaacd_mult64(xt1_0, co10); - mul_1 = ixheaacd_mult64(yt1_0, si10); - x[h2] = (WORD32)((mul_1 + mul_4) >> 32) << RADIXSHIFT; - - mul_10 = ixheaacd_mult64(xt1_0, si10); - mul_7 = ixheaacd_mult64(yt1_0, co10); - x[h2 + 1] = (WORD32)((mul_7 - mul_10) >> 32) << RADIXSHIFT; - - x += 2; - } - x += fft_jmp; - w_ptr = w_ptr - fft_jmp; - } -} - -VOID ixheaacd_esbr_postradixcompute2(WORD32 *ptr_y, WORD32 *ptr_x, - const WORD32 *pdig_rev_tbl, - WORD32 npoints) { - WORD32 i, k; - WORD32 h2; - WORD32 x_0, x_1, x_2, x_3; - WORD32 x_4, x_5, x_6, x_7; - WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f; - WORD32 n00, n10, n20, n30, n01, n11, n21, n31; - WORD32 n02, n12, n22, n32, n03, n13, n23, n33; - WORD32 n0, j0; - WORD32 *x2, *x0; - WORD32 *y0, *y1, *y2, *y3; - - y0 = ptr_y; - y2 = ptr_y + (WORD32)npoints; - x0 = ptr_x; - x2 = ptr_x + (WORD32)(npoints >> 1); - - y1 = y0 + (WORD32)(npoints >> 2); - y3 = y2 + (WORD32)(npoints >> 2); - j0 = 8; - n0 = npoints >> 1; - - for (k = 0; k < 2; k++) { - for (i = 0; i> 1; i += 8) { - h2 = *pdig_rev_tbl++ >> 2; - - x_0 = *x0++; - x_1 = *x0++; - x_2 = *x0++; - x_3 = *x0++; - x_4 = *x0++; - x_5 = *x0++; - x_6 = *x0++; - x_7 = *x0++; - - n00 = x_0 + x_2; - n01 = x_1 + x_3; - n20 = x_0 - x_2; - n21 = x_1 - x_3; - n10 = x_4 + x_6; - n11 = x_5 + x_7; - n30 = x_4 - x_6; - n31 = x_5 - x_7; - - y0[h2] = n00; - y0[h2 + 1] = n01; - y1[h2] = n10; - y1[h2 + 1] = n11; - y2[h2] = n20; - y2[h2 + 1] = n21; - y3[h2] = n30; - y3[h2 + 1] = n31; - - x_8 = *x2++; - x_9 = *x2++; - x_a = *x2++; - x_b = *x2++; - x_c = *x2++; - x_d = *x2++; - x_e = *x2++; - x_f = *x2++; - - n02 = x_8 + x_a; - n03 = x_9 + x_b; - n22 = x_8 - x_a; - n23 = x_9 - x_b; - n12 = x_c + x_e; - n13 = x_d + x_f; - n32 = x_c - x_e; - n33 = x_d - x_f; - - y0[h2 + 2] = n02; - y0[h2 + 3] = n03; - y1[h2 + 2] = n12; - y1[h2 + 3] = n13; - y2[h2 + 2] = n22; - y2[h2 + 3] = n23; - y3[h2 + 2] = n32; - y3[h2 + 3] = n33; - } - x0 += (WORD32)npoints >> 1; - x2 += (WORD32)npoints >> 1; - } -} - -VOID ixheaacd_esbr_postradixcompute4(WORD32 *ptr_y, WORD32 *ptr_x, - const WORD32 *p_dig_rev_tbl, - WORD32 npoints) { - WORD32 i, k; - WORD32 h2; - WORD32 xh0_0, xh1_0, xl0_0, xl1_0; - WORD32 xh0_1, xh1_1, xl0_1, xl1_1; - WORD32 x_0, x_1, x_2, x_3; - WORD32 xh0_2, xh1_2, xl0_2, xl1_2, xh0_3, xh1_3, xl0_3, xl1_3; - WORD32 x_4, x_5, x_6, x_7; - WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f; - WORD32 n00, n10, n20, n30, n01, n11, n21, n31; - WORD32 n02, n12, n22, n32, n03, n13, n23, n33; - WORD32 n0, j0; - WORD32 *x2, *x0; - WORD32 *y0, *y1, *y2, *y3; - - y0 = ptr_y; - y2 = ptr_y + (WORD32)npoints; - x0 = ptr_x; - x2 = ptr_x + (WORD32)(npoints >> 1); - - y1 = y0 + (WORD32)(npoints >> 1); - y3 = y2 + (WORD32)(npoints >> 1); - - j0 = 4; - n0 = npoints >> 2; - - for (k = 0; k < 2; k++) { - for (i = 0; i> 1; i += 8) { - h2 = *p_dig_rev_tbl++ >> 2; - x_0 = *x0++; - x_1 = *x0++; - x_2 = *x0++; - x_3 = *x0++; - x_4 = *x0++; - x_5 = *x0++; - x_6 = *x0++; - x_7 = *x0++; - - xh0_0 = x_0 + x_4; - xh1_0 = x_1 + x_5; - xl0_0 = x_0 - x_4; - xl1_0 = x_1 - x_5; - xh0_1 = x_2 + x_6; - xh1_1 = x_3 + x_7; - xl0_1 = x_2 - x_6; - xl1_1 = x_3 - x_7; - - n00 = xh0_0 + xh0_1; - n01 = xh1_0 + xh1_1; - n10 = xl0_0 + xl1_1; - n11 = xl1_0 - xl0_1; - n20 = xh0_0 - xh0_1; - n21 = xh1_0 - xh1_1; - n30 = xl0_0 - xl1_1; - n31 = xl1_0 + xl0_1; - - y0[h2] = n00; - y0[h2 + 1] = n01; - y1[h2] = n10; - y1[h2 + 1] = n11; - y2[h2] = n20; - y2[h2 + 1] = n21; - y3[h2] = n30; - y3[h2 + 1] = n31; - - x_8 = *x2++; - x_9 = *x2++; - x_a = *x2++; - x_b = *x2++; - x_c = *x2++; - x_d = *x2++; - x_e = *x2++; - x_f = *x2++; - - xh0_2 = x_8 + x_c; - xh1_2 = x_9 + x_d; - xl0_2 = x_8 - x_c; - xl1_2 = x_9 - x_d; - xh0_3 = x_a + x_e; - xh1_3 = x_b + x_f; - xl0_3 = x_a - x_e; - xl1_3 = x_b - x_f; - - n02 = xh0_2 + xh0_3; - n03 = xh1_2 + xh1_3; - n12 = xl0_2 + xl1_3; - n13 = xl1_2 - xl0_3; - n22 = xh0_2 - xh0_3; - n23 = xh1_2 - xh1_3; - n32 = xl0_2 - xl1_3; - n33 = xl1_2 + xl0_3; - - y0[h2 + 2] = n02; - y0[h2 + 3] = n03; - y1[h2 + 2] = n12; - y1[h2 + 3] = n13; - y2[h2 + 2] = n22; - y2[h2 + 3] = n23; - y3[h2 + 2] = n32; - y3[h2 + 3] = n33; - } - x0 += (WORD32)npoints >> 1; - x2 += (WORD32)npoints >> 1; - } -} - -VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, - ia_sbr_qmf_filter_bank_struct *qmf_bank, - WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) { - WORD32 z; - WORD32 temp[128]; - WORD32 scaleshift = 0; - - WORD32 re2, re3; - WORD32 wim, wre; - - WORD32 i, M_2; - WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1); - - const WORD32 *p_sin; - const WORD32 *p_sin_cos; - - WORD32 subband_tmp[128]; - WORD32 re; - WORD32 im; - WORD32 *psubband, *psubband1; - WORD32 *psubband_t, *psubband1_t; - WORD32 *psubband2, *psubband12; - WORD32 *psubband_t2, *psubband1_t2; - - M_2 = ixheaacd_shr32(M, 1); - - p_sin_cos = qmf_bank->esbr_cos_twiddle; - - psubband = &subband[0]; - psubband1 = &subband[2 * M - 1]; - psubband_t = subband_tmp; - psubband1_t = &subband_tmp[2 * M - 1]; - - psubband2 = &subband[64]; - psubband12 = &subband[2 * M - 1 + 64]; - psubband_t2 = &subband_tmp[64]; - psubband1_t2 = &subband_tmp[2 * M - 1 + 64]; - - for (i = (M_2 >> 1) - 1; i >= 0; i--) { - re = *psubband++; - im = *psubband1--; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband_t++ = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> - 32); - *psubband_t++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), - ixheaacd_mult64(re, wim))) >> - 32); - - re = *psubband2++; - im = *psubband12--; - - *psubband_t2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), - ixheaacd_mult64(re, wre))) >> - 32); - *psubband_t2++ = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> - 32); - - re = *psubband1--; - im = *psubband++; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband1_t-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), - ixheaacd_mult64(re, wim))) >> - 32); - *psubband1_t-- = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> - 32); - - re = *psubband12--; - im = *psubband2++; - - *psubband1_t2-- = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> - 32); - *psubband1_t2-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), - ixheaacd_mult64(re, wre))) >> - 32); - - re = *psubband++; - im = *psubband1--; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband_t++ = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> - 32); - *psubband_t++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), - ixheaacd_mult64(re, wim))) >> - 32); - - re = *psubband2++; - im = *psubband12--; - - *psubband_t2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), - ixheaacd_mult64(re, wre))) >> - 32); - *psubband_t2++ = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> - 32); - - re = *psubband1--; - im = *psubband++; - - wim = *p_sin_cos++; - wre = *p_sin_cos++; - - *psubband1_t-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), - ixheaacd_mult64(re, wim))) >> - 32); - *psubband1_t-- = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> - 32); - - re = *psubband12--; - im = *psubband2++; - - *psubband1_t2-- = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> - 32); - *psubband1_t2-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), - ixheaacd_mult64(re, wre))) >> - 32); - } - - if (M == 32) { - ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8); - ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2); - ixheaacd_esbr_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32); - - ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8); - ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2); - ixheaacd_esbr_postradixcompute2(&subband[64], &subband_tmp[64], - p_dig_rev_tbl, 32); - - } - - else if (M == 16) { - ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4); - ixheaacd_esbr_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16); - - ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4); - ixheaacd_esbr_postradixcompute4(&subband[64], &subband_tmp[64], - p_dig_rev_tbl, 16); - - } - - else if (M == 12) { - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[2 * z]; - temp[12 + z] = subband_tmp[2 * z + 1]; - } - - ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[2 * z] = temp[z]; - subband[2 * z + 1] = temp[z + 12]; - } - scaleshift = 0; - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[64 + 2 * z]; - temp[12 + z] = subband_tmp[64 + 2 * z + 1]; - } - - ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[64 + 2 * z] = temp[z]; - subband[64 + 2 * z + 1] = temp[z + 12]; - } - - } - - else { - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[2 * z]; - temp[8 + z] = subband_tmp[2 * z + 1]; - } - - (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[2 * z] = temp[z] << scaleshift; - subband[2 * z + 1] = temp[z + 8] << scaleshift; - } - scaleshift = 0; - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - temp[z] = subband_tmp[64 + 2 * z]; - temp[8 + z] = subband_tmp[64 + 2 * z + 1]; - } - - (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift); - - for (z = 0; z < (qmf_bank->no_channels >> 1); z++) { - subband[64 + 2 * z] = temp[z] << scaleshift; - subband[64 + 2 * z + 1] = temp[8 + z] << scaleshift; - } - } - - psubband = &subband[0]; - psubband1 = &subband[2 * M - 1]; - - re = *psubband1; - - *psubband = *psubband >> 1; - psubband++; - *psubband1 = ixheaacd_negate32(*psubband >> 1); - psubband1--; - - p_sin = qmf_bank->esbr_alt_sin_twiddle; - - wim = *p_sin++; - wre = *p_sin++; - - im = *psubband1; - - *psubband1-- = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> - 32); - *psubband++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), - ixheaacd_mult64(re, wim))) >> - 32); - - psubband2 = &subband[64]; - psubband12 = &subband[2 * M - 1 + 64]; - - re = *psubband12; - - *psubband12-- = ixheaacd_negate32_sat(*psubband2 >> 1); - - *psubband2 = psubband2[1] >> 1; - - psubband2++; - - im = *psubband12; - - *psubband2++ = ixheaacd_negate32_sat((WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >> - 32)); - *psubband12-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re, wim), - ixheaacd_mult64(im, wre))) >> - 32); - - for (i = (M_2 - 2); i >= 0; i--) { - im = psubband[0]; - - re = psubband[1]; - - re2 = *psubband1; - - *psubband++ = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> - 32); - *psubband1-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim), - ixheaacd_mult64(re, wre))) >> - 32); - - im = psubband2[0]; - - re = psubband2[1]; - - re3 = *psubband12; - - *psubband12-- = ixheaacd_negate32_sat((WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >> - 32)); - *psubband2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re, wre), - ixheaacd_mult64(im, wim))) >> - 32); - - wim = *p_sin++; - wre = *p_sin++; - im = psubband1[0]; - - *psubband1-- = (WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re2, wre), ixheaacd_mult64(im, wim))) >> - 32); - *psubband++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre), - ixheaacd_mult64(re2, wim))) >> - 32); - - im = psubband12[0]; - - *psubband2++ = ixheaacd_negate32_sat((WORD32)( - (ixheaacd_add64(ixheaacd_mult64(re3, wre), ixheaacd_mult64(im, wim))) >> - 32)); - *psubband12-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re3, wim), - ixheaacd_mult64(im, wre))) >> - 32); - } -} - -VOID ixheaacd_esbr_fwd_modulation( - const WORD32 *time_sample_buf, WORD32 *real_subband, WORD32 *imag_subband, - ia_sbr_qmf_filter_bank_struct *qmf_bank, - ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) { - WORD32 i; - const WORD32 *time_sample_buf1 = - &time_sample_buf[2 * qmf_bank->no_channels - 1]; - WORD32 temp1, temp2; - WORD32 *t_real_subband = real_subband; - WORD32 *t_imag_subband = imag_subband; - const WORD32 *tcos; - - for (i = qmf_bank->no_channels - 1; i >= 0; i--) { - temp1 = ixheaacd_shr32(*time_sample_buf++, HQ_SHIFT_64); - temp2 = ixheaacd_shr32(*time_sample_buf1--, HQ_SHIFT_64); - - *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2); - - *t_imag_subband++ = ixheaacd_add32(temp1, temp2); - } - - ixheaacd_esbr_cos_sin_mod(real_subband, qmf_bank, - qmf_dec_tables_ptr->esbr_w_16, - qmf_dec_tables_ptr->dig_rev_table4_16); - - tcos = qmf_bank->esbr_t_cos; - - for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) { - WORD32 cosh, sinh; - WORD32 re, im; - - re = *real_subband; - im = *imag_subband; - cosh = *tcos++; - sinh = *tcos++; - *real_subband++ = (WORD32)((ixheaacd_add64(ixheaacd_mult64(re, cosh), - ixheaacd_mult64(im, sinh))) >> - 31); - *imag_subband++ = - (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, cosh), - ixheaacd_mult64(re, sinh))) >> - 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) { @@ -1930,75 +612,6 @@ VOID ixheaacd_esbr_inv_modulation( qmf_dec_tables_ptr->dig_rev_table2_32); } -VOID ixheaacd_sbr_qmfsyn64_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 < 64; k++) { - WORD32 syn_out = rounding_fac; - - syn_out = ixheaacd_add32(syn_out, - ixheaacd_mult16x16in32(tmp1[0 + k], inp1[k + 0])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp1[256 + k], inp1[k + 128])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp1[512 + k], inp1[k + 256])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp1[768 + k], inp1[k + 384])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp1[1024 + k], inp1[k + 512])); - - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp2[128 + k], inp1[k + 64])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp2[384 + k], inp1[k + 192])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp2[640 + k], inp1[k + 320])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp2[896 + k], inp1[k + 448])); - syn_out = ixheaacd_add32( - syn_out, ixheaacd_mult16x16in32(tmp2[1152 + k], inp1[k + 576])); - - sample_buffer[ch_fac * k] = (ixheaacd_shl32_sat(syn_out, shift) >> 16); - } -} - -VOID ixheaacd_esbr_qmfsyn64_winadd(WORD32 *tmp1, WORD32 *tmp2, WORD32 *inp1, - WORD32 *sample_buffer, WORD32 ch_fac) { - WORD32 k; - - for (k = 0; k < 64; k++) { - WORD64 syn_out = 0; - - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[0 + k], inp1[k + 0])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[256 + k], inp1[k + 128])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[512 + k], inp1[k + 256])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[768 + k], inp1[k + 384])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[1024 + k], inp1[k + 512])); - - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[128 + k], inp1[k + 64])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[384 + k], inp1[k + 192])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[640 + k], inp1[k + 320])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[896 + k], inp1[k + 448])); - syn_out = - ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[1152 + k], inp1[k + 576])); - - sample_buffer[ch_fac * k] = (WORD32)(syn_out >> 31); - } -} - VOID ixheaacd_sbr_qmfsyn32_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1, WORD16 *sample_buffer, FLAG shift, WORD32 ch_fac) { @@ -2038,132 +651,6 @@ VOID ixheaacd_sbr_qmfsyn32_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1, } } -VOID ixheaacd_shiftrountine(WORD32 *qmf_real, WORD32 *qmf_imag, WORD32 len, - WORD32 common_shift) { - WORD32 treal, timag; - WORD32 j; - - if (common_shift < 0) { - WORD32 cshift = -common_shift; - cshift = ixheaacd_min32(cshift, 31); - for (j = len - 1; j >= 0; j--) { - treal = *qmf_real; - timag = *qmf_imag; - - treal = (ixheaacd_shr32(treal, cshift)); - timag = (ixheaacd_shr32(timag, cshift)); - - *qmf_real++ = treal; - *qmf_imag++ = timag; - } - } else { - for (j = len - 1; j >= 0; j--) { - treal = (ixheaacd_shl32_sat(*qmf_real, common_shift)); - timag = (ixheaacd_shl32_sat(*qmf_imag, common_shift)); - *qmf_real++ = treal; - *qmf_imag++ = timag; - } - } -} - -VOID ixheaacd_shiftrountine_with_rnd(WORD32 *qmf_real, WORD32 *qmf_imag, - WORD16 *filter_states, WORD32 len, - WORD32 shift) { - WORD16 *filter_states_rev = filter_states + len; - WORD32 treal, timag; - WORD32 j; - - for (j = (len - 1); j >= 0; j -= 2) { - WORD32 r1, r2, i1, i2; - i2 = qmf_imag[j]; - r2 = qmf_real[j]; - - r1 = *qmf_real++; - i1 = *qmf_imag++; - - timag = ixheaacd_add32(i1, r1); - timag = (ixheaacd_shl32_sat(timag, shift)); - filter_states_rev[j] = ixheaacd_round16(timag); - - treal = ixheaacd_sub32(i2, r2); - treal = (ixheaacd_shl32_sat(treal, shift)); - filter_states[j] = ixheaacd_round16(treal); - - treal = ixheaacd_sub32(i1, r1); - treal = (ixheaacd_shl32_sat(treal, shift)); - *filter_states++ = ixheaacd_round16(treal); - - timag = ixheaacd_add32(i2, r2); - ; - timag = (ixheaacd_shl32_sat(timag, shift)); - *filter_states_rev++ = ixheaacd_round16(timag); - } -} - -VOID ixheaacd_shiftrountine_with_rnd_eld(WORD32 *qmf_real, WORD32 *qmf_imag, - WORD16 *filter_states, WORD32 len, - WORD32 shift) { - WORD16 *filter_states_rev = filter_states + len; - WORD32 treal, timag; - WORD32 j; - - for (j = (len - 1); j >= 0; j -= 2) { - WORD32 r1, r2, i1, i2; - i2 = qmf_imag[j]; - r2 = qmf_real[j]; - r1 = *qmf_real++; - i1 = *qmf_imag++; - - timag = ixheaacd_negate32(ixheaacd_add32(i1, r1)); - timag = (ixheaacd_shl32_sat(timag, shift)); - filter_states_rev[j] = ixheaacd_round16(timag); - - treal = ixheaacd_sub32(r2, i2); - treal = (ixheaacd_shl32_sat(treal, shift)); - filter_states[j] = ixheaacd_round16(treal); - - treal = ixheaacd_sub32(r1, i1); - treal = (ixheaacd_shl32_sat(treal, shift)); - *filter_states++ = ixheaacd_round16(treal); - - timag = ixheaacd_negate32(ixheaacd_add32(i2, r2)); - timag = (ixheaacd_shl32_sat(timag, shift)); - *filter_states_rev++ = ixheaacd_round16(timag); - } -} - -VOID ixheaacd_shiftrountine_with_rnd_hq(WORD32 *qmf_real, WORD32 *qmf_imag, - WORD32 *filter_states, WORD32 len, - WORD32 shift) { - WORD32 *filter_states_rev = filter_states + len; - WORD32 treal, timag; - WORD32 j; - - for (j = (len - 1); j >= 0; j -= 2) { - WORD32 r1, r2, i1, i2; - i2 = qmf_imag[j]; - r2 = qmf_real[j]; - r1 = *qmf_real++; - i1 = *qmf_imag++; - - timag = ixheaacd_add32(i1, r1); - timag = (ixheaacd_shl32_sat(timag, shift)); - filter_states_rev[j] = timag; - - treal = ixheaacd_sub32(i2, r2); - treal = (ixheaacd_shl32_sat(treal, shift)); - filter_states[j] = treal; - - treal = ixheaacd_sub32(i1, r1); - treal = (ixheaacd_shl32_sat(treal, shift)); - *filter_states++ = treal; - - timag = ixheaacd_add32(i2, r2); - timag = (ixheaacd_shl32_sat(timag, shift)); - *filter_states_rev++ = timag; - } -} - void ixheaacd_sbr_pre_twiddle(WORD32 *p_xre, WORD32 *p_xim, WORD16 *p_twiddles) { int k; @@ -2276,6 +763,7 @@ VOID ixheaacd_cplx_synt_qmffilt( high_band_scale_factor = (st_syn_scale - scale_factor); p1 = 0; + if (low_pow_flag) { @@ -2340,6 +828,7 @@ VOID ixheaacd_cplx_synt_qmffilt( } } } + if (low_pow_flag) { @@ -2495,297 +984,3 @@ VOID ixheaacd_cplx_synt_qmffilt( qmf_bank->ixheaacd_drc_offset = ixheaacd_drc_offset; } -VOID ixheaacd_radix4bfly(const WORD16 *w, WORD32 *x, WORD32 index1, - WORD32 index) { - int i; - WORD32 l1, l2, h2, fft_jmp; - WORD32 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0; - WORD32 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0; - WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1; - WORD32 x_h2_0, x_h2_1; - WORD16 si10, si20, si30, co10, co20, co30; - - WORD32 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6; - WORD32 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12; - WORD32 *x_l1; - WORD32 *x_l2; - WORD32 *x_h2; - const WORD16 *w_ptr = w; - WORD32 i1; - - h2 = index << 1; - l1 = index << 2; - l2 = (index << 2) + (index << 1); - - x_l1 = &(x[l1]); - x_l2 = &(x[l2]); - x_h2 = &(x[h2]); - - fft_jmp = 6 * (index); - - for (i1 = 0; i1 < index1; i1++) { - for (i = 0; i < index; i++) { - si10 = (*w_ptr++); - co10 = (*w_ptr++); - si20 = (*w_ptr++); - co20 = (*w_ptr++); - si30 = (*w_ptr++); - co30 = (*w_ptr++); - - x_0 = x[0]; - x_h2_0 = x[h2]; - x_l1_0 = x[l1]; - x_l2_0 = x[l2]; - - xh0_0 = x_0 + x_l1_0; - xl0_0 = x_0 - x_l1_0; - - xh20_0 = x_h2_0 + x_l2_0; - xl20_0 = x_h2_0 - x_l2_0; - - x[0] = xh0_0 + xh20_0; - xt0_0 = xh0_0 - xh20_0; - - x_1 = x[1]; - x_h2_1 = x[h2 + 1]; - x_l1_1 = x[l1 + 1]; - x_l2_1 = x[l2 + 1]; - - xh1_0 = x_1 + x_l1_1; - xl1_0 = x_1 - x_l1_1; - - xh21_0 = x_h2_1 + x_l2_1; - xl21_0 = x_h2_1 - x_l2_1; - - x[1] = xh1_0 + xh21_0; - yt0_0 = xh1_0 - xh21_0; - - xt1_0 = xl0_0 + xl21_0; - xt2_0 = xl0_0 - xl21_0; - - yt2_0 = xl1_0 + xl20_0; - yt1_0 = xl1_0 - xl20_0; - - mul_11 = ixheaacd_mult32x16in32(xt2_0, co30); - mul_3 = ixheaacd_mult32x16in32(yt2_0, si30); - x[l2] = (mul_3 + mul_11) << RADIXSHIFT; - - mul_5 = ixheaacd_mult32x16in32(xt2_0, si30); - mul_9 = ixheaacd_mult32x16in32(yt2_0, co30); - x[l2 + 1] = (mul_9 - mul_5) << RADIXSHIFT; - - mul_12 = ixheaacd_mult32x16in32(xt0_0, co20); - mul_2 = ixheaacd_mult32x16in32(yt0_0, si20); - x[l1] = (mul_2 + mul_12) << RADIXSHIFT; - - mul_6 = ixheaacd_mult32x16in32(xt0_0, si20); - mul_8 = ixheaacd_mult32x16in32(yt0_0, co20); - x[l1 + 1] = (mul_8 - mul_6) << RADIXSHIFT; - - mul_4 = ixheaacd_mult32x16in32(xt1_0, co10); - mul_1 = ixheaacd_mult32x16in32(yt1_0, si10); - x[h2] = (mul_1 + mul_4) << RADIXSHIFT; - - mul_10 = ixheaacd_mult32x16in32(xt1_0, si10); - mul_7 = ixheaacd_mult32x16in32(yt1_0, co10); - x[h2 + 1] = (mul_7 - mul_10) << RADIXSHIFT; - - x += 2; - } - x += fft_jmp; - w_ptr = w_ptr - fft_jmp; - } -} - -VOID ixheaacd_postradixcompute4(WORD32 *ptr_y, WORD32 *ptr_x, - const WORD32 *p_dig_rev_tbl, WORD32 npoints) { - WORD32 i, k; - WORD32 h2; - WORD32 xh0_0, xh1_0, xl0_0, xl1_0; - WORD32 xh0_1, xh1_1, xl0_1, xl1_1; - WORD32 x_0, x_1, x_2, x_3; - WORD32 xh0_2, xh1_2, xl0_2, xl1_2, xh0_3, xh1_3, xl0_3, xl1_3; - WORD32 x_4, x_5, x_6, x_7; - WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f; - WORD32 n00, n10, n20, n30, n01, n11, n21, n31; - WORD32 n02, n12, n22, n32, n03, n13, n23, n33; - WORD32 n0, j0; - WORD32 *x2, *x0; - WORD32 *y0, *y1, *y2, *y3; - - y0 = ptr_y; - y2 = ptr_y + (WORD32)npoints; - x0 = ptr_x; - x2 = ptr_x + (WORD32)(npoints >> 1); - - y1 = y0 + (WORD32)(npoints >> 1); - y3 = y2 + (WORD32)(npoints >> 1); - - j0 = 4; - n0 = npoints >> 2; - - for (k = 0; k < 2; k++) { - for (i = 0; i> 1; i += 8) { - h2 = *p_dig_rev_tbl++ >> 2; - x_0 = *x0++; - x_1 = *x0++; - x_2 = *x0++; - x_3 = *x0++; - x_4 = *x0++; - x_5 = *x0++; - x_6 = *x0++; - x_7 = *x0++; - - xh0_0 = x_0 + x_4; - xh1_0 = x_1 + x_5; - xl0_0 = x_0 - x_4; - xl1_0 = x_1 - x_5; - xh0_1 = x_2 + x_6; - xh1_1 = x_3 + x_7; - xl0_1 = x_2 - x_6; - xl1_1 = x_3 - x_7; - - n00 = xh0_0 + xh0_1; - n01 = xh1_0 + xh1_1; - n10 = xl0_0 + xl1_1; - n11 = xl1_0 - xl0_1; - n20 = xh0_0 - xh0_1; - n21 = xh1_0 - xh1_1; - n30 = xl0_0 - xl1_1; - n31 = xl1_0 + xl0_1; - - y0[h2] = n00; - y0[h2 + 1] = n01; - y1[h2] = n10; - y1[h2 + 1] = n11; - y2[h2] = n20; - y2[h2 + 1] = n21; - y3[h2] = n30; - y3[h2 + 1] = n31; - - x_8 = *x2++; - x_9 = *x2++; - x_a = *x2++; - x_b = *x2++; - x_c = *x2++; - x_d = *x2++; - x_e = *x2++; - x_f = *x2++; - - xh0_2 = x_8 + x_c; - xh1_2 = x_9 + x_d; - xl0_2 = x_8 - x_c; - xl1_2 = x_9 - x_d; - xh0_3 = x_a + x_e; - xh1_3 = x_b + x_f; - xl0_3 = x_a - x_e; - xl1_3 = x_b - x_f; - - n02 = xh0_2 + xh0_3; - n03 = xh1_2 + xh1_3; - n12 = xl0_2 + xl1_3; - n13 = xl1_2 - xl0_3; - n22 = xh0_2 - xh0_3; - n23 = xh1_2 - xh1_3; - n32 = xl0_2 - xl1_3; - n33 = xl1_2 + xl0_3; - - y0[h2 + 2] = n02; - y0[h2 + 3] = n03; - y1[h2 + 2] = n12; - y1[h2 + 3] = n13; - y2[h2 + 2] = n22; - y2[h2 + 3] = n23; - y3[h2 + 2] = n32; - y3[h2 + 3] = n33; - } - x0 += (WORD32)npoints >> 1; - x2 += (WORD32)npoints >> 1; - } -} - -VOID ixheaacd_postradixcompute2(WORD32 *ptr_y, WORD32 *ptr_x, - const WORD32 *pdig_rev_tbl, WORD32 npoints) { - WORD32 i, k; - WORD32 h2; - WORD32 x_0, x_1, x_2, x_3; - WORD32 x_4, x_5, x_6, x_7; - WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f; - WORD32 n00, n10, n20, n30, n01, n11, n21, n31; - WORD32 n02, n12, n22, n32, n03, n13, n23, n33; - WORD32 n0, j0; - WORD32 *x2, *x0; - WORD32 *y0, *y1, *y2, *y3; - - y0 = ptr_y; - y2 = ptr_y + (WORD32)npoints; - x0 = ptr_x; - x2 = ptr_x + (WORD32)(npoints >> 1); - - y1 = y0 + (WORD32)(npoints >> 2); - y3 = y2 + (WORD32)(npoints >> 2); - j0 = 8; - n0 = npoints >> 1; - - for (k = 0; k < 2; k++) { - for (i = 0; i> 1; i += 8) { - h2 = *pdig_rev_tbl++ >> 2; - - x_0 = *x0++; - x_1 = *x0++; - x_2 = *x0++; - x_3 = *x0++; - x_4 = *x0++; - x_5 = *x0++; - x_6 = *x0++; - x_7 = *x0++; - - n00 = x_0 + x_2; - n01 = x_1 + x_3; - n20 = x_0 - x_2; - n21 = x_1 - x_3; - n10 = x_4 + x_6; - n11 = x_5 + x_7; - n30 = x_4 - x_6; - n31 = x_5 - x_7; - - y0[h2] = n00; - y0[h2 + 1] = n01; - y1[h2] = n10; - y1[h2 + 1] = n11; - y2[h2] = n20; - y2[h2 + 1] = n21; - y3[h2] = n30; - y3[h2 + 1] = n31; - - x_8 = *x2++; - x_9 = *x2++; - x_a = *x2++; - x_b = *x2++; - x_c = *x2++; - x_d = *x2++; - x_e = *x2++; - x_f = *x2++; - - n02 = x_8 + x_a; - n03 = x_9 + x_b; - n22 = x_8 - x_a; - n23 = x_9 - x_b; - n12 = x_c + x_e; - n13 = x_d + x_f; - n32 = x_c - x_e; - n33 = x_d - x_f; - - y0[h2 + 2] = n02; - y0[h2 + 3] = n03; - y1[h2 + 2] = n12; - y1[h2 + 3] = n13; - y2[h2 + 2] = n22; - y2[h2 + 3] = n23; - y3[h2 + 2] = n32; - y3[h2 + 3] = n33; - } - x0 += (WORD32)npoints >> 1; - x2 += (WORD32)npoints >> 1; - } -} \ No newline at end of file diff --git a/decoder/ixheaacd_qmf_dec.h b/decoder/ixheaacd_qmf_dec.h index 0b9c0a4..96356ee 100644 --- a/decoder/ixheaacd_qmf_dec.h +++ b/decoder/ixheaacd_qmf_dec.h @@ -178,4 +178,43 @@ VOID ixheaacd_cos_sin_mod_loop1(WORD32 *subband, WORD32 M, VOID ixheaacd_cos_sin_mod_loop2(WORD32 *subband, const WORD16 *p_sin, WORD32 M); +VOID ixheaacd_sbr_qmfsyn64_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1, + WORD16 *sample_buffer, FLAG shift, + WORD32 ch_fac); + +VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband, + ia_sbr_qmf_filter_bank_struct *qmf_bank, + WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl); + +VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, + ia_sbr_qmf_filter_bank_struct *syn_qmf, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr); + +VOID ixheaacd_sbr_pre_twiddle(WORD32 *p_xre, WORD32 *p_xim, + WORD16 *p_twiddles); + +VOID ixheaacd_inv_emodulation( + WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr); + +VOID ixheaacd_pretwdct2(WORD32 *inp, WORD32 *out_fwd); + +VOID ixheaacd_sbr_qmfanal32_winadd_eld(WORD16 *inp1, WORD16 *inp2, + WORD16 *p_qmf1, WORD16 *p_qmf2, + WORD32 *p_out); + +VOID ixheaacd_dct2_32(WORD32 *inp, WORD32 *out, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, + WORD16 *filter_states); + +VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states, + ia_sbr_qmf_filter_bank_struct *syn_qmf, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr); + +VOID ixheaacd_fftposttw(WORD32 *out, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr); + +VOID ixheaacd_posttwdct2(WORD32 *inp, WORD16 *out_fwd, + ia_qmf_dec_tables_struct *qmf_dec_tables_ptr); + #endif diff --git a/decoder/ixheaacd_qmf_poly.h b/decoder/ixheaacd_qmf_poly.h index 25d4694..debdad5 100644 --- a/decoder/ixheaacd_qmf_poly.h +++ b/decoder/ixheaacd_qmf_poly.h @@ -23,9 +23,9 @@ double *ixheaacd_interpo_esbr_fcoff(const double *orig_prot, WORD32 no, WORD32 lo, WORD32 li); -VOID ixheaacd_complex_anal_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer); +WORD32 ixheaacd_complex_anal_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer); -VOID ixheaacd_real_synth_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, +WORD32 ixheaacd_real_synth_filt(ia_esbr_hbe_txposer_struct *ptr_hbe_txposer, WORD32 num_columns, FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64]); diff --git a/decoder/ixheaacd_sbr_dec.c b/decoder/ixheaacd_sbr_dec.c index 571d955..31beb76 100644 --- a/decoder/ixheaacd_sbr_dec.c +++ b/decoder/ixheaacd_sbr_dec.c @@ -705,7 +705,7 @@ WORD32 ixheaacd_sbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, WORD16 *ptr_time_data, op_delay + codec_x_delay + SBR_HF_ADJ_OFFSET); if (hbe_flag) { - ixheaacd_qmf_hbe_apply( + WORD32 err_code = ixheaacd_qmf_hbe_apply( ptr_sbr_dec->p_hbe_txposer, ptr_sbr_dec->qmf_buf_real + (op_delay + SBR_HF_ADJ_OFFSET) + ESBR_HBE_DELAY_OFFSET, @@ -715,6 +715,8 @@ WORD32 ixheaacd_sbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, WORD16 *ptr_time_data, ptr_sbr_dec->ph_vocod_qmf_real + (op_delay + SBR_HF_ADJ_OFFSET), ptr_sbr_dec->ph_vocod_qmf_imag + (op_delay + SBR_HF_ADJ_OFFSET), ptr_frame_data->pitch_in_bins); + if(err_code) + return err_code; if (upsample_ratio_idx == SBR_UPSAMPLE_IDX_4_1) { ixheaacd_hbe_repl_spec( @@ -1012,7 +1014,7 @@ WORD32 ixheaacd_sbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, WORD16 *ptr_time_data, return 0; } -void ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, +WORD32 ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, ia_sbr_header_data_struct *ptr_header_data, ia_sbr_frame_info_data_struct *ptr_frame_data, FLAG apply_processing, FLAG low_pow_flag, @@ -1098,7 +1100,7 @@ void ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, op_delay + codec_x_delay + SBR_HF_ADJ_OFFSET); if (hbe_flag) { - ixheaacd_qmf_hbe_apply( + WORD32 err = ixheaacd_qmf_hbe_apply( ptr_sbr_dec->p_hbe_txposer, ptr_sbr_dec->qmf_buf_real + (op_delay + SBR_HF_ADJ_OFFSET) + ESBR_HBE_DELAY_OFFSET, @@ -1108,6 +1110,8 @@ void ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, ptr_sbr_dec->ph_vocod_qmf_real + (op_delay + SBR_HF_ADJ_OFFSET), ptr_sbr_dec->ph_vocod_qmf_imag + (op_delay + SBR_HF_ADJ_OFFSET), ptr_frame_data->pitch_in_bins); + if(err) + return err; if (upsample_ratio_idx == SBR_UPSAMPLE_IDX_4_1) { ixheaacd_hbe_repl_spec( @@ -1131,7 +1135,7 @@ void ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, mps_sbr_flag, ch_fac); ptr_frame_data->prev_sbr_mode = sbr_mode; - return; + return 0; } WORD32 ixheaacd_sbr_dec_from_mps(FLOAT32 *p_mps_qmf_output, VOID *p_sbr_dec, diff --git a/decoder/ixheaacd_sbr_dec.h b/decoder/ixheaacd_sbr_dec.h index 2853237..6585c51 100644 --- a/decoder/ixheaacd_sbr_dec.h +++ b/decoder/ixheaacd_sbr_dec.h @@ -174,7 +174,7 @@ WORD16 ixheaacd_create_sbrdec( WORD32 ixheaacd_sbr_dec_from_mps(FLOAT32 *p_mps_qmf_output, VOID *p_sbr_dec, VOID *p_sbr_frame, VOID *p_sbr_header); -VOID ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *h_hbe_txposer, +WORD32 ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *h_hbe_txposer, FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64], WORD32 num_columns, FLOAT32 pv_qmf_buf_real[][64], @@ -204,7 +204,7 @@ VOID ixheaacd_rescale_x_overlap( ia_sbr_prev_frame_data_struct *ptr_frame_data_prev, WORD32 **pp_overlap_buffer_real, FLAG low_pow_flag); -VOID ixheaacd_qmf_hbe_data_reinit( +WORD32 ixheaacd_qmf_hbe_data_reinit( ia_esbr_hbe_txposer_struct *ptr_hbe_transposer_str, WORD16 *ptr_freq_band_tbl[MAX_FREQ_COEFFS + 1], WORD16 *ptr_num_sf_bands, WORD32 upsamp_4_flag); @@ -216,14 +216,14 @@ WORD32 ixheaacd_sbr_read_pvc_sce(ia_sbr_frame_info_data_struct *ptr_frame_data, ia_sbr_tables_struct *sbr_tables_ptr, ia_sbr_header_data_struct *ptr_header_data); -VOID ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *h_hbe_txposer, +WORD32 ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *h_hbe_txposer, FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64], WORD32 num_columns, FLOAT32 pv_qmf_buf_real[][64], FLOAT32 pv_qmf_buf_imag[][64], WORD32 pitch_in_bins); -VOID ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, +WORD32 ixheaacd_esbr_dec(ia_sbr_dec_struct *ptr_sbr_dec, ia_sbr_header_data_struct *ptr_header_data, ia_sbr_frame_info_data_struct *ptr_frame_data, FLAG apply_processing, FLAG low_pow_flag, diff --git a/decoder/ixheaacd_sbrdec_lpfuncs.c b/decoder/ixheaacd_sbrdec_lpfuncs.c index 03d2a8a..1af42f1 100644 --- a/decoder/ixheaacd_sbrdec_lpfuncs.c +++ b/decoder/ixheaacd_sbrdec_lpfuncs.c @@ -1073,6 +1073,8 @@ WORD32 ixheaacd_generate_hf(FLOAT32 ptr_src_buf_real[][64], patch = 0; while (sb < usb) { + if(MAX_NUM_PATCHES <= patch) + return -1; ptr_frame_data->patch_param.start_subband[patch] = sb; num_bands_in_patch = goal_sb - sb; @@ -1109,11 +1111,7 @@ WORD32 ixheaacd_generate_hf(FLOAT32 ptr_src_buf_real[][64], } if (num_bands_in_patch <= 0) { - if(num_bands_in_patch == 0) - { - return -1; - } - continue; + return -1; } for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) { @@ -1246,6 +1244,8 @@ WORD32 ixheaacd_generate_hf(FLOAT32 ptr_src_buf_real[][64], } } ptr_frame_data->patch_param.num_patches = patch; + if(patch >= (MAX_NUM_PATCHES + 1)) + return -1; for (i = 0; i < num_if_bands; i++) { bw_array_prev[i] = bw_array[i]; } diff --git a/decoder/ixheaacd_sbrdecoder.c b/decoder/ixheaacd_sbrdecoder.c index 10164e2..1e53ba7 100644 --- a/decoder/ixheaacd_sbrdecoder.c +++ b/decoder/ixheaacd_sbrdecoder.c @@ -156,11 +156,13 @@ static WORD32 ixheaacd_sbr_dec_reset(ia_sbr_dec_struct *ptr_sbr_dec, } if (hbe_flag && ptr_sbr_dec->p_hbe_txposer != NULL) { WORD32 k, i; - ixheaacd_qmf_hbe_data_reinit( + WORD32 err = ixheaacd_qmf_hbe_data_reinit( ptr_sbr_dec->p_hbe_txposer, ptr_header_data->pstr_freq_band_data->freq_band_table, ptr_header_data->pstr_freq_band_data->num_sf_bands, ptr_header_data->is_usf_4); + if(err) + return err; for (k = 0; k < 2; k++) { if (!((upsample_ratio_idx == SBR_UPSAMPLE_IDX_4_1) && (k == 0))) { @@ -178,12 +180,14 @@ static WORD32 ixheaacd_sbr_dec_reset(ia_sbr_dec_struct *ptr_sbr_dec, 64 * sizeof(FLOAT32)); } - ixheaacd_qmf_hbe_apply( + err = ixheaacd_qmf_hbe_apply( ptr_sbr_dec->p_hbe_txposer, ptr_sbr_dec->qmf_buf_real + op_delay + xpos_delay, ptr_sbr_dec->qmf_buf_imag + op_delay + xpos_delay, num_time_slots, ptr_sbr_dec->ph_vocod_qmf_real + op_delay, ptr_sbr_dec->ph_vocod_qmf_imag + op_delay, pitch_in_bins); + if(err) + return err; if (upsample_ratio_idx == SBR_UPSAMPLE_IDX_4_1) { ixheaacd_hbe_repl_spec(&ptr_sbr_dec->p_hbe_txposer->x_over_qmf[0], @@ -436,6 +440,9 @@ WORD16 ixheaacd_applysbr(ia_handle_sbr_dec_inst_struct self, &(pstr_sbr_channel[lr]->str_sbr_dec), ptr_header_data[k], low_pow_flag, self->pstr_common_tables, ptr_frame_data[k]->pitch_in_bins, audio_object_type); + if(err < 0) + return err; + } } @@ -466,6 +473,10 @@ WORD16 ixheaacd_applysbr(ia_handle_sbr_dec_inst_struct self, err = ixheaacd_calc_frq_bnd_tbls(ptr_header_data[k], self->pstr_common_tables); + if(err) + { + return err; + } } } @@ -479,6 +490,8 @@ WORD16 ixheaacd_applysbr(ia_handle_sbr_dec_inst_struct self, &(pstr_sbr_channel[lr]->str_sbr_dec), ptr_header_data[k], low_pow_flag, self->pstr_common_tables, ptr_frame_data[k]->pitch_in_bins, audio_object_type); + if(err < 0) + return err; } } ptr_header_data[k]->status = 0; @@ -518,6 +531,8 @@ WORD16 ixheaacd_applysbr(ia_handle_sbr_dec_inst_struct self, frame_status = ixheaacd_sbr_read_pvc_sce( ptr_frame_data[k], it_bit_buff, 0, self->ptr_pvc_data_str, self->pstr_sbr_tables, ptr_header_data[k]); + if(frame_status < 0) + return frame_status; } } if (audio_object_type != AOT_ER_AAC_ELD) { @@ -680,10 +695,12 @@ WORD16 ixheaacd_applysbr(ia_handle_sbr_dec_inst_struct self, pstr_sbr_channel[1]->str_sbr_dec.time_sample_buf = self->time_sample_buf[1]; if (ele_channels == 1 && usac_flag) { - ixheaacd_esbr_dec(&pstr_sbr_channel[1]->str_sbr_dec, ptr_header_data[1], + WORD32 err_code = ixheaacd_esbr_dec(&pstr_sbr_channel[1]->str_sbr_dec, ptr_header_data[1], ptr_frame_data[1], (ptr_header_data[1]->sync_state == SBR_ACTIVE), low_pow_flag, self->pstr_sbr_tables, ch_fac); + if(err_code) + return err_code; } else { if (pstr_drc_dec == NULL) { WORD32 err_code = ixheaacd_sbr_dec( diff --git a/decoder/ixheaacd_sbrqmftrans.h b/decoder/ixheaacd_sbrqmftrans.h index 6ffe5ed..55455cb 100644 --- a/decoder/ixheaacd_sbrqmftrans.h +++ b/decoder/ixheaacd_sbrqmftrans.h @@ -20,14 +20,14 @@ #ifndef IXHEAACD_SBRQMFTRANS_H #define IXHEAACD_SBRQMFTRANS_H -VOID ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *h_hbe_txposer, +WORD32 ixheaacd_qmf_hbe_apply(ia_esbr_hbe_txposer_struct *h_hbe_txposer, FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64], WORD32 num_columns, FLOAT32 pv_qmf_buf_real[][64], FLOAT32 pv_qmf_buf_imag[][64], WORD32 pitch_in_bins); -VOID ixheaacd_qmf_hbe_data_reinit( +WORD32 ixheaacd_qmf_hbe_data_reinit( ia_esbr_hbe_txposer_struct *ptr_hbe_transposer_str, WORD16 *ptr_freq_band_tbl[MAX_FREQ_COEFFS + 1], WORD16 *ptr_num_sf_bands, WORD32 upsamp_4_flag); diff --git a/decoder/ixheaacd_spectrum_dec.c b/decoder/ixheaacd_spectrum_dec.c index b29911e..544df08 100644 --- a/decoder/ixheaacd_spectrum_dec.c +++ b/decoder/ixheaacd_spectrum_dec.c @@ -393,6 +393,11 @@ WORD32 ixheaacd_fd_channel_stream( ixheaacd_scale_factor_data(info, tot_sfb, *max_sfb, info->sfb_per_sbk, ptr_code_book); + if((it_bit_buff->ptr_read_next > it_bit_buff->ptr_bit_buf_end - 3) && (it_bit_buff->size == it_bit_buff->max_size)) + { + return -1; + } + ixheaacd_section_data(usac_data, it_bit_buff, info, global_gain, usac_data->factors[chn], usac_data->group_dis[chn], ptr_code_book); diff --git a/decoder/ixheaacd_ver_number.h b/decoder/ixheaacd_ver_number.h index 9aa7338..c2c4832 100644 --- a/decoder/ixheaacd_ver_number.h +++ b/decoder/ixheaacd_ver_number.h @@ -18,9 +18,9 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ #ifdef _ARM_ -#define xHE_AAC_DEC_ITTIAM_VER "_ARM $Rev: 1.38 $" +#define xHE_AAC_DEC_ITTIAM_VER "_ARM $Rev: 1.41 $" #elif _X86_ -#define xHE_AAC_DEC_ITTIAM_VER "_X86 $Rev: 1.38 $" +#define xHE_AAC_DEC_ITTIAM_VER "_X86 $Rev: 1.41 $" #else -#define xHE_AAC_DEC_ITTIAM_VER "_MSVC $Rev: 1.38 $" +#define xHE_AAC_DEC_ITTIAM_VER "_MSVC $Rev: 1.41 $" #endif